...one of the most highly
regarded and expertly designed C++ library projects in the
world.
— Herb Sutter and Andrei
Alexandrescu, C++
Coding Standards
Provides core I/O functionality.
class io_service : noncopyable
Name |
Description |
---|---|
Class used to uniquely identify a service. |
|
Base class for all io_service services. |
|
Provides serialised handler execution. |
|
Class to inform the io_service when it has work to do. |
Name |
Description |
---|---|
Request the io_service to invoke the given handler. |
|
Constructor. |
|
Run the io_service object's event processing loop to execute ready handlers. |
|
Run the io_service object's event processing loop to execute one ready handler. |
|
Request the io_service to invoke the given handler and return immediately. |
|
Reset the io_service in preparation for a subsequent run() invocation. |
|
Run the io_service object's event processing loop. |
|
Run the io_service object's event processing loop to execute at most one handler. |
|
Stop the io_service object's event processing loop. |
|
Create a new handler that automatically dispatches the wrapped handler on the io_service. |
|
Destructor. |
Name |
Description |
---|---|
Add a service object to the io_service. |
|
Determine if an io_service contains a specified service type. |
|
Obtain the service object corresponding to the given type. |
The io_service
class provides the core I/O functionality for users of the asynchronous I/O
objects, including:
The io_service
class also includes facilities intended for developers of custom asynchronous
services.
Distinct objects: Safe.
Shared objects:
Safe, with the exception that calling reset()
while there are unfinished run()
,
run_one()
,
poll()
or poll_one()
calls results in undefined behaviour.
Synchronous operations on I/O objects implicitly run the io_service
object for an individual
operation. The io_service
functions run()
,
run_one()
,
poll()
or poll_one()
must be called for the io_service
to perform asynchronous
operations on behalf of a C++ program. Notification that an asynchronous
operation has completed is delivered by invocation of the associated handler.
Handlers are invoked only by a thread that is currently calling any overload
of run()
,
run_one()
,
poll()
or poll_one()
for the io_service
.
If an exception is thrown from a handler, the exception is allowed to propagate
through the throwing thread's invocation of run()
, run_one()
, poll()
or poll_one()
. No other threads that are calling any
of these functions are affected. It is then the responsibility of the application
to catch the exception.
After the exception has been caught, the run()
, run_one()
, poll()
or poll_one()
call may be restarted without
the need for an intervening call to reset()
. This allows the thread to rejoin the
io_service
object's thread pool without impacting any other threads in the pool.
For example:
boost::asio::io_service io_service; ... for (;;) { try { io_service.run(); break; // run() exited normally } catch (my_exception& e) { // Deal with exception as appropriate. } }
Some applications may need to prevent an io_service
object's run()
call
from returning when there is no more work to do. For example, the io_service
may be being run in a
background thread that is launched prior to the application's asynchronous
operations. The run()
call may be kept running by creating an object of type io_service::work
:
boost::asio::io_service io_service; boost::asio::io_service::work work(io_service); ...
To effect a shutdown, the application will then need to call the io_service
object's stop()
member function. This will cause the io_service
run()
call to return as soon as possible, abandoning
unfinished operations and without permitting ready handlers to be dispatched.
Alternatively, if the application requires that all operations and handlers be allowed to finish normally, the work object may be explicitly destroyed.
boost::asio::io_service io_service; auto_ptr<boost::asio::io_service::work> work( new boost::asio::io_service::work(io_service)); ... work.reset(); // Allow run() to exit.
Class io_service
implements an extensible, type-safe, polymorphic set of I/O services, indexed
by service type. An object of class io_service
must be initialised before
I/O objects such as sockets, resolvers and timers can be used. These I/O
objects are distinguished by having constructors that accept an io_service&
parameter.
I/O services exist to manage the logical interface to the operating system on behalf of the I/O objects. In particular, there are resources that are shared across a class of I/O objects. For example, timers may be implemented in terms of a single timer queue. The I/O services manage these shared resources.
Access to the services of an io_service
is via three function
templates, use_service()
,
add_service()
and has_service()
.
In a call to use_service<Service>()
, the type argument chooses a service,
making available all members of the named type. If Service
is not present in an io_service
, an object of type Service
is created and added to the io_service
.
A C++ program can check if an io_service
implements a particular
service with the function template has_service<Service>()
.
Service objects may be explicitly added to an io_service
using the function template
add_service<Service>()
.
If the Service
is already
present, the service_already_exists
exception
is thrown. If the owner of the service is not the same object as the io_service
parameter, the invalid_service_owner
exception
is thrown.
Once a service reference is obtained from an io_service
object by calling use_service()
,
that reference remains usable as long as the owning io_service
object exists.
All I/O service implementations have io_service::service
as a public base class.
Custom I/O services may be implemented by deriving from this class and then
added to an io_service
using the facilities
described above.
Header: boost/asio/io_service.hpp
Convenience header: boost/asio.hpp