]>
Commit | Line | Data |
---|---|---|
b32b8144 FG |
1 | // |
2 | // io_context.hpp | |
3 | // ~~~~~~~~~~~~~~ | |
4 | // | |
f67539c2 | 5 | // Copyright (c) 2003-2020 Christopher M. Kohlhoff (chris at kohlhoff dot com) |
b32b8144 FG |
6 | // |
7 | // Distributed under the Boost Software License, Version 1.0. (See accompanying | |
8 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | |
9 | // | |
10 | ||
11 | #ifndef BOOST_ASIO_IO_CONTEXT_HPP | |
12 | #define BOOST_ASIO_IO_CONTEXT_HPP | |
13 | ||
14 | #if defined(_MSC_VER) && (_MSC_VER >= 1200) | |
15 | # pragma once | |
16 | #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) | |
17 | ||
18 | #include <boost/asio/detail/config.hpp> | |
19 | #include <cstddef> | |
20 | #include <stdexcept> | |
21 | #include <typeinfo> | |
22 | #include <boost/asio/async_result.hpp> | |
23 | #include <boost/asio/detail/noncopyable.hpp> | |
24 | #include <boost/asio/detail/wrapped_handler.hpp> | |
25 | #include <boost/system/error_code.hpp> | |
26 | #include <boost/asio/execution_context.hpp> | |
27 | ||
28 | #if defined(BOOST_ASIO_HAS_CHRONO) | |
29 | # include <boost/asio/detail/chrono.hpp> | |
30 | #endif // defined(BOOST_ASIO_HAS_CHRONO) | |
31 | ||
32 | #if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) | |
33 | # include <boost/asio/detail/winsock_init.hpp> | |
34 | #elif defined(__sun) || defined(__QNX__) || defined(__hpux) || defined(_AIX) \ | |
35 | || defined(__osf__) | |
36 | # include <boost/asio/detail/signal_init.hpp> | |
37 | #endif | |
38 | ||
39 | #include <boost/asio/detail/push_options.hpp> | |
40 | ||
41 | namespace boost { | |
42 | namespace asio { | |
43 | ||
44 | namespace detail { | |
45 | #if defined(BOOST_ASIO_HAS_IOCP) | |
46 | typedef class win_iocp_io_context io_context_impl; | |
47 | class win_iocp_overlapped_ptr; | |
48 | #else | |
49 | typedef class scheduler io_context_impl; | |
50 | #endif | |
51 | } // namespace detail | |
52 | ||
53 | /// Provides core I/O functionality. | |
54 | /** | |
55 | * The io_context class provides the core I/O functionality for users of the | |
56 | * asynchronous I/O objects, including: | |
57 | * | |
58 | * @li boost::asio::ip::tcp::socket | |
59 | * @li boost::asio::ip::tcp::acceptor | |
60 | * @li boost::asio::ip::udp::socket | |
61 | * @li boost::asio::deadline_timer. | |
62 | * | |
63 | * The io_context class also includes facilities intended for developers of | |
64 | * custom asynchronous services. | |
65 | * | |
66 | * @par Thread Safety | |
67 | * @e Distinct @e objects: Safe.@n | |
68 | * @e Shared @e objects: Safe, with the specific exceptions of the restart() | |
69 | * and notify_fork() functions. Calling restart() while there are unfinished | |
70 | * run(), run_one(), run_for(), run_until(), poll() or poll_one() calls results | |
71 | * in undefined behaviour. The notify_fork() function should not be called | |
72 | * while any io_context function, or any function on an I/O object that is | |
73 | * associated with the io_context, is being called in another thread. | |
74 | * | |
75 | * @par Concepts: | |
76 | * Dispatcher. | |
77 | * | |
78 | * @par Synchronous and asynchronous operations | |
79 | * | |
80 | * Synchronous operations on I/O objects implicitly run the io_context object | |
81 | * for an individual operation. The io_context functions run(), run_one(), | |
82 | * run_for(), run_until(), poll() or poll_one() must be called for the | |
83 | * io_context to perform asynchronous operations on behalf of a C++ program. | |
84 | * Notification that an asynchronous operation has completed is delivered by | |
85 | * invocation of the associated handler. Handlers are invoked only by a thread | |
86 | * that is currently calling any overload of run(), run_one(), run_for(), | |
87 | * run_until(), poll() or poll_one() for the io_context. | |
88 | * | |
89 | * @par Effect of exceptions thrown from handlers | |
90 | * | |
91 | * If an exception is thrown from a handler, the exception is allowed to | |
92 | * propagate through the throwing thread's invocation of run(), run_one(), | |
93 | * run_for(), run_until(), poll() or poll_one(). No other threads that are | |
94 | * calling any of these functions are affected. It is then the responsibility | |
95 | * of the application to catch the exception. | |
96 | * | |
97 | * After the exception has been caught, the run(), run_one(), run_for(), | |
98 | * run_until(), poll() or poll_one() call may be restarted @em without the need | |
99 | * for an intervening call to restart(). This allows the thread to rejoin the | |
100 | * io_context object's thread pool without impacting any other threads in the | |
101 | * pool. | |
102 | * | |
103 | * For example: | |
104 | * | |
105 | * @code | |
106 | * boost::asio::io_context io_context; | |
107 | * ... | |
108 | * for (;;) | |
109 | * { | |
110 | * try | |
111 | * { | |
112 | * io_context.run(); | |
113 | * break; // run() exited normally | |
114 | * } | |
115 | * catch (my_exception& e) | |
116 | * { | |
117 | * // Deal with exception as appropriate. | |
118 | * } | |
119 | * } | |
120 | * @endcode | |
121 | * | |
122 | * @par Submitting arbitrary tasks to the io_context | |
123 | * | |
124 | * To submit functions to the io_context, use the @ref boost::asio::dispatch, | |
125 | * @ref boost::asio::post or @ref boost::asio::defer free functions. | |
126 | * | |
127 | * For example: | |
128 | * | |
129 | * @code void my_task() | |
130 | * { | |
131 | * ... | |
132 | * } | |
133 | * | |
134 | * ... | |
135 | * | |
136 | * boost::asio::io_context io_context; | |
137 | * | |
138 | * // Submit a function to the io_context. | |
139 | * boost::asio::post(io_context, my_task); | |
140 | * | |
141 | * // Submit a lambda object to the io_context. | |
142 | * boost::asio::post(io_context, | |
143 | * []() | |
144 | * { | |
145 | * ... | |
146 | * }); | |
147 | * | |
148 | * // Run the io_context until it runs out of work. | |
149 | * io_context.run(); @endcode | |
150 | * | |
151 | * @par Stopping the io_context from running out of work | |
152 | * | |
153 | * Some applications may need to prevent an io_context object's run() call from | |
154 | * returning when there is no more work to do. For example, the io_context may | |
155 | * be being run in a background thread that is launched prior to the | |
156 | * application's asynchronous operations. The run() call may be kept running by | |
157 | * creating an object of type | |
158 | * boost::asio::executor_work_guard<io_context::executor_type>: | |
159 | * | |
160 | * @code boost::asio::io_context io_context; | |
161 | * boost::asio::executor_work_guard<boost::asio::io_context::executor_type> | |
162 | * = boost::asio::make_work_guard(io_context); | |
163 | * ... @endcode | |
164 | * | |
165 | * To effect a shutdown, the application will then need to call the io_context | |
166 | * object's stop() member function. This will cause the io_context run() call | |
167 | * to return as soon as possible, abandoning unfinished operations and without | |
168 | * permitting ready handlers to be dispatched. | |
169 | * | |
170 | * Alternatively, if the application requires that all operations and handlers | |
171 | * be allowed to finish normally, the work object may be explicitly reset. | |
172 | * | |
173 | * @code boost::asio::io_context io_context; | |
174 | * boost::asio::executor_work_guard<boost::asio::io_context::executor_type> | |
175 | * = boost::asio::make_work_guard(io_context); | |
176 | * ... | |
177 | * work.reset(); // Allow run() to exit. @endcode | |
178 | */ | |
179 | class io_context | |
180 | : public execution_context | |
181 | { | |
182 | private: | |
183 | typedef detail::io_context_impl impl_type; | |
184 | #if defined(BOOST_ASIO_HAS_IOCP) | |
185 | friend class detail::win_iocp_overlapped_ptr; | |
186 | #endif | |
187 | ||
188 | public: | |
189 | class executor_type; | |
190 | friend class executor_type; | |
191 | ||
192 | #if !defined(BOOST_ASIO_NO_DEPRECATED) | |
193 | class work; | |
194 | friend class work; | |
195 | #endif // !defined(BOOST_ASIO_NO_DEPRECATED) | |
196 | ||
197 | class service; | |
198 | ||
199 | #if !defined(BOOST_ASIO_NO_EXTENSIONS) | |
200 | class strand; | |
201 | #endif // !defined(BOOST_ASIO_NO_EXTENSIONS) | |
202 | ||
203 | /// The type used to count the number of handlers executed by the context. | |
204 | typedef std::size_t count_type; | |
205 | ||
206 | /// Constructor. | |
207 | BOOST_ASIO_DECL io_context(); | |
208 | ||
209 | /// Constructor. | |
210 | /** | |
211 | * Construct with a hint about the required level of concurrency. | |
212 | * | |
213 | * @param concurrency_hint A suggestion to the implementation on how many | |
214 | * threads it should allow to run simultaneously. | |
215 | */ | |
216 | BOOST_ASIO_DECL explicit io_context(int concurrency_hint); | |
217 | ||
218 | /// Destructor. | |
219 | /** | |
220 | * On destruction, the io_context performs the following sequence of | |
221 | * operations: | |
222 | * | |
223 | * @li For each service object @c svc in the io_context set, in reverse order | |
224 | * of the beginning of service object lifetime, performs | |
225 | * @c svc->shutdown(). | |
226 | * | |
227 | * @li Uninvoked handler objects that were scheduled for deferred invocation | |
228 | * on the io_context, or any associated strand, are destroyed. | |
229 | * | |
230 | * @li For each service object @c svc in the io_context set, in reverse order | |
231 | * of the beginning of service object lifetime, performs | |
232 | * <tt>delete static_cast<io_context::service*>(svc)</tt>. | |
233 | * | |
234 | * @note The destruction sequence described above permits programs to | |
235 | * simplify their resource management by using @c shared_ptr<>. Where an | |
236 | * object's lifetime is tied to the lifetime of a connection (or some other | |
237 | * sequence of asynchronous operations), a @c shared_ptr to the object would | |
238 | * be bound into the handlers for all asynchronous operations associated with | |
239 | * it. This works as follows: | |
240 | * | |
241 | * @li When a single connection ends, all associated asynchronous operations | |
242 | * complete. The corresponding handler objects are destroyed, and all | |
243 | * @c shared_ptr references to the objects are destroyed. | |
244 | * | |
245 | * @li To shut down the whole program, the io_context function stop() is | |
246 | * called to terminate any run() calls as soon as possible. The io_context | |
247 | * destructor defined above destroys all handlers, causing all @c shared_ptr | |
248 | * references to all connection objects to be destroyed. | |
249 | */ | |
250 | BOOST_ASIO_DECL ~io_context(); | |
251 | ||
252 | /// Obtains the executor associated with the io_context. | |
253 | executor_type get_executor() BOOST_ASIO_NOEXCEPT; | |
254 | ||
255 | /// Run the io_context object's event processing loop. | |
256 | /** | |
257 | * The run() function blocks until all work has finished and there are no | |
258 | * more handlers to be dispatched, or until the io_context has been stopped. | |
259 | * | |
260 | * Multiple threads may call the run() function to set up a pool of threads | |
261 | * from which the io_context may execute handlers. All threads that are | |
262 | * waiting in the pool are equivalent and the io_context may choose any one | |
263 | * of them to invoke a handler. | |
264 | * | |
265 | * A normal exit from the run() function implies that the io_context object | |
266 | * is stopped (the stopped() function returns @c true). Subsequent calls to | |
267 | * run(), run_one(), poll() or poll_one() will return immediately unless there | |
268 | * is a prior call to restart(). | |
269 | * | |
270 | * @return The number of handlers that were executed. | |
271 | * | |
272 | * @note Calling the run() function from a thread that is currently calling | |
273 | * one of run(), run_one(), run_for(), run_until(), poll() or poll_one() on | |
274 | * the same io_context object may introduce the potential for deadlock. It is | |
275 | * the caller's reponsibility to avoid this. | |
276 | * | |
277 | * The poll() function may also be used to dispatch ready handlers, but | |
278 | * without blocking. | |
279 | */ | |
280 | BOOST_ASIO_DECL count_type run(); | |
281 | ||
282 | #if !defined(BOOST_ASIO_NO_DEPRECATED) | |
283 | /// (Deprecated: Use non-error_code overload.) Run the io_context object's | |
284 | /// event processing loop. | |
285 | /** | |
286 | * The run() function blocks until all work has finished and there are no | |
287 | * more handlers to be dispatched, or until the io_context has been stopped. | |
288 | * | |
289 | * Multiple threads may call the run() function to set up a pool of threads | |
290 | * from which the io_context may execute handlers. All threads that are | |
291 | * waiting in the pool are equivalent and the io_context may choose any one | |
292 | * of them to invoke a handler. | |
293 | * | |
294 | * A normal exit from the run() function implies that the io_context object | |
295 | * is stopped (the stopped() function returns @c true). Subsequent calls to | |
296 | * run(), run_one(), poll() or poll_one() will return immediately unless there | |
297 | * is a prior call to restart(). | |
298 | * | |
299 | * @param ec Set to indicate what error occurred, if any. | |
300 | * | |
301 | * @return The number of handlers that were executed. | |
302 | * | |
303 | * @note Calling the run() function from a thread that is currently calling | |
304 | * one of run(), run_one(), run_for(), run_until(), poll() or poll_one() on | |
305 | * the same io_context object may introduce the potential for deadlock. It is | |
306 | * the caller's reponsibility to avoid this. | |
307 | * | |
308 | * The poll() function may also be used to dispatch ready handlers, but | |
309 | * without blocking. | |
310 | */ | |
311 | BOOST_ASIO_DECL count_type run(boost::system::error_code& ec); | |
312 | #endif // !defined(BOOST_ASIO_NO_DEPRECATED) | |
313 | ||
314 | #if defined(BOOST_ASIO_HAS_CHRONO) || defined(GENERATING_DOCUMENTATION) | |
315 | /// Run the io_context object's event processing loop for a specified | |
316 | /// duration. | |
317 | /** | |
318 | * The run_for() function blocks until all work has finished and there are no | |
319 | * more handlers to be dispatched, until the io_context has been stopped, or | |
320 | * until the specified duration has elapsed. | |
321 | * | |
322 | * @param rel_time The duration for which the call may block. | |
323 | * | |
324 | * @return The number of handlers that were executed. | |
325 | */ | |
326 | template <typename Rep, typename Period> | |
327 | std::size_t run_for(const chrono::duration<Rep, Period>& rel_time); | |
328 | ||
329 | /// Run the io_context object's event processing loop until a specified time. | |
330 | /** | |
331 | * The run_until() function blocks until all work has finished and there are | |
332 | * no more handlers to be dispatched, until the io_context has been stopped, | |
333 | * or until the specified time has been reached. | |
334 | * | |
335 | * @param abs_time The time point until which the call may block. | |
336 | * | |
337 | * @return The number of handlers that were executed. | |
338 | */ | |
339 | template <typename Clock, typename Duration> | |
340 | std::size_t run_until(const chrono::time_point<Clock, Duration>& abs_time); | |
341 | #endif // defined(BOOST_ASIO_HAS_CHRONO) || defined(GENERATING_DOCUMENTATION) | |
342 | ||
343 | /// Run the io_context object's event processing loop to execute at most one | |
344 | /// handler. | |
345 | /** | |
346 | * The run_one() function blocks until one handler has been dispatched, or | |
347 | * until the io_context has been stopped. | |
348 | * | |
349 | * @return The number of handlers that were executed. A zero return value | |
350 | * implies that the io_context object is stopped (the stopped() function | |
351 | * returns @c true). Subsequent calls to run(), run_one(), poll() or | |
352 | * poll_one() will return immediately unless there is a prior call to | |
353 | * restart(). | |
354 | * | |
355 | * @note Calling the run_one() function from a thread that is currently | |
356 | * calling one of run(), run_one(), run_for(), run_until(), poll() or | |
357 | * poll_one() on the same io_context object may introduce the potential for | |
358 | * deadlock. It is the caller's reponsibility to avoid this. | |
359 | */ | |
360 | BOOST_ASIO_DECL count_type run_one(); | |
361 | ||
362 | #if !defined(BOOST_ASIO_NO_DEPRECATED) | |
363 | /// (Deprecated: Use non-error_code overlaod.) Run the io_context object's | |
364 | /// event processing loop to execute at most one handler. | |
365 | /** | |
366 | * The run_one() function blocks until one handler has been dispatched, or | |
367 | * until the io_context has been stopped. | |
368 | * | |
369 | * @return The number of handlers that were executed. A zero return value | |
370 | * implies that the io_context object is stopped (the stopped() function | |
371 | * returns @c true). Subsequent calls to run(), run_one(), poll() or | |
372 | * poll_one() will return immediately unless there is a prior call to | |
373 | * restart(). | |
374 | * | |
375 | * @return The number of handlers that were executed. | |
376 | * | |
377 | * @note Calling the run_one() function from a thread that is currently | |
378 | * calling one of run(), run_one(), run_for(), run_until(), poll() or | |
379 | * poll_one() on the same io_context object may introduce the potential for | |
380 | * deadlock. It is the caller's reponsibility to avoid this. | |
381 | */ | |
382 | BOOST_ASIO_DECL count_type run_one(boost::system::error_code& ec); | |
383 | #endif // !defined(BOOST_ASIO_NO_DEPRECATED) | |
384 | ||
385 | #if defined(BOOST_ASIO_HAS_CHRONO) || defined(GENERATING_DOCUMENTATION) | |
386 | /// Run the io_context object's event processing loop for a specified duration | |
387 | /// to execute at most one handler. | |
388 | /** | |
389 | * The run_one_for() function blocks until one handler has been dispatched, | |
390 | * until the io_context has been stopped, or until the specified duration has | |
391 | * elapsed. | |
392 | * | |
393 | * @param rel_time The duration for which the call may block. | |
394 | * | |
395 | * @return The number of handlers that were executed. | |
396 | */ | |
397 | template <typename Rep, typename Period> | |
398 | std::size_t run_one_for(const chrono::duration<Rep, Period>& rel_time); | |
399 | ||
400 | /// Run the io_context object's event processing loop until a specified time | |
401 | /// to execute at most one handler. | |
402 | /** | |
403 | * The run_one_until() function blocks until one handler has been dispatched, | |
404 | * until the io_context has been stopped, or until the specified time has | |
405 | * been reached. | |
406 | * | |
407 | * @param abs_time The time point until which the call may block. | |
408 | * | |
409 | * @return The number of handlers that were executed. | |
410 | */ | |
411 | template <typename Clock, typename Duration> | |
412 | std::size_t run_one_until( | |
413 | const chrono::time_point<Clock, Duration>& abs_time); | |
414 | #endif // defined(BOOST_ASIO_HAS_CHRONO) || defined(GENERATING_DOCUMENTATION) | |
415 | ||
416 | /// Run the io_context object's event processing loop to execute ready | |
417 | /// handlers. | |
418 | /** | |
419 | * The poll() function runs handlers that are ready to run, without blocking, | |
420 | * until the io_context has been stopped or there are no more ready handlers. | |
421 | * | |
422 | * @return The number of handlers that were executed. | |
423 | */ | |
424 | BOOST_ASIO_DECL count_type poll(); | |
425 | ||
426 | #if !defined(BOOST_ASIO_NO_DEPRECATED) | |
427 | /// (Deprecated: Use non-error_code overload.) Run the io_context object's | |
428 | /// event processing loop to execute ready handlers. | |
429 | /** | |
430 | * The poll() function runs handlers that are ready to run, without blocking, | |
431 | * until the io_context has been stopped or there are no more ready handlers. | |
432 | * | |
433 | * @param ec Set to indicate what error occurred, if any. | |
434 | * | |
435 | * @return The number of handlers that were executed. | |
436 | */ | |
437 | BOOST_ASIO_DECL count_type poll(boost::system::error_code& ec); | |
438 | #endif // !defined(BOOST_ASIO_NO_DEPRECATED) | |
439 | ||
440 | /// Run the io_context object's event processing loop to execute one ready | |
441 | /// handler. | |
442 | /** | |
443 | * The poll_one() function runs at most one handler that is ready to run, | |
444 | * without blocking. | |
445 | * | |
446 | * @return The number of handlers that were executed. | |
447 | */ | |
448 | BOOST_ASIO_DECL count_type poll_one(); | |
449 | ||
450 | #if !defined(BOOST_ASIO_NO_DEPRECATED) | |
451 | /// (Deprecated: Use non-error_code overload.) Run the io_context object's | |
452 | /// event processing loop to execute one ready handler. | |
453 | /** | |
454 | * The poll_one() function runs at most one handler that is ready to run, | |
455 | * without blocking. | |
456 | * | |
457 | * @param ec Set to indicate what error occurred, if any. | |
458 | * | |
459 | * @return The number of handlers that were executed. | |
460 | */ | |
461 | BOOST_ASIO_DECL count_type poll_one(boost::system::error_code& ec); | |
462 | #endif // !defined(BOOST_ASIO_NO_DEPRECATED) | |
463 | ||
464 | /// Stop the io_context object's event processing loop. | |
465 | /** | |
466 | * This function does not block, but instead simply signals the io_context to | |
467 | * stop. All invocations of its run() or run_one() member functions should | |
468 | * return as soon as possible. Subsequent calls to run(), run_one(), poll() | |
469 | * or poll_one() will return immediately until restart() is called. | |
470 | */ | |
471 | BOOST_ASIO_DECL void stop(); | |
472 | ||
473 | /// Determine whether the io_context object has been stopped. | |
474 | /** | |
475 | * This function is used to determine whether an io_context object has been | |
476 | * stopped, either through an explicit call to stop(), or due to running out | |
477 | * of work. When an io_context object is stopped, calls to run(), run_one(), | |
478 | * poll() or poll_one() will return immediately without invoking any | |
479 | * handlers. | |
480 | * | |
481 | * @return @c true if the io_context object is stopped, otherwise @c false. | |
482 | */ | |
483 | BOOST_ASIO_DECL bool stopped() const; | |
484 | ||
485 | /// Restart the io_context in preparation for a subsequent run() invocation. | |
486 | /** | |
487 | * This function must be called prior to any second or later set of | |
488 | * invocations of the run(), run_one(), poll() or poll_one() functions when a | |
489 | * previous invocation of these functions returned due to the io_context | |
490 | * being stopped or running out of work. After a call to restart(), the | |
491 | * io_context object's stopped() function will return @c false. | |
492 | * | |
493 | * This function must not be called while there are any unfinished calls to | |
494 | * the run(), run_one(), poll() or poll_one() functions. | |
495 | */ | |
496 | BOOST_ASIO_DECL void restart(); | |
497 | ||
498 | #if !defined(BOOST_ASIO_NO_DEPRECATED) | |
499 | /// (Deprecated: Use restart().) Reset the io_context in preparation for a | |
500 | /// subsequent run() invocation. | |
501 | /** | |
502 | * This function must be called prior to any second or later set of | |
503 | * invocations of the run(), run_one(), poll() or poll_one() functions when a | |
504 | * previous invocation of these functions returned due to the io_context | |
505 | * being stopped or running out of work. After a call to restart(), the | |
506 | * io_context object's stopped() function will return @c false. | |
507 | * | |
508 | * This function must not be called while there are any unfinished calls to | |
509 | * the run(), run_one(), poll() or poll_one() functions. | |
510 | */ | |
511 | void reset(); | |
512 | ||
513 | /// (Deprecated: Use boost::asio::dispatch().) Request the io_context to | |
514 | /// invoke the given handler. | |
515 | /** | |
516 | * This function is used to ask the io_context to execute the given handler. | |
517 | * | |
518 | * The io_context guarantees that the handler will only be called in a thread | |
519 | * in which the run(), run_one(), poll() or poll_one() member functions is | |
520 | * currently being invoked. The handler may be executed inside this function | |
521 | * if the guarantee can be met. | |
522 | * | |
523 | * @param handler The handler to be called. The io_context will make | |
524 | * a copy of the handler object as required. The function signature of the | |
525 | * handler must be: @code void handler(); @endcode | |
526 | * | |
527 | * @note This function throws an exception only if: | |
528 | * | |
529 | * @li the handler's @c asio_handler_allocate function; or | |
530 | * | |
531 | * @li the handler's copy constructor | |
532 | * | |
533 | * throws an exception. | |
534 | */ | |
11fdf7f2 | 535 | template <typename LegacyCompletionHandler> |
92f5a8d4 | 536 | BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(LegacyCompletionHandler, void ()) |
11fdf7f2 | 537 | dispatch(BOOST_ASIO_MOVE_ARG(LegacyCompletionHandler) handler); |
b32b8144 FG |
538 | |
539 | /// (Deprecated: Use boost::asio::post().) Request the io_context to invoke | |
540 | /// the given handler and return immediately. | |
541 | /** | |
542 | * This function is used to ask the io_context to execute the given handler, | |
543 | * but without allowing the io_context to call the handler from inside this | |
544 | * function. | |
545 | * | |
546 | * The io_context guarantees that the handler will only be called in a thread | |
547 | * in which the run(), run_one(), poll() or poll_one() member functions is | |
548 | * currently being invoked. | |
549 | * | |
550 | * @param handler The handler to be called. The io_context will make | |
551 | * a copy of the handler object as required. The function signature of the | |
552 | * handler must be: @code void handler(); @endcode | |
553 | * | |
554 | * @note This function throws an exception only if: | |
555 | * | |
556 | * @li the handler's @c asio_handler_allocate function; or | |
557 | * | |
558 | * @li the handler's copy constructor | |
559 | * | |
560 | * throws an exception. | |
561 | */ | |
11fdf7f2 | 562 | template <typename LegacyCompletionHandler> |
92f5a8d4 | 563 | BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(LegacyCompletionHandler, void ()) |
11fdf7f2 | 564 | post(BOOST_ASIO_MOVE_ARG(LegacyCompletionHandler) handler); |
b32b8144 FG |
565 | |
566 | /// (Deprecated: Use boost::asio::bind_executor().) Create a new handler that | |
567 | /// automatically dispatches the wrapped handler on the io_context. | |
568 | /** | |
569 | * This function is used to create a new handler function object that, when | |
570 | * invoked, will automatically pass the wrapped handler to the io_context | |
571 | * object's dispatch function. | |
572 | * | |
573 | * @param handler The handler to be wrapped. The io_context will make a copy | |
574 | * of the handler object as required. The function signature of the handler | |
575 | * must be: @code void handler(A1 a1, ... An an); @endcode | |
576 | * | |
577 | * @return A function object that, when invoked, passes the wrapped handler to | |
578 | * the io_context object's dispatch function. Given a function object with the | |
579 | * signature: | |
580 | * @code R f(A1 a1, ... An an); @endcode | |
581 | * If this function object is passed to the wrap function like so: | |
582 | * @code io_context.wrap(f); @endcode | |
583 | * then the return value is a function object with the signature | |
584 | * @code void g(A1 a1, ... An an); @endcode | |
585 | * that, when invoked, executes code equivalent to: | |
586 | * @code io_context.dispatch(boost::bind(f, a1, ... an)); @endcode | |
587 | */ | |
588 | template <typename Handler> | |
589 | #if defined(GENERATING_DOCUMENTATION) | |
590 | unspecified | |
591 | #else | |
592 | detail::wrapped_handler<io_context&, Handler> | |
593 | #endif | |
594 | wrap(Handler handler); | |
595 | #endif // !defined(BOOST_ASIO_NO_DEPRECATED) | |
596 | ||
597 | private: | |
92f5a8d4 TL |
598 | #if !defined(BOOST_ASIO_NO_DEPRECATED) |
599 | struct initiate_dispatch; | |
600 | struct initiate_post; | |
601 | #endif // !defined(BOOST_ASIO_NO_DEPRECATED) | |
602 | ||
b32b8144 FG |
603 | // Helper function to add the implementation. |
604 | BOOST_ASIO_DECL impl_type& add_impl(impl_type* impl); | |
605 | ||
606 | // Backwards compatible overload for use with services derived from | |
607 | // io_context::service. | |
608 | template <typename Service> | |
609 | friend Service& use_service(io_context& ioc); | |
610 | ||
611 | #if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) | |
612 | detail::winsock_init<> init_; | |
613 | #elif defined(__sun) || defined(__QNX__) || defined(__hpux) || defined(_AIX) \ | |
614 | || defined(__osf__) | |
615 | detail::signal_init<> init_; | |
616 | #endif | |
617 | ||
618 | // The implementation. | |
619 | impl_type& impl_; | |
620 | }; | |
621 | ||
622 | /// Executor used to submit functions to an io_context. | |
623 | class io_context::executor_type | |
624 | { | |
625 | public: | |
626 | /// Obtain the underlying execution context. | |
627 | io_context& context() const BOOST_ASIO_NOEXCEPT; | |
628 | ||
629 | /// Inform the io_context that it has some outstanding work to do. | |
630 | /** | |
631 | * This function is used to inform the io_context that some work has begun. | |
632 | * This ensures that the io_context's run() and run_one() functions do not | |
633 | * exit while the work is underway. | |
634 | */ | |
635 | void on_work_started() const BOOST_ASIO_NOEXCEPT; | |
636 | ||
637 | /// Inform the io_context that some work is no longer outstanding. | |
638 | /** | |
639 | * This function is used to inform the io_context that some work has | |
640 | * finished. Once the count of unfinished work reaches zero, the io_context | |
641 | * is stopped and the run() and run_one() functions may exit. | |
642 | */ | |
643 | void on_work_finished() const BOOST_ASIO_NOEXCEPT; | |
644 | ||
645 | /// Request the io_context to invoke the given function object. | |
646 | /** | |
647 | * This function is used to ask the io_context to execute the given function | |
648 | * object. If the current thread is running the io_context, @c dispatch() | |
649 | * executes the function before returning. Otherwise, the function will be | |
650 | * scheduled to run on the io_context. | |
651 | * | |
652 | * @param f The function object to be called. The executor will make a copy | |
653 | * of the handler object as required. The function signature of the function | |
654 | * object must be: @code void function(); @endcode | |
655 | * | |
656 | * @param a An allocator that may be used by the executor to allocate the | |
657 | * internal storage needed for function invocation. | |
658 | */ | |
659 | template <typename Function, typename Allocator> | |
660 | void dispatch(BOOST_ASIO_MOVE_ARG(Function) f, const Allocator& a) const; | |
661 | ||
662 | /// Request the io_context to invoke the given function object. | |
663 | /** | |
664 | * This function is used to ask the io_context to execute the given function | |
665 | * object. The function object will never be executed inside @c post(). | |
666 | * Instead, it will be scheduled to run on the io_context. | |
667 | * | |
668 | * @param f The function object to be called. The executor will make a copy | |
669 | * of the handler object as required. The function signature of the function | |
670 | * object must be: @code void function(); @endcode | |
671 | * | |
672 | * @param a An allocator that may be used by the executor to allocate the | |
673 | * internal storage needed for function invocation. | |
674 | */ | |
675 | template <typename Function, typename Allocator> | |
676 | void post(BOOST_ASIO_MOVE_ARG(Function) f, const Allocator& a) const; | |
677 | ||
678 | /// Request the io_context to invoke the given function object. | |
679 | /** | |
680 | * This function is used to ask the io_context to execute the given function | |
681 | * object. The function object will never be executed inside @c defer(). | |
682 | * Instead, it will be scheduled to run on the io_context. | |
683 | * | |
684 | * If the current thread belongs to the io_context, @c defer() will delay | |
685 | * scheduling the function object until the current thread returns control to | |
686 | * the pool. | |
687 | * | |
688 | * @param f The function object to be called. The executor will make a copy | |
689 | * of the handler object as required. The function signature of the function | |
690 | * object must be: @code void function(); @endcode | |
691 | * | |
692 | * @param a An allocator that may be used by the executor to allocate the | |
693 | * internal storage needed for function invocation. | |
694 | */ | |
695 | template <typename Function, typename Allocator> | |
696 | void defer(BOOST_ASIO_MOVE_ARG(Function) f, const Allocator& a) const; | |
697 | ||
698 | /// Determine whether the io_context is running in the current thread. | |
699 | /** | |
700 | * @return @c true if the current thread is running the io_context. Otherwise | |
701 | * returns @c false. | |
702 | */ | |
703 | bool running_in_this_thread() const BOOST_ASIO_NOEXCEPT; | |
704 | ||
705 | /// Compare two executors for equality. | |
706 | /** | |
707 | * Two executors are equal if they refer to the same underlying io_context. | |
708 | */ | |
709 | friend bool operator==(const executor_type& a, | |
710 | const executor_type& b) BOOST_ASIO_NOEXCEPT | |
711 | { | |
712 | return &a.io_context_ == &b.io_context_; | |
713 | } | |
714 | ||
715 | /// Compare two executors for inequality. | |
716 | /** | |
717 | * Two executors are equal if they refer to the same underlying io_context. | |
718 | */ | |
719 | friend bool operator!=(const executor_type& a, | |
720 | const executor_type& b) BOOST_ASIO_NOEXCEPT | |
721 | { | |
722 | return &a.io_context_ != &b.io_context_; | |
723 | } | |
724 | ||
725 | private: | |
726 | friend class io_context; | |
727 | ||
728 | // Constructor. | |
729 | explicit executor_type(io_context& i) : io_context_(i) {} | |
730 | ||
731 | // The underlying io_context. | |
732 | io_context& io_context_; | |
733 | }; | |
734 | ||
735 | #if !defined(BOOST_ASIO_NO_DEPRECATED) | |
736 | /// (Deprecated: Use executor_work_guard.) Class to inform the io_context when | |
737 | /// it has work to do. | |
738 | /** | |
739 | * The work class is used to inform the io_context when work starts and | |
740 | * finishes. This ensures that the io_context object's run() function will not | |
741 | * exit while work is underway, and that it does exit when there is no | |
742 | * unfinished work remaining. | |
743 | * | |
744 | * The work class is copy-constructible so that it may be used as a data member | |
745 | * in a handler class. It is not assignable. | |
746 | */ | |
747 | class io_context::work | |
748 | { | |
749 | public: | |
750 | /// Constructor notifies the io_context that work is starting. | |
751 | /** | |
752 | * The constructor is used to inform the io_context that some work has begun. | |
753 | * This ensures that the io_context object's run() function will not exit | |
754 | * while the work is underway. | |
755 | */ | |
756 | explicit work(boost::asio::io_context& io_context); | |
757 | ||
758 | /// Copy constructor notifies the io_context that work is starting. | |
759 | /** | |
760 | * The constructor is used to inform the io_context that some work has begun. | |
761 | * This ensures that the io_context object's run() function will not exit | |
762 | * while the work is underway. | |
763 | */ | |
764 | work(const work& other); | |
765 | ||
766 | /// Destructor notifies the io_context that the work is complete. | |
767 | /** | |
768 | * The destructor is used to inform the io_context that some work has | |
769 | * finished. Once the count of unfinished work reaches zero, the io_context | |
770 | * object's run() function is permitted to exit. | |
771 | */ | |
772 | ~work(); | |
773 | ||
774 | /// Get the io_context associated with the work. | |
775 | boost::asio::io_context& get_io_context(); | |
776 | ||
b32b8144 FG |
777 | private: |
778 | // Prevent assignment. | |
779 | void operator=(const work& other); | |
780 | ||
781 | // The io_context implementation. | |
782 | detail::io_context_impl& io_context_impl_; | |
783 | }; | |
784 | #endif // !defined(BOOST_ASIO_NO_DEPRECATED) | |
785 | ||
786 | /// Base class for all io_context services. | |
787 | class io_context::service | |
788 | : public execution_context::service | |
789 | { | |
790 | public: | |
791 | /// Get the io_context object that owns the service. | |
792 | boost::asio::io_context& get_io_context(); | |
793 | ||
b32b8144 FG |
794 | private: |
795 | /// Destroy all user-defined handler objects owned by the service. | |
796 | BOOST_ASIO_DECL virtual void shutdown(); | |
797 | ||
798 | #if !defined(BOOST_ASIO_NO_DEPRECATED) | |
799 | /// (Deprecated: Use shutdown().) Destroy all user-defined handler objects | |
800 | /// owned by the service. | |
801 | BOOST_ASIO_DECL virtual void shutdown_service(); | |
802 | #endif // !defined(BOOST_ASIO_NO_DEPRECATED) | |
803 | ||
804 | /// Handle notification of a fork-related event to perform any necessary | |
805 | /// housekeeping. | |
806 | /** | |
807 | * This function is not a pure virtual so that services only have to | |
808 | * implement it if necessary. The default implementation does nothing. | |
809 | */ | |
810 | BOOST_ASIO_DECL virtual void notify_fork( | |
811 | execution_context::fork_event event); | |
812 | ||
813 | #if !defined(BOOST_ASIO_NO_DEPRECATED) | |
814 | /// (Deprecated: Use notify_fork().) Handle notification of a fork-related | |
815 | /// event to perform any necessary housekeeping. | |
816 | /** | |
817 | * This function is not a pure virtual so that services only have to | |
818 | * implement it if necessary. The default implementation does nothing. | |
819 | */ | |
820 | BOOST_ASIO_DECL virtual void fork_service( | |
821 | execution_context::fork_event event); | |
822 | #endif // !defined(BOOST_ASIO_NO_DEPRECATED) | |
823 | ||
824 | protected: | |
825 | /// Constructor. | |
826 | /** | |
827 | * @param owner The io_context object that owns the service. | |
828 | */ | |
829 | BOOST_ASIO_DECL service(boost::asio::io_context& owner); | |
830 | ||
831 | /// Destructor. | |
832 | BOOST_ASIO_DECL virtual ~service(); | |
833 | }; | |
834 | ||
835 | namespace detail { | |
836 | ||
837 | // Special service base class to keep classes header-file only. | |
838 | template <typename Type> | |
839 | class service_base | |
840 | : public boost::asio::io_context::service | |
841 | { | |
842 | public: | |
843 | static boost::asio::detail::service_id<Type> id; | |
844 | ||
845 | // Constructor. | |
846 | service_base(boost::asio::io_context& io_context) | |
847 | : boost::asio::io_context::service(io_context) | |
848 | { | |
849 | } | |
850 | }; | |
851 | ||
852 | template <typename Type> | |
853 | boost::asio::detail::service_id<Type> service_base<Type>::id; | |
854 | ||
855 | } // namespace detail | |
856 | } // namespace asio | |
857 | } // namespace boost | |
858 | ||
859 | #include <boost/asio/detail/pop_options.hpp> | |
860 | ||
861 | #include <boost/asio/impl/io_context.hpp> | |
862 | #if defined(BOOST_ASIO_HEADER_ONLY) | |
863 | # include <boost/asio/impl/io_context.ipp> | |
864 | #endif // defined(BOOST_ASIO_HEADER_ONLY) | |
865 | ||
866 | // If both io_context.hpp and strand.hpp have been included, automatically | |
867 | // include the header file needed for the io_context::strand class. | |
868 | #if !defined(BOOST_ASIO_NO_EXTENSIONS) | |
869 | # if defined(BOOST_ASIO_STRAND_HPP) | |
870 | # include <boost/asio/io_context_strand.hpp> | |
871 | # endif // defined(BOOST_ASIO_STRAND_HPP) | |
872 | #endif // !defined(BOOST_ASIO_NO_EXTENSIONS) | |
873 | ||
874 | #endif // BOOST_ASIO_IO_CONTEXT_HPP |