1 // 2 // io_service.hpp 3 // ~~~~~~~~~~~~~~ 4 // 5 // Copyright (c) 2003-2011 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/detail/noncopyable.hpp> 23 #include <boost/asio/detail/service_registry_fwd.hpp> 24 #include <boost/asio/detail/wrapped_handler.hpp> 25 #include <boost/system/error_code.hpp> 26 27 #if defined(BOOST_ASIO_HAS_IOCP) 28 # include <boost/asio/detail/win_iocp_io_service_fwd.hpp> 29 #else 30 # include <boost/asio/detail/task_io_service_fwd.hpp> 31 #endif 32 33 #if defined(BOOST_WINDOWS) || defined(__CYGWIN__) 34 # include <boost/asio/detail/winsock_init.hpp> 35 #elif defined(__sun) || defined(__QNX__) || defined(__hpux) || defined(_AIX) \ 36 || defined(__osf__) 37 # include <boost/asio/detail/signal_init.hpp> 38 #endif 39 40 #include <boost/asio/detail/push_options.hpp> 41 42 namespace boost { 43 namespace asio { 44 45 class io_service; 46 template <typename Service> Service& use_service(io_service& ios); 47 template <typename Service> void add_service(io_service& ios, Service* svc); 48 template <typename Service> bool has_service(io_service& ios); 49 50 #if defined(BOOST_ASIO_HAS_IOCP) 51 namespace detail { typedef win_iocp_io_service io_service_impl; } 52 #else 53 namespace detail { typedef task_io_service io_service_impl; } 54 #endif 55 56 /// Provides core I/O functionality. 57 /** 58 * The io_service class provides the core I/O functionality for users of the 59 * asynchronous I/O objects, including: 60 * 61 * @li boost::asio::ip::tcp::socket 62 * @li boost::asio::ip::tcp::acceptor 63 * @li boost::asio::ip::udp::socket 64 * @li boost::asio::deadline_timer. 65 * 66 * The io_service class also includes facilities intended for developers of 67 * custom asynchronous services. 68 * 69 * @par Thread Safety 70 * @e Distinct @e objects: Safe.@n 71 * @e Shared @e objects: Safe, with the specific exceptions of the reset() and 72 * notify_fork() functions. Calling reset() while there are unfinished run(), 73 * run_one(), poll() or poll_one() calls results in undefined behaviour. The 74 * notify_fork() function should not be called while any io_service function, 75 * or any function on an I/O object that is associated with the io_service, is 76 * being called in another thread. 77 * 78 * @par Concepts: 79 * Dispatcher. 80 * 81 * @par Synchronous and asynchronous operations 82 * 83 * Synchronous operations on I/O objects implicitly run the io_service object 84 * for an individual operation. The io_service functions run(), run_one(), 85 * poll() or poll_one() must be called for the io_service to perform 86 * asynchronous operations on behalf of a C++ program. Notification that an 87 * asynchronous operation has completed is delivered by invocation of the 88 * associated handler. Handlers are invoked only by a thread that is currently 89 * calling any overload of run(), run_one(), poll() or poll_one() for the 90 * io_service. 91 * 92 * @par Effect of exceptions thrown from handlers 93 * 94 * If an exception is thrown from a handler, the exception is allowed to 95 * propagate through the throwing thread's invocation of run(), run_one(), 96 * poll() or poll_one(). No other threads that are calling any of these 97 * functions are affected. It is then the responsibility of the application to 98 * catch the exception. 99 * 100 * After the exception has been caught, the run(), run_one(), poll() or 101 * poll_one() call may be restarted @em without the need for an intervening 102 * call to reset(). This allows the thread to rejoin the io_service object's 103 * thread pool without impacting any other threads in the pool. 104 * 105 * For example: 106 * 107 * @code 108 * boost::asio::io_service io_service; 109 * ... 110 * for (;;) 111 * { 112 * try 113 * { 114 * io_service.run(); 115 * break; // run() exited normally 116 * } 117 * catch (my_exception& e) 118 * { 119 * // Deal with exception as appropriate. 120 * } 121 * } 122 * @endcode 123 * 124 * @par Stopping the io_service from running out of work 125 * 126 * Some applications may need to prevent an io_service object's run() call from 127 * returning when there is no more work to do. For example, the io_service may 128 * be being run in a background thread that is launched prior to the 129 * application's asynchronous operations. The run() call may be kept running by 130 * creating an object of type boost::asio::io_service::work: 131 * 132 * @code boost::asio::io_service io_service; 133 * boost::asio::io_service::work work(io_service); 134 * ... @endcode 135 * 136 * To effect a shutdown, the application will then need to call the io_service 137 * object's stop() member function. This will cause the io_service run() call 138 * to return as soon as possible, abandoning unfinished operations and without 139 * permitting ready handlers to be dispatched. 140 * 141 * Alternatively, if the application requires that all operations and handlers 142 * be allowed to finish normally, the work object may be explicitly destroyed. 143 * 144 * @code boost::asio::io_service io_service; 145 * auto_ptr<boost::asio::io_service::work> work( 146 * new boost::asio::io_service::work(io_service)); 147 * ... 148 * work.reset(); // Allow run() to exit. @endcode 149 * 150 * @par The io_service class and I/O services 151 * 152 * Class io_service implements an extensible, type-safe, polymorphic set of I/O 153 * services, indexed by service type. An object of class io_service must be 154 * initialised before I/O objects such as sockets, resolvers and timers can be 155 * used. These I/O objects are distinguished by having constructors that accept 156 * an @c io_service& parameter. 157 * 158 * I/O services exist to manage the logical interface to the operating system on 159 * behalf of the I/O objects. In particular, there are resources that are shared 160 * across a class of I/O objects. For example, timers may be implemented in 161 * terms of a single timer queue. The I/O services manage these shared 162 * resources. 163 * 164 * Access to the services of an io_service is via three function templates, 165 * use_service(), add_service() and has_service(). 166 * 167 * In a call to @c use_service<Service>(), the type argument chooses a service, 168 * making available all members of the named type. If @c Service is not present 169 * in an io_service, an object of type @c Service is created and added to the 170 * io_service. A C++ program can check if an io_service implements a 171 * particular service with the function template @c has_service<Service>(). 172 * 173 * Service objects may be explicitly added to an io_service using the function 174 * template @c add_service<Service>(). If the @c Service is already present, the 175 * service_already_exists exception is thrown. If the owner of the service is 176 * not the same object as the io_service parameter, the invalid_service_owner 177 * exception is thrown. 178 * 179 * Once a service reference is obtained from an io_service object by calling 180 * use_service(), that reference remains usable as long as the owning io_service 181 * object exists. 182 * 183 * All I/O service implementations have io_service::service as a public base 184 * class. Custom I/O services may be implemented by deriving from this class and 185 * then added to an io_service using the facilities described above. 186 */ 187 class io_service 188 : private noncopyable 189 { 190 private: 191 typedef detail::io_service_impl impl_type; 192 #if defined(BOOST_ASIO_HAS_IOCP) 193 friend class detail::win_iocp_overlapped_ptr; 194 #endif 195 196 public: 197 class work; 198 friend class work; 199 200 class id; 201 202 class service; 203 204 class strand; 205 206 /// Constructor. 207 BOOST_ASIO_DECL io_service(); 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_service(std::size_t concurrency_hint); 217 218 /// Destructor. 219 /** 220 * On destruction, the io_service performs the following sequence of 221 * operations: 222 * 223 * @li For each service object @c svc in the io_service set, in reverse order 224 * of the beginning of service object lifetime, performs 225 * @c svc->shutdown_service(). 226 * 227 * @li Uninvoked handler objects that were scheduled for deferred invocation 228 * on the io_service, or any associated strand, are destroyed. 229 * 230 * @li For each service object @c svc in the io_service set, in reverse order 231 * of the beginning of service object lifetime, performs 232 * <tt>delete static_cast<io_service::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_service function stop() is 246 * called to terminate any run() calls as soon as possible. The io_service 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_service(); 251 252 /// Run the io_service object's event processing loop. 253 /** 254 * The run() function blocks until all work has finished and there are no 255 * more handlers to be dispatched, or until the io_service has been stopped. 256 * 257 * Multiple threads may call the run() function to set up a pool of threads 258 * from which the io_service may execute handlers. All threads that are 259 * waiting in the pool are equivalent and the io_service may choose any one 260 * of them to invoke a handler. 261 * 262 * A normal exit from the run() function implies that the io_service object 263 * is stopped (the stopped() function returns @c true). Subsequent calls to 264 * run(), run_one(), poll() or poll_one() will return immediately unless there 265 * is a prior call to reset(). 266 * 267 * @return The number of handlers that were executed. 268 * 269 * @throws boost::system::system_error Thrown on failure. 270 * 271 * @note The run() function must not be called from a thread that is currently 272 * calling one of run(), run_one(), poll() or poll_one() on the same 273 * io_service object. 274 * 275 * The poll() function may also be used to dispatch ready handlers, but 276 * without blocking. 277 */ 278 BOOST_ASIO_DECL std::size_t run(); 279 280 /// Run the io_service object's event processing loop. 281 /** 282 * The run() function blocks until all work has finished and there are no 283 * more handlers to be dispatched, or until the io_service has been stopped. 284 * 285 * Multiple threads may call the run() function to set up a pool of threads 286 * from which the io_service may execute handlers. All threads that are 287 * waiting in the pool are equivalent and the io_service may choose any one 288 * of them to invoke a handler. 289 * 290 * A normal exit from the run() function implies that the io_service object 291 * is stopped (the stopped() function returns @c true). Subsequent calls to 292 * run(), run_one(), poll() or poll_one() will return immediately unless there 293 * is a prior call to reset(). 294 * 295 * @param ec Set to indicate what error occurred, if any. 296 * 297 * @return The number of handlers that were executed. 298 * 299 * @note The run() function must not be called from a thread that is currently 300 * calling one of run(), run_one(), poll() or poll_one() on the same 301 * io_service object. 302 * 303 * The poll() function may also be used to dispatch ready handlers, but 304 * without blocking. 305 */ 306 BOOST_ASIO_DECL std::size_t run(boost::system::error_code& ec); 307 308 /// Run the io_service object's event processing loop to execute at most one 309 /// handler. 310 /** 311 * The run_one() function blocks until one handler has been dispatched, or 312 * until the io_service has been stopped. 313 * 314 * @return The number of handlers that were executed. A zero return value 315 * implies that the io_service object is stopped (the stopped() function 316 * returns @c true). Subsequent calls to run(), run_one(), poll() or 317 * poll_one() will return immediately unless there is a prior call to 318 * reset(). 319 * 320 * @throws boost::system::system_error Thrown on failure. 321 */ 322 BOOST_ASIO_DECL std::size_t run_one(); 323 324 /// Run the io_service object's event processing loop to execute at most one 325 /// handler. 326 /** 327 * The run_one() function blocks until one handler has been dispatched, or 328 * until the io_service has been stopped. 329 * 330 * @return The number of handlers that were executed. A zero return value 331 * implies that the io_service object is stopped (the stopped() function 332 * returns @c true). Subsequent calls to run(), run_one(), poll() or 333 * poll_one() will return immediately unless there is a prior call to 334 * reset(). 335 * 336 * @return The number of handlers that were executed. 337 */ 338 BOOST_ASIO_DECL std::size_t run_one(boost::system::error_code& ec); 339 340 /// Run the io_service object's event processing loop to execute ready 341 /// handlers. 342 /** 343 * The poll() function runs handlers that are ready to run, without blocking, 344 * until the io_service has been stopped or there are no more ready handlers. 345 * 346 * @return The number of handlers that were executed. 347 * 348 * @throws boost::system::system_error Thrown on failure. 349 */ 350 BOOST_ASIO_DECL std::size_t poll(); 351 352 /// Run the io_service object's event processing loop to execute ready 353 /// handlers. 354 /** 355 * The poll() function runs handlers that are ready to run, without blocking, 356 * until the io_service has been stopped or there are no more ready handlers. 357 * 358 * @param ec Set to indicate what error occurred, if any. 359 * 360 * @return The number of handlers that were executed. 361 */ 362 BOOST_ASIO_DECL std::size_t poll(boost::system::error_code& ec); 363 364 /// Run the io_service object's event processing loop to execute one ready 365 /// handler. 366 /** 367 * The poll_one() function runs at most one handler that is ready to run, 368 * without blocking. 369 * 370 * @return The number of handlers that were executed. 371 * 372 * @throws boost::system::system_error Thrown on failure. 373 */ 374 BOOST_ASIO_DECL std::size_t poll_one(); 375 376 /// Run the io_service object's event processing loop to execute one ready 377 /// handler. 378 /** 379 * The poll_one() function runs at most one handler that is ready to run, 380 * without blocking. 381 * 382 * @param ec Set to indicate what error occurred, if any. 383 * 384 * @return The number of handlers that were executed. 385 */ 386 BOOST_ASIO_DECL std::size_t poll_one(boost::system::error_code& ec); 387 388 /// Stop the io_service object's event processing loop. 389 /** 390 * This function does not block, but instead simply signals the io_service to 391 * stop. All invocations of its run() or run_one() member functions should 392 * return as soon as possible. Subsequent calls to run(), run_one(), poll() 393 * or poll_one() will return immediately until reset() is called. 394 */ 395 BOOST_ASIO_DECL void stop(); 396 397 /// Determine whether the io_service object has been stopped. 398 /** 399 * This function is used to determine whether an io_service object has been 400 * stopped, either through an explicit call to stop(), or due to running out 401 * of work. When an io_service object is stopped, calls to run(), run_one(), 402 * poll() or poll_one() will return immediately without invoking any 403 * handlers. 404 * 405 * @return @c true if the io_service object is stopped, otherwise @c false. 406 */ 407 BOOST_ASIO_DECL bool stopped() const; 408 409 /// Reset the io_service in preparation for a subsequent run() invocation. 410 /** 411 * This function must be called prior to any second or later set of 412 * invocations of the run(), run_one(), poll() or poll_one() functions when a 413 * previous invocation of these functions returned due to the io_service 414 * being stopped or running out of work. After a call to reset(), the 415 * io_service object's stopped() function will return @c false. 416 * 417 * This function must not be called while there are any unfinished calls to 418 * the run(), run_one(), poll() or poll_one() functions. 419 */ 420 BOOST_ASIO_DECL void reset(); 421 422 /// Request the io_service to invoke the given handler. 423 /** 424 * This function is used to ask the io_service to execute the given handler. 425 * 426 * The io_service guarantees that the handler will only be called in a thread 427 * in which the run(), run_one(), poll() or poll_one() member functions is 428 * currently being invoked. The handler may be executed inside this function 429 * if the guarantee can be met. 430 * 431 * @param handler The handler to be called. The io_service will make 432 * a copy of the handler object as required. The function signature of the 433 * handler must be: @code void handler(); @endcode 434 * 435 * @note This function throws an exception only if: 436 * 437 * @li the handler's @c asio_handler_allocate function; or 438 * 439 * @li the handler's copy constructor 440 * 441 * throws an exception. 442 */ 443 template <typename CompletionHandler> 444 void dispatch(BOOST_ASIO_MOVE_ARG(CompletionHandler) handler); 445 446 /// Request the io_service to invoke the given handler and return immediately. 447 /** 448 * This function is used to ask the io_service to execute the given handler, 449 * but without allowing the io_service to call the handler from inside this 450 * function. 451 * 452 * The io_service guarantees that the handler will only be called in a thread 453 * in which the run(), run_one(), poll() or poll_one() member functions is 454 * currently being invoked. 455 * 456 * @param handler The handler to be called. The io_service will make 457 * a copy of the handler object as required. The function signature of the 458 * handler must be: @code void handler(); @endcode 459 * 460 * @note This function throws an exception only if: 461 * 462 * @li the handler's @c asio_handler_allocate function; or 463 * 464 * @li the handler's copy constructor 465 * 466 * throws an exception. 467 */ 468 template <typename CompletionHandler> 469 void 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_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. 662 boost::asio::io_service& io_service_; 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