include/boost/corosio/native/native_io_context.hpp

91.9% Lines (34/37) 100.0% List of functions (10/10) 72.7% Branches (16/22)
native_io_context.hpp
f(x) Functions (10)
Function Calls Lines Branches Blocks
boost::corosio::native_io_context<boost::corosio::iocp_t{}>::sched() :69 9x 100.0% 100.0% boost::corosio::native_io_context<boost::corosio::iocp_t{}>::native_io_context() :76 8x 100.0% 100.0% boost::corosio::native_io_context<boost::corosio::iocp_t{}>::native_io_context(unsigned int) :83 1x 100.0% 100.0% boost::corosio::native_io_context<boost::corosio::iocp_t{}>::stop() :107 1x 100.0% 100.0% boost::corosio::native_io_context<boost::corosio::iocp_t{}>::stopped() const :113 4x 100.0% 100.0% boost::corosio::native_io_context<boost::corosio::iocp_t{}>::restart() :119 1x 100.0% 100.0% unsigned long long boost::corosio::native_io_context<boost::corosio::iocp_t{}>::run_for<long long, std::ratio<1ll, 1000ll> >(std::chrono::duration<long long, std::ratio<1ll, 1000ll> > const&) :149 1x 100.0% 100.0% 87.5% unsigned long long boost::corosio::native_io_context<boost::corosio::iocp_t{}>::run_until<std::chrono::_V2::steady_clock, std::chrono::duration<long long, std::ratio<1ll, 1000000000ll> > >(std::chrono::time_point<std::chrono::_V2::steady_clock, std::chrono::duration<long long, std::ratio<1ll, 1000000000ll> > > const&) :162 1x 100.0% 75.0% 100.0% unsigned long long boost::corosio::native_io_context<boost::corosio::iocp_t{}>::run_one_until<std::chrono::_V2::steady_clock, std::chrono::duration<long long, std::ratio<1ll, 1000000000ll> > >(std::chrono::time_point<std::chrono::_V2::steady_clock, std::chrono::duration<long long, std::ratio<1ll, 1000000000ll> > > const&) :191 2x 76.9% 68.8% 62.2% boost::corosio::native_io_context<boost::corosio::iocp_t{}>::poll() :218 1x 100.0% 100.0%
Line Branch TLA Hits Source Code
1 //
2 // Copyright (c) 2026 Steve Gerbino
3 //
4 // Distributed under the Boost Software License, Version 1.0. (See accompanying
5 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 //
7 // Official repository: https://github.com/cppalliance/corosio
8 //
9
10 #ifndef BOOST_COROSIO_NATIVE_NATIVE_IO_CONTEXT_HPP
11 #define BOOST_COROSIO_NATIVE_NATIVE_IO_CONTEXT_HPP
12
13 #include <boost/corosio/io_context.hpp>
14 #include <boost/corosio/backend.hpp>
15
16 #ifndef BOOST_COROSIO_MRDOCS
17 #if BOOST_COROSIO_HAS_EPOLL
18 #include <boost/corosio/native/detail/epoll/epoll_scheduler.hpp>
19 #endif
20
21 #if BOOST_COROSIO_HAS_SELECT
22 #include <boost/corosio/native/detail/select/select_scheduler.hpp>
23 #endif
24
25 #if BOOST_COROSIO_HAS_KQUEUE
26 #include <boost/corosio/native/detail/kqueue/kqueue_scheduler.hpp>
27 #endif
28
29 #if BOOST_COROSIO_HAS_IOCP
30 #include <boost/corosio/native/detail/iocp/win_scheduler.hpp>
31 #endif
32 #endif // !BOOST_COROSIO_MRDOCS
33
34 namespace boost::corosio {
35
36 /** An I/O context with devirtualized event loop methods.
37
38 This class template inherits from @ref io_context and shadows
39 all public methods with versions that call the concrete
40 scheduler directly, bypassing virtual dispatch. No new state
41 is added.
42
43 A `native_io_context` IS-A `io_context` and can be passed
44 anywhere an `io_context&` is accepted, in which case virtual
45 dispatch is used transparently.
46
47 @tparam Backend A backend tag value (e.g., `epoll`,
48 `iocp`) whose type provides `scheduler_type`.
49
50 @par Thread Safety
51 Same as the underlying context type.
52
53 @par Example
54 @code
55 #include <boost/corosio/native/native_io_context.hpp>
56
57 native_io_context<epoll> ctx;
58 ctx.poll(); // devirtualized call
59 @endcode
60
61 @see io_context, epoll_t, iocp_t
62 */
63 template<auto Backend>
64 class native_io_context : public io_context
65 {
66 using backend_type = decltype(Backend);
67 using scheduler_type = typename backend_type::scheduler_type;
68
69 9x scheduler_type& sched() noexcept
70 {
71 9x return *static_cast<scheduler_type*>(this->sched_);
72 }
73
74 public:
75 /** Construct with default concurrency. */
76 8x native_io_context() : io_context(Backend) {}
77
78 /** Construct with a concurrency hint.
79
80 @param concurrency_hint Hint for the number of threads that
81 will call `run()`.
82 */
83 1x explicit native_io_context(unsigned concurrency_hint)
84 1x : io_context(Backend, concurrency_hint)
85 {
86 1x }
87
88 /** Construct with runtime tuning options.
89
90 @param opts Runtime options controlling scheduler and
91 service behavior.
92 @param concurrency_hint Hint for the number of threads that
93 will call `run()`.
94 */
95 explicit native_io_context(
96 io_context_options const& opts,
97 unsigned concurrency_hint = std::thread::hardware_concurrency())
98 : io_context(Backend, opts, concurrency_hint)
99 {
100 }
101
102 // Non-copyable, non-movable
103 native_io_context(native_io_context const&) = delete;
104 native_io_context& operator=(native_io_context const&) = delete;
105
106 /// Signal the context to stop processing.
107 1x void stop()
108 {
109 1x sched().stop();
110 1x }
111
112 /// Return whether the context has been stopped.
113 4x bool stopped() const noexcept
114 {
115 4x return const_cast<native_io_context*>(this)->sched().stopped();
116 }
117
118 /// Restart the context after being stopped.
119 1x void restart()
120 {
121 1x sched().restart();
122 1x }
123
124 /** Process all pending work items.
125
126 @return The number of handlers executed.
127 */
128 std::size_t run()
129 {
130 return sched().run();
131 }
132
133 /** Process at most one pending work item.
134
135 @return The number of handlers executed (0 or 1).
136 */
137 std::size_t run_one()
138 {
139 return sched().run_one();
140 }
141
142 /** Process work items for the specified duration.
143
144 @param rel_time The duration for which to process work.
145
146 @return The number of handlers executed.
147 */
148 template<class Rep, class Period>
149 1x std::size_t run_for(std::chrono::duration<Rep, Period> const& rel_time)
150 {
151
2/2
✓ Branch 3 → 4 taken 1 time.
✓ Branch 4 → 5 taken 1 time.
1x return run_until(std::chrono::steady_clock::now() + rel_time);
152 }
153
154 /** Process work items until the specified time.
155
156 @param abs_time The time point until which to process work.
157
158 @return The number of handlers executed.
159 */
160 template<class Clock, class Duration>
161 std::size_t
162 1x run_until(std::chrono::time_point<Clock, Duration> const& abs_time)
163 {
164 1x std::size_t n = 0;
165
2/2
✓ Branch 7 → 3 taken 1 time.
✓ Branch 7 → 8 taken 1 time.
2x while (run_one_until(abs_time))
166
1/2
✓ Branch 4 → 5 taken 1 time.
✗ Branch 4 → 6 not taken.
1x if (n != (std::numeric_limits<std::size_t>::max)())
167 1x ++n;
168 1x return n;
169 }
170
171 /** Process at most one work item for the specified duration.
172
173 @param rel_time The duration for which the call may block.
174
175 @return The number of handlers executed (0 or 1).
176 */
177 template<class Rep, class Period>
178 std::size_t run_one_for(std::chrono::duration<Rep, Period> const& rel_time)
179 {
180 return run_one_until(std::chrono::steady_clock::now() + rel_time);
181 }
182
183 /** Process at most one work item until the specified time.
184
185 @param abs_time The time point until which the call may block.
186
187 @return The number of handlers executed (0 or 1).
188 */
189 template<class Clock, class Duration>
190 std::size_t
191 2x run_one_until(std::chrono::time_point<Clock, Duration> const& abs_time)
192 {
193 2x typename Clock::time_point now = Clock::now();
194
2/3
✓ Branch 25 → 26 taken 2 times.
✓ Branch 27 → 4 taken 2 times.
✗ Branch 27 → 28 not taken.
2x while (now < abs_time)
195 {
196
1/1
✓ Branch 4 → 5 taken 2 times.
2x auto rel_time = abs_time - now;
197
2/3
✓ Branch 6 → 7 taken 2 times.
✗ Branch 8 → 9 not taken.
✓ Branch 8 → 12 taken 2 times.
2x if (rel_time > std::chrono::seconds(1))
198 rel_time = std::chrono::seconds(1);
199
200
1/1
✓ Branch 15 → 16 taken 2 times.
4x std::size_t s = sched().wait_one(
201 static_cast<long>(
202
1/1
✓ Branch 13 → 14 taken 2 times.
2x std::chrono::duration_cast<std::chrono::microseconds>(
203 rel_time)
204 2x .count()));
205
206
4/6
✓ Branch 16 → 17 taken 1 time.
✓ Branch 16 → 19 taken 1 time.
✓ Branch 18 → 19 taken 1 time.
✗ Branch 18 → 20 not taken.
✓ Branch 21 → 22 taken 2 times.
✗ Branch 21 → 23 not taken.
2x if (s || stopped())
207 2x return s;
208
209 now = Clock::now();
210 }
211 return 0;
212 }
213
214 /** Process all ready work items without blocking.
215
216 @return The number of handlers executed.
217 */
218 1x std::size_t poll()
219 {
220 1x return sched().poll();
221 }
222
223 /** Process at most one ready work item without blocking.
224
225 @return The number of handlers executed (0 or 1).
226 */
227 std::size_t poll_one()
228 {
229 return sched().poll_one();
230 }
231 };
232
233 } // namespace boost::corosio
234
235 #endif // BOOST_COROSIO_NATIVE_NATIVE_IO_CONTEXT_HPP
236