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