10ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie//
20ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie// io_service.hpp
30ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie// ~~~~~~~~~~~~~~
40ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie//
50ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com)
60ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie//
70ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie// Distributed under the Boost Software License, Version 1.0. (See accompanying
80ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
90ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie//
100ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie
110ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie#ifndef ASIO_IO_SERVICE_HPP
120ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie#define ASIO_IO_SERVICE_HPP
130ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie
140ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie
150ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie#include "asio/detail/config.hpp"
160ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie#include <cstddef>
170ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie#include <stdexcept>
180ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie#include <typeinfo>
190ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie#include "asio/async_result.hpp"
200ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie#include "asio/detail/noncopyable.hpp"
210ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie#include "asio/detail/wrapped_handler.hpp"
220ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie#include "asio/error_code.hpp"
230ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie
240ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie#if   defined(__sun) || defined(__QNX__) || defined(__hpux) || defined(_AIX)    || defined(__osf__)
250ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie# include "asio/detail/signal_init.hpp"
260ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie#endif
270ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie
280ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie#include "asio/detail/push_options.hpp"
290ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie
300ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffienamespace asio {
310ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie
320ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffieclass io_service;
330ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffietemplate <typename Service> Service& use_service(io_service& ios);
340ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffietemplate <typename Service> void add_service(io_service& ios, Service* svc);
350ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffietemplate <typename Service> bool has_service(io_service& ios);
360ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie
370ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffienamespace detail {
380ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  typedef class task_io_service io_service_impl;
390ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  class service_registry;
400ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie} // namespace detail
410ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie
420ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie/// Provides core I/O functionality.
430ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie/**
440ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * The io_service class provides the core I/O functionality for users of the
450ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * asynchronous I/O objects, including:
460ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie *
470ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @li asio::ip::tcp::socket
480ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @li asio::ip::tcp::acceptor
490ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @li asio::ip::udp::socket
500ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @li asio::deadline_timer.
510ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie *
520ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * The io_service class also includes facilities intended for developers of
530ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * custom asynchronous services.
540ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie *
550ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @par Thread Safety
560ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @e Distinct @e objects: Safe.@n
570ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @e Shared @e objects: Safe, with the specific exceptions of the reset() and
580ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * notify_fork() functions. Calling reset() while there are unfinished run(),
590ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * run_one(), poll() or poll_one() calls results in undefined behaviour. The
600ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * notify_fork() function should not be called while any io_service function,
610ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * or any function on an I/O object that is associated with the io_service, is
620ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * being called in another thread.
630ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie *
640ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @par Concepts:
650ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * Dispatcher.
660ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie *
670ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @par Synchronous and asynchronous operations
680ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie *
690ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * Synchronous operations on I/O objects implicitly run the io_service object
700ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * for an individual operation. The io_service functions run(), run_one(),
710ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * poll() or poll_one() must be called for the io_service to perform
720ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * asynchronous operations on behalf of a C++ program. Notification that an
730ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * asynchronous operation has completed is delivered by invocation of the
740ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * associated handler. Handlers are invoked only by a thread that is currently
750ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * calling any overload of run(), run_one(), poll() or poll_one() for the
760ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * io_service.
770ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie *
780ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @par Effect of exceptions thrown from handlers
790ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie *
800ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * If an exception is thrown from a handler, the exception is allowed to
810ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * propagate through the throwing thread's invocation of run(), run_one(),
820ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * poll() or poll_one(). No other threads that are calling any of these
830ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * functions are affected. It is then the responsibility of the application to
840ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * catch the exception.
850ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie *
860ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * After the exception has been caught, the run(), run_one(), poll() or
870ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * poll_one() call may be restarted @em without the need for an intervening
880ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * call to reset(). This allows the thread to rejoin the io_service object's
890ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * thread pool without impacting any other threads in the pool.
900ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie *
910ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * For example:
920ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie *
930ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @code
940ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * asio::io_service io_service;
950ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * ...
960ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * for (;;)
970ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * {
980ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie *   try
990ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie *   {
1000ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie *     io_service.run();
1010ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie *     break; // run() exited normally
1020ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie *   }
1030ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie *   catch (my_exception& e)
1040ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie *   {
1050ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie *     // Deal with exception as appropriate.
1060ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie *   }
1070ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * }
1080ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @endcode
1090ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie *
1100ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @par Stopping the io_service from running out of work
1110ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie *
1120ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * Some applications may need to prevent an io_service object's run() call from
1130ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * returning when there is no more work to do. For example, the io_service may
1140ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * be being run in a background thread that is launched prior to the
1150ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * application's asynchronous operations. The run() call may be kept running by
1160ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * creating an object of type asio::io_service::work:
1170ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie *
1180ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @code asio::io_service io_service;
1190ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * asio::io_service::work work(io_service);
1200ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * ... @endcode
1210ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie *
1220ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * To effect a shutdown, the application will then need to call the io_service
1230ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * object's stop() member function. This will cause the io_service run() call
1240ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * to return as soon as possible, abandoning unfinished operations and without
1250ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * permitting ready handlers to be dispatched.
1260ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie *
1270ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * Alternatively, if the application requires that all operations and handlers
1280ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * be allowed to finish normally, the work object may be explicitly destroyed.
1290ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie *
1300ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @code asio::io_service io_service;
1310ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * auto_ptr<asio::io_service::work> work(
1320ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie *     new asio::io_service::work(io_service));
1330ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * ...
1340ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * work.reset(); // Allow run() to exit. @endcode
1350ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie *
1360ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @par The io_service class and I/O services
1370ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie *
1380ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * Class io_service implements an extensible, type-safe, polymorphic set of I/O
1390ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * services, indexed by service type. An object of class io_service must be
1400ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * initialised before I/O objects such as sockets, resolvers and timers can be
1410ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * used. These I/O objects are distinguished by having constructors that accept
1420ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * an @c io_service& parameter.
1430ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie *
1440ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * I/O services exist to manage the logical interface to the operating system on
1450ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * behalf of the I/O objects. In particular, there are resources that are shared
1460ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * across a class of I/O objects. For example, timers may be implemented in
1470ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * terms of a single timer queue. The I/O services manage these shared
1480ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * resources.
1490ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie *
1500ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * Access to the services of an io_service is via three function templates,
1510ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * use_service(), add_service() and has_service().
1520ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie *
1530ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * In a call to @c use_service<Service>(), the type argument chooses a service,
1540ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * making available all members of the named type. If @c Service is not present
1550ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * in an io_service, an object of type @c Service is created and added to the
1560ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * io_service. A C++ program can check if an io_service implements a
1570ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * particular service with the function template @c has_service<Service>().
1580ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie *
1590ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * Service objects may be explicitly added to an io_service using the function
1600ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * template @c add_service<Service>(). If the @c Service is already present, the
1610ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * service_already_exists exception is thrown. If the owner of the service is
1620ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * not the same object as the io_service parameter, the invalid_service_owner
1630ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * exception is thrown.
1640ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie *
1650ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * Once a service reference is obtained from an io_service object by calling
1660ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * use_service(), that reference remains usable as long as the owning io_service
1670ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * object exists.
1680ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie *
1690ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * All I/O service implementations have io_service::service as a public base
1700ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * class. Custom I/O services may be implemented by deriving from this class and
1710ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * then added to an io_service using the facilities described above.
1720ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie */
1730ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffieclass io_service
1740ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  : private noncopyable
1750ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie{
1760ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffieprivate:
1770ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  typedef detail::io_service_impl impl_type;
1780ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie
1790ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffiepublic:
1800ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  class work;
1810ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  friend class work;
1820ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie
1830ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  class id;
1840ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie
1850ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  class service;
1860ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie
1870ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  class strand;
1880ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie
1890ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  /// Constructor.
1900ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  ASIO_DECL io_service();
1910ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie
1920ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  /// Constructor.
1930ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  /**
1940ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * Construct with a hint about the required level of concurrency.
1950ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   *
1960ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * @param concurrency_hint A suggestion to the implementation on how many
1970ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * threads it should allow to run simultaneously.
1980ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   */
1990ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  ASIO_DECL explicit io_service(std::size_t concurrency_hint);
2000ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie
2010ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  /// Destructor.
2020ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  /**
2030ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * On destruction, the io_service performs the following sequence of
2040ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * operations:
2050ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   *
2060ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * @li For each service object @c svc in the io_service set, in reverse order
2070ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * of the beginning of service object lifetime, performs
2080ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * @c svc->shutdown_service().
2090ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   *
2100ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * @li Uninvoked handler objects that were scheduled for deferred invocation
2110ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * on the io_service, or any associated strand, are destroyed.
2120ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   *
2130ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * @li For each service object @c svc in the io_service set, in reverse order
2140ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * of the beginning of service object lifetime, performs
2150ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * <tt>delete static_cast<io_service::service*>(svc)</tt>.
2160ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   *
2170ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * @note The destruction sequence described above permits programs to
2180ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * simplify their resource management by using @c shared_ptr<>. Where an
2190ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * object's lifetime is tied to the lifetime of a connection (or some other
2200ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * sequence of asynchronous operations), a @c shared_ptr to the object would
2210ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * be bound into the handlers for all asynchronous operations associated with
2220ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * it. This works as follows:
2230ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   *
2240ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * @li When a single connection ends, all associated asynchronous operations
2250ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * complete. The corresponding handler objects are destroyed, and all
2260ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * @c shared_ptr references to the objects are destroyed.
2270ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   *
2280ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * @li To shut down the whole program, the io_service function stop() is
2290ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * called to terminate any run() calls as soon as possible. The io_service
2300ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * destructor defined above destroys all handlers, causing all @c shared_ptr
2310ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * references to all connection objects to be destroyed.
2320ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   */
2330ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  ASIO_DECL ~io_service();
2340ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie
2350ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  /// Run the io_service object's event processing loop.
2360ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  /**
2370ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * The run() function blocks until all work has finished and there are no
2380ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * more handlers to be dispatched, or until the io_service has been stopped.
2390ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   *
2400ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * Multiple threads may call the run() function to set up a pool of threads
2410ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * from which the io_service may execute handlers. All threads that are
2420ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * waiting in the pool are equivalent and the io_service may choose any one
2430ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * of them to invoke a handler.
2440ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   *
2450ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * A normal exit from the run() function implies that the io_service object
2460ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * is stopped (the stopped() function returns @c true). Subsequent calls to
2470ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * run(), run_one(), poll() or poll_one() will return immediately unless there
2480ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * is a prior call to reset().
2490ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   *
2500ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * @return The number of handlers that were executed.
2510ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   *
2520ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * @throws asio::system_error Thrown on failure.
2530ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   *
2540ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * @note The run() function must not be called from a thread that is currently
2550ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * calling one of run(), run_one(), poll() or poll_one() on the same
2560ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * io_service object.
2570ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   *
2580ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * The poll() function may also be used to dispatch ready handlers, but
2590ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * without blocking.
2600ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   */
2610ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  ASIO_DECL std::size_t run();
2620ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie
2630ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  /// Run the io_service object's event processing loop.
2640ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  /**
2650ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * The run() function blocks until all work has finished and there are no
2660ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * more handlers to be dispatched, or until the io_service has been stopped.
2670ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   *
2680ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * Multiple threads may call the run() function to set up a pool of threads
2690ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * from which the io_service may execute handlers. All threads that are
2700ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * waiting in the pool are equivalent and the io_service may choose any one
2710ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * of them to invoke a handler.
2720ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   *
2730ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * A normal exit from the run() function implies that the io_service object
2740ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * is stopped (the stopped() function returns @c true). Subsequent calls to
2750ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * run(), run_one(), poll() or poll_one() will return immediately unless there
2760ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * is a prior call to reset().
2770ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   *
2780ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * @param ec Set to indicate what error occurred, if any.
2790ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   *
2800ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * @return The number of handlers that were executed.
2810ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   *
2820ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * @note The run() function must not be called from a thread that is currently
2830ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * calling one of run(), run_one(), poll() or poll_one() on the same
2840ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * io_service object.
2850ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   *
2860ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * The poll() function may also be used to dispatch ready handlers, but
2870ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * without blocking.
2880ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   */
2890ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  ASIO_DECL std::size_t run(asio::error_code& ec);
2900ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie
2910ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  /// Run the io_service object's event processing loop to execute at most one
2920ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  /// handler.
2930ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  /**
2940ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * The run_one() function blocks until one handler has been dispatched, or
2950ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * until the io_service has been stopped.
2960ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   *
2970ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * @return The number of handlers that were executed. A zero return value
2980ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * implies that the io_service object is stopped (the stopped() function
2990ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * returns @c true). Subsequent calls to run(), run_one(), poll() or
3000ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * poll_one() will return immediately unless there is a prior call to
3010ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * reset().
3020ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   *
3030ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * @throws asio::system_error Thrown on failure.
3040ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   */
3050ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  ASIO_DECL std::size_t run_one();
3060ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie
3070ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  /// Run the io_service object's event processing loop to execute at most one
3080ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  /// handler.
3090ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  /**
3100ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * The run_one() function blocks until one handler has been dispatched, or
3110ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * until the io_service has been stopped.
3120ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   *
3130ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * @return The number of handlers that were executed. A zero return value
3140ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * implies that the io_service object is stopped (the stopped() function
3150ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * returns @c true). Subsequent calls to run(), run_one(), poll() or
3160ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * poll_one() will return immediately unless there is a prior call to
3170ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * reset().
3180ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   *
3190ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * @return The number of handlers that were executed.
3200ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   */
3210ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  ASIO_DECL std::size_t run_one(asio::error_code& ec);
3220ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie
3230ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  /// Run the io_service object's event processing loop to execute ready
3240ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  /// handlers.
3250ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  /**
3260ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * The poll() function runs handlers that are ready to run, without blocking,
3270ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * until the io_service has been stopped or there are no more ready handlers.
3280ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   *
3290ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * @return The number of handlers that were executed.
3300ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   *
3310ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * @throws asio::system_error Thrown on failure.
3320ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   */
3330ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  ASIO_DECL std::size_t poll();
3340ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie
3350ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  /// Run the io_service object's event processing loop to execute ready
3360ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  /// handlers.
3370ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  /**
3380ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * The poll() function runs handlers that are ready to run, without blocking,
3390ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * until the io_service has been stopped or there are no more ready handlers.
3400ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   *
3410ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * @param ec Set to indicate what error occurred, if any.
3420ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   *
3430ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * @return The number of handlers that were executed.
3440ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   */
3450ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  ASIO_DECL std::size_t poll(asio::error_code& ec);
3460ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie
3470ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  /// Run the io_service object's event processing loop to execute one ready
3480ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  /// handler.
3490ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  /**
3500ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * The poll_one() function runs at most one handler that is ready to run,
3510ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * without blocking.
3520ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   *
3530ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * @return The number of handlers that were executed.
3540ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   *
3550ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * @throws asio::system_error Thrown on failure.
3560ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   */
3570ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  ASIO_DECL std::size_t poll_one();
3580ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie
3590ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  /// Run the io_service object's event processing loop to execute one ready
3600ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  /// handler.
3610ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  /**
3620ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * The poll_one() function runs at most one handler that is ready to run,
3630ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * without blocking.
3640ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   *
3650ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * @param ec Set to indicate what error occurred, if any.
3660ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   *
3670ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * @return The number of handlers that were executed.
3680ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   */
3690ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  ASIO_DECL std::size_t poll_one(asio::error_code& ec);
3700ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie
3710ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  /// Stop the io_service object's event processing loop.
3720ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  /**
3730ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * This function does not block, but instead simply signals the io_service to
3740ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * stop. All invocations of its run() or run_one() member functions should
3750ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * return as soon as possible. Subsequent calls to run(), run_one(), poll()
3760ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * or poll_one() will return immediately until reset() is called.
3770ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   */
3780ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  ASIO_DECL void stop();
3790ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie
3800ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  /// Determine whether the io_service object has been stopped.
3810ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  /**
3820ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * This function is used to determine whether an io_service object has been
3830ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * stopped, either through an explicit call to stop(), or due to running out
3840ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * of work. When an io_service object is stopped, calls to run(), run_one(),
3850ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * poll() or poll_one() will return immediately without invoking any
3860ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * handlers.
3870ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   *
3880ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * @return @c true if the io_service object is stopped, otherwise @c false.
3890ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   */
3900ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  ASIO_DECL bool stopped() const;
3910ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie
3920ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  /// Reset the io_service in preparation for a subsequent run() invocation.
3930ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  /**
3940ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * This function must be called prior to any second or later set of
3950ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * invocations of the run(), run_one(), poll() or poll_one() functions when a
3960ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * previous invocation of these functions returned due to the io_service
3970ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * being stopped or running out of work. After a call to reset(), the
3980ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * io_service object's stopped() function will return @c false.
3990ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   *
4000ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * This function must not be called while there are any unfinished calls to
4010ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * the run(), run_one(), poll() or poll_one() functions.
4020ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   */
4030ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  ASIO_DECL void reset();
4040ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie
4050ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  /// Request the io_service to invoke the given handler.
4060ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  /**
4070ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * This function is used to ask the io_service to execute the given handler.
4080ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   *
4090ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * The io_service guarantees that the handler will only be called in a thread
4100ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * in which the run(), run_one(), poll() or poll_one() member functions is
4110ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * currently being invoked. The handler may be executed inside this function
4120ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * if the guarantee can be met.
4130ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   *
4140ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * @param handler The handler to be called. The io_service will make
4150ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * a copy of the handler object as required. The function signature of the
4160ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * handler must be: @code void handler(); @endcode
4170ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   *
4180ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * @note This function throws an exception only if:
4190ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   *
4200ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * @li the handler's @c asio_handler_allocate function; or
4210ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   *
4220ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * @li the handler's copy constructor
4230ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   *
4240ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * throws an exception.
4250ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   */
4260ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  template <typename CompletionHandler>
4270ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  ASIO_INITFN_RESULT_TYPE(CompletionHandler, void ())
4280ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  dispatch(ASIO_MOVE_ARG(CompletionHandler) handler);
4290ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie
4300ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  /// Request the io_service to invoke the given handler and return immediately.
4310ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  /**
4320ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * This function is used to ask the io_service to execute the given handler,
4330ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * but without allowing the io_service to call the handler from inside this
4340ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * function.
4350ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   *
4360ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * The io_service guarantees that the handler will only be called in a thread
4370ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * in which the run(), run_one(), poll() or poll_one() member functions is
4380ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * currently being invoked.
4390ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   *
4400ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * @param handler The handler to be called. The io_service will make
4410ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * a copy of the handler object as required. The function signature of the
4420ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * handler must be: @code void handler(); @endcode
4430ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   *
4440ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * @note This function throws an exception only if:
4450ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   *
4460ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * @li the handler's @c asio_handler_allocate function; or
4470ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   *
4480ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * @li the handler's copy constructor
4490ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   *
4500ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * throws an exception.
4510ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   */
4520ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  template <typename CompletionHandler>
4530ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  ASIO_INITFN_RESULT_TYPE(CompletionHandler, void ())
4540ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  post(ASIO_MOVE_ARG(CompletionHandler) handler);
4550ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie
4560ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  /// Create a new handler that automatically dispatches the wrapped handler
4570ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  /// on the io_service.
4580ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  /**
4590ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * This function is used to create a new handler function object that, when
4600ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * invoked, will automatically pass the wrapped handler to the io_service
4610ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * object's dispatch function.
4620ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   *
4630ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * @param handler The handler to be wrapped. The io_service will make a copy
4640ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * of the handler object as required. The function signature of the handler
4650ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * must be: @code void handler(A1 a1, ... An an); @endcode
4660ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   *
4670ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * @return A function object that, when invoked, passes the wrapped handler to
4680ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * the io_service object's dispatch function. Given a function object with the
4690ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * signature:
4700ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * @code R f(A1 a1, ... An an); @endcode
4710ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * If this function object is passed to the wrap function like so:
4720ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * @code io_service.wrap(f); @endcode
4730ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * then the return value is a function object with the signature
4740ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * @code void g(A1 a1, ... An an); @endcode
4750ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * that, when invoked, executes code equivalent to:
4760ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * @code io_service.dispatch(boost::bind(f, a1, ... an)); @endcode
4770ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   */
4780ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  template <typename Handler>
4790ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  detail::wrapped_handler<io_service&, Handler>
4800ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  wrap(Handler handler);
4810ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie
4820ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  /// Fork-related event notifications.
4830ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  enum fork_event
4840ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  {
4850ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie    /// Notify the io_service that the process is about to fork.
4860ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie    fork_prepare,
4870ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie
4880ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie    /// Notify the io_service that the process has forked and is the parent.
4890ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie    fork_parent,
4900ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie
4910ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie    /// Notify the io_service that the process has forked and is the child.
4920ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie    fork_child
4930ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  };
4940ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie
4950ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  /// Notify the io_service of a fork-related event.
4960ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  /**
4970ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * This function is used to inform the io_service that the process is about
4980ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * to fork, or has just forked. This allows the io_service, and the services
4990ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * it contains, to perform any necessary housekeeping to ensure correct
5000ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * operation following a fork.
5010ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   *
5020ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * This function must not be called while any other io_service function, or
5030ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * any function on an I/O object associated with the io_service, is being
5040ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * called in another thread. It is, however, safe to call this function from
5050ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * within a completion handler, provided no other thread is accessing the
5060ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * io_service.
5070ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   *
5080ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * @param event A fork-related event.
5090ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   *
5100ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * @throws asio::system_error Thrown on failure. If the notification
5110ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * fails the io_service object should no longer be used and should be
5120ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * destroyed.
5130ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   *
5140ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * @par Example
5150ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * The following code illustrates how to incorporate the notify_fork()
5160ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * function:
5170ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * @code my_io_service.notify_fork(asio::io_service::fork_prepare);
5180ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * if (fork() == 0)
5190ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * {
5200ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   *   // This is the child process.
5210ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   *   my_io_service.notify_fork(asio::io_service::fork_child);
5220ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * }
5230ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * else
5240ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * {
5250ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   *   // This is the parent process.
5260ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   *   my_io_service.notify_fork(asio::io_service::fork_parent);
5270ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * } @endcode
5280ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   *
5290ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * @note For each service object @c svc in the io_service set, performs
5300ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * <tt>svc->fork_service();</tt>. When processing the fork_prepare event,
5310ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * services are visited in reverse order of the beginning of service object
5320ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * lifetime. Otherwise, services are visited in order of the beginning of
5330ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * service object lifetime.
5340ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   */
5350ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  ASIO_DECL void notify_fork(asio::io_service::fork_event event);
5360ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie
5370ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  /// Obtain the service object corresponding to the given type.
5380ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  /**
5390ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * This function is used to locate a service object that corresponds to
5400ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * the given service type. If there is no existing implementation of the
5410ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * service, then the io_service will create a new instance of the service.
5420ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   *
5430ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * @param ios The io_service object that owns the service.
5440ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   *
5450ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * @return The service interface implementing the specified service type.
5460ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * Ownership of the service interface is not transferred to the caller.
5470ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   */
5480ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  template <typename Service>
5490ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  friend Service& use_service(io_service& ios);
5500ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie
5510ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  /// Add a service object to the io_service.
5520ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  /**
5530ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * This function is used to add a service to the io_service.
5540ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   *
5550ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * @param ios The io_service object that owns the service.
5560ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   *
5570ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * @param svc The service object. On success, ownership of the service object
5580ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * is transferred to the io_service. When the io_service object is destroyed,
5590ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * it will destroy the service object by performing:
5600ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * @code delete static_cast<io_service::service*>(svc) @endcode
5610ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   *
5620ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * @throws asio::service_already_exists Thrown if a service of the
5630ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * given type is already present in the io_service.
5640ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   *
5650ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * @throws asio::invalid_service_owner Thrown if the service's owning
5660ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * io_service is not the io_service object specified by the ios parameter.
5670ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   */
5680ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  template <typename Service>
5690ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  friend void add_service(io_service& ios, Service* svc);
5700ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie
5710ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  /// Determine if an io_service contains a specified service type.
5720ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  /**
5730ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * This function is used to determine whether the io_service contains a
5740ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * service object corresponding to the given service type.
5750ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   *
5760ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * @param ios The io_service object that owns the service.
5770ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   *
5780ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * @return A boolean indicating whether the io_service contains the service.
5790ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   */
5800ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  template <typename Service>
5810ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  friend bool has_service(io_service& ios);
5820ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie
5830ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffieprivate:
5840ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie#if   defined(__sun) || defined(__QNX__) || defined(__hpux) || defined(_AIX)    || defined(__osf__)
5850ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  detail::signal_init<> init_;
5860ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie#endif
5870ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie
5880ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  // The service registry.
5890ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  asio::detail::service_registry* service_registry_;
5900ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie
5910ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  // The implementation.
5920ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  impl_type& impl_;
5930ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie};
5940ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie
5950ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie/// Class to inform the io_service when it has work to do.
5960ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie/**
5970ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * The work class is used to inform the io_service when work starts and
5980ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * finishes. This ensures that the io_service object's run() function will not
5990ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * exit while work is underway, and that it does exit when there is no
6000ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * unfinished work remaining.
6010ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie *
6020ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * The work class is copy-constructible so that it may be used as a data member
6030ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * in a handler class. It is not assignable.
6040ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie */
6050ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffieclass io_service::work
6060ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie{
6070ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffiepublic:
6080ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  /// Constructor notifies the io_service that work is starting.
6090ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  /**
6100ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * The constructor is used to inform the io_service that some work has begun.
6110ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * This ensures that the io_service object's run() function will not exit
6120ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * while the work is underway.
6130ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   */
6140ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  explicit work(asio::io_service& io_service);
6150ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie
6160ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  /// Copy constructor notifies the io_service that work is starting.
6170ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  /**
6180ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * The constructor is used to inform the io_service that some work has begun.
6190ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * This ensures that the io_service object's run() function will not exit
6200ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * while the work is underway.
6210ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   */
6220ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  work(const work& other);
6230ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie
6240ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  /// Destructor notifies the io_service that the work is complete.
6250ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  /**
6260ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * The destructor is used to inform the io_service that some work has
6270ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * finished. Once the count of unfinished work reaches zero, the io_service
6280ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * object's run() function is permitted to exit.
6290ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   */
6300ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  ~work();
6310ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie
6320ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  /// Get the io_service associated with the work.
6330ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  asio::io_service& get_io_service();
6340ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie
6350ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffieprivate:
6360ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  // Prevent assignment.
6370ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  void operator=(const work& other);
6380ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie
6390ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  // The io_service implementation.
6400ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  detail::io_service_impl& io_service_impl_;
6410ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie};
6420ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie
6430ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie/// Class used to uniquely identify a service.
6440ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffieclass io_service::id
6450ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  : private noncopyable
6460ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie{
6470ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffiepublic:
6480ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  /// Constructor.
6490ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  id() {}
6500ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie};
6510ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie
6520ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie/// Base class for all io_service services.
6530ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffieclass io_service::service
6540ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  : private noncopyable
6550ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie{
6560ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffiepublic:
6570ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  /// Get the io_service object that owns the service.
6580ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  asio::io_service& get_io_service();
6590ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie
6600ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffieprotected:
6610ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  /// Constructor.
6620ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  /**
6630ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * @param owner The io_service object that owns the service.
6640ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   */
6650ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  ASIO_DECL service(asio::io_service& owner);
6660ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie
6670ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  /// Destructor.
6680ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  ASIO_DECL virtual ~service();
6690ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie
6700ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffieprivate:
6710ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  /// Destroy all user-defined handler objects owned by the service.
6720ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  virtual void shutdown_service() = 0;
6730ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie
6740ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  /// Handle notification of a fork-related event to perform any necessary
6750ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  /// housekeeping.
6760ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  /**
6770ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * This function is not a pure virtual so that services only have to
6780ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   * implement it if necessary. The default implementation does nothing.
6790ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie   */
6800ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  ASIO_DECL virtual void fork_service(
6810ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie      asio::io_service::fork_event event);
6820ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie
6830ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  friend class asio::detail::service_registry;
6840ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  struct key
6850ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  {
6860ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie    key() : type_info_(0), id_(0) {}
6870ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie    const std::type_info* type_info_;
6880ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie    const asio::io_service::id* id_;
6890ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  } key_;
6900ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie
6910ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  asio::io_service& owner_;
6920ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  service* next_;
6930ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie};
6940ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie
6950ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie/// Exception thrown when trying to add a duplicate service to an io_service.
6960ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffieclass service_already_exists
6970ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  : public std::logic_error
6980ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie{
6990ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffiepublic:
7000ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  ASIO_DECL service_already_exists();
7010ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie};
7020ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie
7030ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie/// Exception thrown when trying to add a service object to an io_service where
7040ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie/// the service has a different owner.
7050ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffieclass invalid_service_owner
7060ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  : public std::logic_error
7070ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie{
7080ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffiepublic:
7090ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  ASIO_DECL invalid_service_owner();
7100ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie};
7110ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie
7120ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffienamespace detail {
7130ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie
7140ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie// Special derived service id type to keep classes header-file only.
7150ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffietemplate <typename Type>
7160ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffieclass service_id
7170ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  : public asio::io_service::id
7180ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie{
7190ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie};
7200ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie
7210ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie// Special service base class to keep classes header-file only.
7220ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffietemplate <typename Type>
7230ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffieclass service_base
7240ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  : public asio::io_service::service
7250ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie{
7260ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffiepublic:
7270ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  static asio::detail::service_id<Type> id;
7280ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie
7290ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  // Constructor.
7300ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  service_base(asio::io_service& io_service)
7310ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie    : asio::io_service::service(io_service)
7320ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  {
7330ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  }
7340ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie};
7350ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie
7360ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffietemplate <typename Type>
7370ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffieasio::detail::service_id<Type> service_base<Type>::id;
7380ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie
7390ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie} // namespace detail
7400ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie} // namespace asio
7410ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie
7420ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie#include "asio/detail/pop_options.hpp"
7430ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie
7440ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie#include "asio/impl/io_service.hpp"
7450ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie# include "asio/impl/io_service.ipp"
7460ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie
7470ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie#endif // ASIO_IO_SERVICE_HPP
748