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