1 // 2 // io_service.hpp 3 // ~~~~~~~~~~~~~~ 4 // 5 // Copyright (c) 2003-2015 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 11 #ifndef BOOST_ASIO_IO_SERVICE_HPP 12 #define BOOST_ASIO_IO_SERVICE_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 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 34 #include <boost/asio/detail/push_options.hpp> 35 36 namespace boost { 37 namespace asio { 38 39 class io_service; 40 template <typename Service> Service& use_service(io_service& ios); 41 template <typename Service> void add_service(io_service& ios, Service* svc); 42 template <typename Service> bool has_service(io_service& ios); 43 44 namespace detail { 45 #if defined(BOOST_ASIO_HAS_IOCP) 46 typedef class win_iocp_io_service io_service_impl; 47 class win_iocp_overlapped_ptr; 48 #else 49 typedef class task_io_service io_service_impl; 50 #endif 51 class service_registry; 52 } // namespace detail 53 54 /// Provides core I/O functionality. 55 /** 56 * The io_service class provides the core I/O functionality for users of the 57 * asynchronous I/O objects, including: 58 * 59 * @li boost::asio::ip::tcp::socket 60 * @li boost::asio::ip::tcp::acceptor 61 * @li boost::asio::ip::udp::socket 62 * @li boost::asio::deadline_timer. 63 * 64 * The io_service class also includes facilities intended for developers of 65 * custom asynchronous services. 66 * 67 * @par Thread Safety 68 * @e Distinct @e objects: Safe.@n 69 * @e Shared @e objects: Safe, with the specific exceptions of the reset() and 70 * notify_fork() functions. Calling reset() while there are unfinished run(), 71 * run_one(), poll() or poll_one() calls results in undefined behaviour. The 72 * notify_fork() function should not be called while any io_service function, 73 * or any function on an I/O object that is associated with the io_service, is 74 * being called in another thread. 75 * 76 * @par Concepts: 77 * Dispatcher. 78 * 79 * @par Synchronous and asynchronous operations 80 * 81 * Synchronous operations on I/O objects implicitly run the io_service object 82 * for an individual operation. The io_service functions run(), run_one(), 83 * poll() or poll_one() must be called for the io_service to perform 84 * asynchronous operations on behalf of a C++ program. Notification that an 85 * asynchronous operation has completed is delivered by invocation of the 86 * associated handler. Handlers are invoked only by a thread that is currently 87 * calling any overload of run(), run_one(), poll() or poll_one() for the 88 * io_service. 89 * 90 * @par Effect of exceptions thrown from handlers 91 * 92 * If an exception is thrown from a handler, the exception is allowed to 93 * propagate through the throwing thread's invocation of run(), run_one(), 94 * poll() or poll_one(). No other threads that are calling any of these 95 * functions are affected. It is then the responsibility of the application to 96 * catch the exception. 97 * 98 * After the exception has been caught, the run(), run_one(), poll() or 99 * poll_one() call may be restarted @em without the need for an intervening 100 * call to reset(). This allows the thread to rejoin the io_service object's 101 * thread pool without impacting any other threads in the pool. 102 * 103 * For example: 104 * 105 * @code 106 * boost::asio::io_service io_service; 107 * ... 108 * for (;;) 109 * { 110 * try 111 * { 112 * io_service.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 Stopping the io_service from running out of work 123 * 124 * Some applications may need to prevent an io_service object's run() call from 125 * returning when there is no more work to do. For example, the io_service may 126 * be being run in a background thread that is launched prior to the 127 * application's asynchronous operations. The run() call may be kept running by 128 * creating an object of type boost::asio::io_service::work: 129 * 130 * @code boost::asio::io_service io_service; 131 * boost::asio::io_service::work work(io_service); 132 * ... @endcode 133 * 134 * To effect a shutdown, the application will then need to call the io_service 135 * object's stop() member function. This will cause the io_service run() call 136 * to return as soon as possible, abandoning unfinished operations and without 137 * permitting ready handlers to be dispatched. 138 * 139 * Alternatively, if the application requires that all operations and handlers 140 * be allowed to finish normally, the work object may be explicitly destroyed. 141 * 142 * @code boost::asio::io_service io_service; 143 * auto_ptr<boost::asio::io_service::work> work( 144 * new boost::asio::io_service::work(io_service)); 145 * ... 146 * work.reset(); // Allow run() to exit. @endcode 147 * 148 * @par The io_service class and I/O services 149 * 150 * Class io_service implements an extensible, type-safe, polymorphic set of I/O 151 * services, indexed by service type. An object of class io_service must be 152 * initialised before I/O objects such as sockets, resolvers and timers can be 153 * used. These I/O objects are distinguished by having constructors that accept 154 * an @c io_service& parameter. 155 * 156 * I/O services exist to manage the logical interface to the operating system on 157 * behalf of the I/O objects. In particular, there are resources that are shared 158 * across a class of I/O objects. For example, timers may be implemented in 159 * terms of a single timer queue. The I/O services manage these shared 160 * resources. 161 * 162 * Access to the services of an io_service is via three function templates, 163 * use_service(), add_service() and has_service(). 164 * 165 * In a call to @c use_service<Service>(), the type argument chooses a service, 166 * making available all members of the named type. If @c Service is not present 167 * in an io_service, an object of type @c Service is created and added to the 168 * io_service. A C++ program can check if an io_service implements a 169 * particular service with the function template @c has_service<Service>(). 170 * 171 * Service objects may be explicitly added to an io_service using the function 172 * template @c add_service<Service>(). If the @c Service is already present, the 173 * service_already_exists exception is thrown. If the owner of the service is 174 * not the same object as the io_service parameter, the invalid_service_owner 175 * exception is thrown. 176 * 177 * Once a service reference is obtained from an io_service object by calling 178 * use_service(), that reference remains usable as long as the owning io_service 179 * object exists. 180 * 181 * All I/O service implementations have io_service::service as a public base 182 * class. Custom I/O services may be implemented by deriving from this class and 183 * then added to an io_service using the facilities described above. 184 */ 185 class io_service 186 : private noncopyable 187 { 188 private: 189 typedef detail::io_service_impl impl_type; 190 #if defined(BOOST_ASIO_HAS_IOCP) 191 friend class detail::win_iocp_overlapped_ptr; 192 #endif 193 194 public: 195 class work; 196 friend class work; 197 198 class id; 199 200 class service; 201 202 class strand; 203 204 /// Constructor. 205 BOOST_ASIO_DECL io_service(); 206 207 /// Constructor. 208 /** 209 * Construct with a hint about the required level of concurrency. 210 * 211 * @param concurrency_hint A suggestion to the implementation on how many 212 * threads it should allow to run simultaneously. 213 */ 214 BOOST_ASIO_DECL explicit io_service(std::size_t concurrency_hint); 215 216 /// Destructor. 217 /** 218 * On destruction, the io_service performs the following sequence of 219 * operations: 220 * 221 * @li For each service object @c svc in the io_service set, in reverse order 222 * of the beginning of service object lifetime, performs 223 * @c svc->shutdown_service(). 224 * 225 * @li Uninvoked handler objects that were scheduled for deferred invocation 226 * on the io_service, or any associated strand, are destroyed. 227 * 228 * @li For each service object @c svc in the io_service set, in reverse order 229 * of the beginning of service object lifetime, performs 230 * <tt>delete static_cast<io_service::service*>(svc)</tt>. 231 * 232 * @note The destruction sequence described above permits programs to 233 * simplify their resource management by using @c shared_ptr<>. Where an 234 * object's lifetime is tied to the lifetime of a connection (or some other 235 * sequence of asynchronous operations), a @c shared_ptr to the object would 236 * be bound into the handlers for all asynchronous operations associated with 237 * it. This works as follows: 238 * 239 * @li When a single connection ends, all associated asynchronous operations 240 * complete. The corresponding handler objects are destroyed, and all 241 * @c shared_ptr references to the objects are destroyed. 242 * 243 * @li To shut down the whole program, the io_service function stop() is 244 * called to terminate any run() calls as soon as possible. The io_service 245 * destructor defined above destroys all handlers, causing all @c shared_ptr 246 * references to all connection objects to be destroyed. 247 */ 248 BOOST_ASIO_DECL ~io_service(); 249 250 /// Run the io_service object's event processing loop. 251 /** 252 * The run() function blocks until all work has finished and there are no 253 * more handlers to be dispatched, or until the io_service has been stopped. 254 * 255 * Multiple threads may call the run() function to set up a pool of threads 256 * from which the io_service may execute handlers. All threads that are 257 * waiting in the pool are equivalent and the io_service may choose any one 258 * of them to invoke a handler. 259 * 260 * A normal exit from the run() function implies that the io_service object 261 * is stopped (the stopped() function returns @c true). Subsequent calls to 262 * run(), run_one(), poll() or poll_one() will return immediately unless there 263 * is a prior call to reset(). 264 * 265 * @return The number of handlers that were executed. 266 * 267 * @throws boost::system::system_error Thrown on failure. 268 * 269 * @note The run() function must not be called from a thread that is currently 270 * calling one of run(), run_one(), poll() or poll_one() on the same 271 * io_service object. 272 * 273 * The poll() function may also be used to dispatch ready handlers, but 274 * without blocking. 275 */ 276 BOOST_ASIO_DECL std::size_t run(); 277 278 /// Run the io_service object's event processing loop. 279 /** 280 * The run() function blocks until all work has finished and there are no 281 * more handlers to be dispatched, or until the io_service has been stopped. 282 * 283 * Multiple threads may call the run() function to set up a pool of threads 284 * from which the io_service may execute handlers. All threads that are 285 * waiting in the pool are equivalent and the io_service may choose any one 286 * of them to invoke a handler. 287 * 288 * A normal exit from the run() function implies that the io_service object 289 * is stopped (the stopped() function returns @c true). Subsequent calls to 290 * run(), run_one(), poll() or poll_one() will return immediately unless there 291 * is a prior call to reset(). 292 * 293 * @param ec Set to indicate what error occurred, if any. 294 * 295 * @return The number of handlers that were executed. 296 * 297 * @note The run() function must not be called from a thread that is currently 298 * calling one of run(), run_one(), poll() or poll_one() on the same 299 * io_service object. 300 * 301 * The poll() function may also be used to dispatch ready handlers, but 302 * without blocking. 303 */ 304 BOOST_ASIO_DECL std::size_t run(boost::system::error_code& ec); 305 306 /// Run the io_service object's event processing loop to execute at most one 307 /// handler. 308 /** 309 * The run_one() function blocks until one handler has been dispatched, or 310 * until the io_service has been stopped. 311 * 312 * @return The number of handlers that were executed. A zero return value 313 * implies that the io_service object is stopped (the stopped() function 314 * returns @c true). Subsequent calls to run(), run_one(), poll() or 315 * poll_one() will return immediately unless there is a prior call to 316 * reset(). 317 * 318 * @throws boost::system::system_error Thrown on failure. 319 */ 320 BOOST_ASIO_DECL std::size_t run_one(); 321 322 /// Run the io_service object's event processing loop to execute at most one 323 /// handler. 324 /** 325 * The run_one() function blocks until one handler has been dispatched, or 326 * until the io_service has been stopped. 327 * 328 * @return The number of handlers that were executed. A zero return value 329 * implies that the io_service object is stopped (the stopped() function 330 * returns @c true). Subsequent calls to run(), run_one(), poll() or 331 * poll_one() will return immediately unless there is a prior call to 332 * reset(). 333 * 334 * @return The number of handlers that were executed. 335 */ 336 BOOST_ASIO_DECL std::size_t run_one(boost::system::error_code& ec); 337 338 /// Run the io_service object's event processing loop to execute ready 339 /// handlers. 340 /** 341 * The poll() function runs handlers that are ready to run, without blocking, 342 * until the io_service has been stopped or there are no more ready handlers. 343 * 344 * @return The number of handlers that were executed. 345 * 346 * @throws boost::system::system_error Thrown on failure. 347 */ 348 BOOST_ASIO_DECL std::size_t poll(); 349 350 /// Run the io_service object's event processing loop to execute ready 351 /// handlers. 352 /** 353 * The poll() function runs handlers that are ready to run, without blocking, 354 * until the io_service has been stopped or there are no more ready handlers. 355 * 356 * @param ec Set to indicate what error occurred, if any. 357 * 358 * @return The number of handlers that were executed. 359 */ 360 BOOST_ASIO_DECL std::size_t poll(boost::system::error_code& ec); 361 362 /// Run the io_service object's event processing loop to execute one ready 363 /// handler. 364 /** 365 * The poll_one() function runs at most one handler that is ready to run, 366 * without blocking. 367 * 368 * @return The number of handlers that were executed. 369 * 370 * @throws boost::system::system_error Thrown on failure. 371 */ 372 BOOST_ASIO_DECL std::size_t poll_one(); 373 374 /// Run the io_service object's event processing loop to execute one ready 375 /// handler. 376 /** 377 * The poll_one() function runs at most one handler that is ready to run, 378 * without blocking. 379 * 380 * @param ec Set to indicate what error occurred, if any. 381 * 382 * @return The number of handlers that were executed. 383 */ 384 BOOST_ASIO_DECL std::size_t poll_one(boost::system::error_code& ec); 385 386 /// Stop the io_service object's event processing loop. 387 /** 388 * This function does not block, but instead simply signals the io_service to 389 * stop. All invocations of its run() or run_one() member functions should 390 * return as soon as possible. Subsequent calls to run(), run_one(), poll() 391 * or poll_one() will return immediately until reset() is called. 392 */ 393 BOOST_ASIO_DECL void stop(); 394 395 /// Determine whether the io_service object has been stopped. 396 /** 397 * This function is used to determine whether an io_service object has been 398 * stopped, either through an explicit call to stop(), or due to running out 399 * of work. When an io_service object is stopped, calls to run(), run_one(), 400 * poll() or poll_one() will return immediately without invoking any 401 * handlers. 402 * 403 * @return @c true if the io_service object is stopped, otherwise @c false. 404 */ 405 BOOST_ASIO_DECL bool stopped() const; 406 407 /// Reset the io_service in preparation for a subsequent run() invocation. 408 /** 409 * This function must be called prior to any second or later set of 410 * invocations of the run(), run_one(), poll() or poll_one() functions when a 411 * previous invocation of these functions returned due to the io_service 412 * being stopped or running out of work. After a call to reset(), the 413 * io_service object's stopped() function will return @c false. 414 * 415 * This function must not be called while there are any unfinished calls to 416 * the run(), run_one(), poll() or poll_one() functions. 417 */ 418 BOOST_ASIO_DECL void reset(); 419 420 /// Request the io_service to invoke the given handler. 421 /** 422 * This function is used to ask the io_service to execute the given handler. 423 * 424 * The io_service guarantees that the handler will only be called in a thread 425 * in which the run(), run_one(), poll() or poll_one() member functions is 426 * currently being invoked. The handler may be executed inside this function 427 * if the guarantee can be met. 428 * 429 * @param handler The handler to be called. The io_service will make 430 * a copy of the handler object as required. The function signature of the 431 * handler must be: @code void handler(); @endcode 432 * 433 * @note This function throws an exception only if: 434 * 435 * @li the handler's @c asio_handler_allocate function; or 436 * 437 * @li the handler's copy constructor 438 * 439 * throws an exception. 440 */ 441 template <typename CompletionHandler> 442 BOOST_ASIO_INITFN_RESULT_TYPE(CompletionHandler, void ()) 443 dispatch(BOOST_ASIO_MOVE_ARG(CompletionHandler) handler); 444 445 /// Request the io_service to invoke the given handler and return immediately. 446 /** 447 * This function is used to ask the io_service to execute the given handler, 448 * but without allowing the io_service to call the handler from inside this 449 * function. 450 * 451 * The io_service guarantees that the handler will only be called in a thread 452 * in which the run(), run_one(), poll() or poll_one() member functions is 453 * currently being invoked. 454 * 455 * @param handler The handler to be called. The io_service will make 456 * a copy of the handler object as required. The function signature of the 457 * handler must be: @code void handler(); @endcode 458 * 459 * @note This function throws an exception only if: 460 * 461 * @li the handler's @c asio_handler_allocate function; or 462 * 463 * @li the handler's copy constructor 464 * 465 * throws an exception. 466 */ 467 template <typename CompletionHandler> 468 BOOST_ASIO_INITFN_RESULT_TYPE(CompletionHandler, void ()) 469 post(BOOST_ASIO_MOVE_ARG(CompletionHandler) handler); 470 471 /// Create a new handler that automatically dispatches the wrapped handler 472 /// on the io_service. 473 /** 474 * This function is used to create a new handler function object that, when 475 * invoked, will automatically pass the wrapped handler to the io_service 476 * object's dispatch function. 477 * 478 * @param handler The handler to be wrapped. The io_service will make a copy 479 * of the handler object as required. The function signature of the handler 480 * must be: @code void handler(A1 a1, ... An an); @endcode 481 * 482 * @return A function object that, when invoked, passes the wrapped handler to 483 * the io_service object's dispatch function. Given a function object with the 484 * signature: 485 * @code R f(A1 a1, ... An an); @endcode 486 * If this function object is passed to the wrap function like so: 487 * @code io_service.wrap(f); @endcode 488 * then the return value is a function object with the signature 489 * @code void g(A1 a1, ... An an); @endcode 490 * that, when invoked, executes code equivalent to: 491 * @code io_service.dispatch(boost::bind(f, a1, ... an)); @endcode 492 */ 493 template <typename Handler> 494 #if defined(GENERATING_DOCUMENTATION) 495 unspecified 496 #else 497 detail::wrapped_handler<io_service&, Handler> 498 #endif 499 wrap(Handler handler); 500 501 /// Fork-related event notifications. 502 enum fork_event 503 { 504 /// Notify the io_service that the process is about to fork. 505 fork_prepare, 506 507 /// Notify the io_service that the process has forked and is the parent. 508 fork_parent, 509 510 /// Notify the io_service that the process has forked and is the child. 511 fork_child 512 }; 513 514 /// Notify the io_service of a fork-related event. 515 /** 516 * This function is used to inform the io_service that the process is about 517 * to fork, or has just forked. This allows the io_service, and the services 518 * it contains, to perform any necessary housekeeping to ensure correct 519 * operation following a fork. 520 * 521 * This function must not be called while any other io_service function, or 522 * any function on an I/O object associated with the io_service, is being 523 * called in another thread. It is, however, safe to call this function from 524 * within a completion handler, provided no other thread is accessing the 525 * io_service. 526 * 527 * @param event A fork-related event. 528 * 529 * @throws boost::system::system_error Thrown on failure. If the notification 530 * fails the io_service object should no longer be used and should be 531 * destroyed. 532 * 533 * @par Example 534 * The following code illustrates how to incorporate the notify_fork() 535 * function: 536 * @code my_io_service.notify_fork(boost::asio::io_service::fork_prepare); 537 * if (fork() == 0) 538 * { 539 * // This is the child process. 540 * my_io_service.notify_fork(boost::asio::io_service::fork_child); 541 * } 542 * else 543 * { 544 * // This is the parent process. 545 * my_io_service.notify_fork(boost::asio::io_service::fork_parent); 546 * } @endcode 547 * 548 * @note For each service object @c svc in the io_service set, performs 549 * <tt>svc->fork_service();</tt>. When processing the fork_prepare event, 550 * services are visited in reverse order of the beginning of service object 551 * lifetime. Otherwise, services are visited in order of the beginning of 552 * service object lifetime. 553 */ 554 BOOST_ASIO_DECL void notify_fork(boost::asio::io_service::fork_event event); 555 556 /// Obtain the service object corresponding to the given type. 557 /** 558 * This function is used to locate a service object that corresponds to 559 * the given service type. If there is no existing implementation of the 560 * service, then the io_service will create a new instance of the service. 561 * 562 * @param ios The io_service object that owns the service. 563 * 564 * @return The service interface implementing the specified service type. 565 * Ownership of the service interface is not transferred to the caller. 566 */ 567 template <typename Service> 568 friend Service& use_service(io_service& ios); 569 570 /// Add a service object to the io_service. 571 /** 572 * This function is used to add a service to the io_service. 573 * 574 * @param ios The io_service object that owns the service. 575 * 576 * @param svc The service object. On success, ownership of the service object 577 * is transferred to the io_service. When the io_service object is destroyed, 578 * it will destroy the service object by performing: 579 * @code delete static_cast<io_service::service*>(svc) @endcode 580 * 581 * @throws boost::asio::service_already_exists Thrown if a service of the 582 * given type is already present in the io_service. 583 * 584 * @throws boost::asio::invalid_service_owner Thrown if the service's owning 585 * io_service is not the io_service object specified by the ios parameter. 586 */ 587 template <typename Service> 588 friend void add_service(io_service& ios, Service* svc); 589 590 /// Determine if an io_service contains a specified service type. 591 /** 592 * This function is used to determine whether the io_service contains a 593 * service object corresponding to the given service type. 594 * 595 * @param ios The io_service object that owns the service. 596 * 597 * @return A boolean indicating whether the io_service contains the service. 598 */ 599 template <typename Service> 600 friend bool has_service(io_service& ios); 601 602 private: 603 #if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) 604 detail::winsock_init<> init_; 605 #elif defined(__sun) || defined(__QNX__) || defined(__hpux) || defined(_AIX) \ 606 || defined(__osf__) 607 detail::signal_init<> init_; 608 #endif 609 610 // The service registry. 611 boost::asio::detail::service_registry* service_registry_; 612 613 // The implementation. 614 impl_type& impl_; 615 }; 616 617 /// Class to inform the io_service when it has work to do. 618 /** 619 * The work class is used to inform the io_service when work starts and 620 * finishes. This ensures that the io_service object's run() function will not 621 * exit while work is underway, and that it does exit when there is no 622 * unfinished work remaining. 623 * 624 * The work class is copy-constructible so that it may be used as a data member 625 * in a handler class. It is not assignable. 626 */ 627 class io_service::work 628 { 629 public: 630 /// Constructor notifies the io_service that work is starting. 631 /** 632 * The constructor is used to inform the io_service that some work has begun. 633 * This ensures that the io_service object's run() function will not exit 634 * while the work is underway. 635 */ 636 explicit work(boost::asio::io_service& io_service); 637 638 /// Copy constructor notifies the io_service that work is starting. 639 /** 640 * The constructor is used to inform the io_service that some work has begun. 641 * This ensures that the io_service object's run() function will not exit 642 * while the work is underway. 643 */ 644 work(const work& other); 645 646 /// Destructor notifies the io_service that the work is complete. 647 /** 648 * The destructor is used to inform the io_service that some work has 649 * finished. Once the count of unfinished work reaches zero, the io_service 650 * object's run() function is permitted to exit. 651 */ 652 ~work(); 653 654 /// Get the io_service associated with the work. 655 boost::asio::io_service& get_io_service(); 656 657 private: 658 // Prevent assignment. 659 void operator=(const work& other); 660 661 // The io_service implementation. 662 detail::io_service_impl& io_service_impl_; 663 }; 664 665 /// Class used to uniquely identify a service. 666 class io_service::id 667 : private noncopyable 668 { 669 public: 670 /// Constructor. id()671 id() {} 672 }; 673 674 /// Base class for all io_service services. 675 class io_service::service 676 : private noncopyable 677 { 678 public: 679 /// Get the io_service object that owns the service. 680 boost::asio::io_service& get_io_service(); 681 682 protected: 683 /// Constructor. 684 /** 685 * @param owner The io_service object that owns the service. 686 */ 687 BOOST_ASIO_DECL service(boost::asio::io_service& owner); 688 689 /// Destructor. 690 BOOST_ASIO_DECL virtual ~service(); 691 692 private: 693 /// Destroy all user-defined handler objects owned by the service. 694 virtual void shutdown_service() = 0; 695 696 /// Handle notification of a fork-related event to perform any necessary 697 /// housekeeping. 698 /** 699 * This function is not a pure virtual so that services only have to 700 * implement it if necessary. The default implementation does nothing. 701 */ 702 BOOST_ASIO_DECL virtual void fork_service( 703 boost::asio::io_service::fork_event event); 704 705 friend class boost::asio::detail::service_registry; 706 struct key 707 { keyboost::asio::io_service::service::key708 key() : type_info_(0), id_(0) {} 709 const std::type_info* type_info_; 710 const boost::asio::io_service::id* id_; 711 } key_; 712 713 boost::asio::io_service& owner_; 714 service* next_; 715 }; 716 717 /// Exception thrown when trying to add a duplicate service to an io_service. 718 class service_already_exists 719 : public std::logic_error 720 { 721 public: 722 BOOST_ASIO_DECL service_already_exists(); 723 }; 724 725 /// Exception thrown when trying to add a service object to an io_service where 726 /// the service has a different owner. 727 class invalid_service_owner 728 : public std::logic_error 729 { 730 public: 731 BOOST_ASIO_DECL invalid_service_owner(); 732 }; 733 734 namespace detail { 735 736 // Special derived service id type to keep classes header-file only. 737 template <typename Type> 738 class service_id 739 : public boost::asio::io_service::id 740 { 741 }; 742 743 // Special service base class to keep classes header-file only. 744 template <typename Type> 745 class service_base 746 : public boost::asio::io_service::service 747 { 748 public: 749 static boost::asio::detail::service_id<Type> id; 750 751 // Constructor. service_base(boost::asio::io_service & io_service)752 service_base(boost::asio::io_service& io_service) 753 : boost::asio::io_service::service(io_service) 754 { 755 } 756 }; 757 758 template <typename Type> 759 boost::asio::detail::service_id<Type> service_base<Type>::id; 760 761 } // namespace detail 762 } // namespace asio 763 } // namespace boost 764 765 #include <boost/asio/detail/pop_options.hpp> 766 767 #include <boost/asio/impl/io_service.hpp> 768 #if defined(BOOST_ASIO_HEADER_ONLY) 769 # include <boost/asio/impl/io_service.ipp> 770 #endif // defined(BOOST_ASIO_HEADER_ONLY) 771 772 #endif // BOOST_ASIO_IO_SERVICE_HPP 773