Changeset 84311

Timestamp:
May 17, 2013, 1:38:47 AM (9 years ago)
Author:
chris_kohlhoff
Message:

Add the asio::spawn() function, a high-level wrapper for running
stackful coroutines. It is based on the Boost.Coroutine library.

Here is an example of its use:

asio::spawn(my_strand, do_echo);

...

void do_echo(asio::yield_context yield)
{

try
{

char data[128];
for (;;)
{

std::size_t length =

my_socket.async_read_some(

asio::buffer(data), yield);

asio::async_write(my_socket,

asio::buffer(data, length), yield);

}

}
catch (std::exception& e)
{

...

}

}

The first argument to asio::spawn() may be a strand, io_service or
completion handler. This argument determines the context in which the
coroutine is permitted to execute. For example, a server's per-client
object may consist of multiple coroutines; they should all run on the
same strand so that no explicit synchronisation is required.

The second argument is a function object with signature ():

void coroutine(asio::yield_context yield);

that specifies the code to be run as part of the coroutine. The
parameter yield may be passed to an asynchronous operation in place of
the completion handler, as in:

std::size_t length =

my_socket.async_read_some(

asio::buffer(data), yield);

This starts the asynchronous operation and suspends the coroutine. The
coroutine will be resumed automatically when the asynchronous operation
completes.

Where a completion handler signature has the form:

void handler(error_code ec, result_type result);

the initiating function returns the result_type. In the async_read_some
example above, this is std::size_t. If the asynchronous operation fails,
the error_code is converted into a system_error exception and thrown.

Where a completion handler signature has the form:

void handler(error_code ec);

the initiating function returns void. As above, an error is passed back
to the coroutine as a system_error exception.

To collect the error_code from an operation, rather than have it throw
an exception, associate the output variable with the yield_context as
follows:

error_code ec;
std::size_t length =

my_socket.async_read_some(

asio::buffer(data), yield[ec]);

Note: if asio::spawn() is used with a custom completion handler of
type Handler, the function object signature is actually:

void coroutine(asio::basic_yield_context<Handler> yield);

(No files)

Note: See TracChangeset for help on using the changeset viewer.