io_context.hpp 32 KB

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