/usr/include/asio/spawn.hpp is in libasio-dev 1:1.10.2-2.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 | //
// spawn.hpp
// ~~~~~~~~~
//
// Copyright (c) 2003-2014 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef ASIO_SPAWN_HPP
#define ASIO_SPAWN_HPP
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
#include "asio/detail/config.hpp"
#include <boost/coroutine/all.hpp>
#include "asio/detail/weak_ptr.hpp"
#include "asio/detail/wrapped_handler.hpp"
#include "asio/io_service.hpp"
#include "asio/strand.hpp"
#include "asio/detail/push_options.hpp"
namespace asio {
/// Context object the represents the currently executing coroutine.
/**
* The basic_yield_context class is used to represent the currently executing
* stackful coroutine. A basic_yield_context may be passed as a handler to an
* asynchronous operation. For example:
*
* @code template <typename Handler>
* void my_coroutine(basic_yield_context<Handler> yield)
* {
* ...
* std::size_t n = my_socket.async_read_some(buffer, yield);
* ...
* } @endcode
*
* The initiating function (async_read_some in the above example) suspends the
* current coroutine. The coroutine is resumed when the asynchronous operation
* completes, and the result of the operation is returned.
*/
template <typename Handler>
class basic_yield_context
{
public:
/// The coroutine callee type, used by the implementation.
/**
* When using Boost.Coroutine v1, this type is:
* @code typename coroutine<void()> @endcode
* When using Boost.Coroutine v2 (unidirectional coroutines), this type is:
* @code push_coroutine<void> @endcode
*/
#if defined(GENERATING_DOCUMENTATION)
typedef implementation_defined callee_type;
#elif defined(BOOST_COROUTINES_UNIDIRECT) || defined(BOOST_COROUTINES_V2)
typedef boost::coroutines::push_coroutine<void> callee_type;
#else
typedef boost::coroutines::coroutine<void()> callee_type;
#endif
/// The coroutine caller type, used by the implementation.
/**
* When using Boost.Coroutine v1, this type is:
* @code typename coroutine<void()>::caller_type @endcode
* When using Boost.Coroutine v2 (unidirectional coroutines), this type is:
* @code pull_coroutine<void> @endcode
*/
#if defined(GENERATING_DOCUMENTATION)
typedef implementation_defined caller_type;
#elif defined(BOOST_COROUTINES_UNIDIRECT) || defined(BOOST_COROUTINES_V2)
typedef boost::coroutines::pull_coroutine<void> caller_type;
#else
typedef boost::coroutines::coroutine<void()>::caller_type caller_type;
#endif
/// Construct a yield context to represent the specified coroutine.
/**
* Most applications do not need to use this constructor. Instead, the
* spawn() function passes a yield context as an argument to the coroutine
* function.
*/
basic_yield_context(
const detail::weak_ptr<callee_type>& coro,
caller_type& ca, Handler& handler)
: coro_(coro),
ca_(ca),
handler_(handler),
ec_(0)
{
}
/// Return a yield context that sets the specified error_code.
/**
* By default, when a yield context is used with an asynchronous operation, a
* non-success error_code is converted to system_error and thrown. This
* operator may be used to specify an error_code object that should instead be
* set with the asynchronous operation's result. For example:
*
* @code template <typename Handler>
* void my_coroutine(basic_yield_context<Handler> yield)
* {
* ...
* std::size_t n = my_socket.async_read_some(buffer, yield[ec]);
* if (ec)
* {
* // An error occurred.
* }
* ...
* } @endcode
*/
basic_yield_context operator[](asio::error_code& ec) const
{
basic_yield_context tmp(*this);
tmp.ec_ = &ec;
return tmp;
}
#if defined(GENERATING_DOCUMENTATION)
private:
#endif // defined(GENERATING_DOCUMENTATION)
detail::weak_ptr<callee_type> coro_;
caller_type& ca_;
Handler& handler_;
asio::error_code* ec_;
};
#if defined(GENERATING_DOCUMENTATION)
/// Context object that represents the currently executing coroutine.
typedef basic_yield_context<unspecified> yield_context;
#else // defined(GENERATING_DOCUMENTATION)
typedef basic_yield_context<
detail::wrapped_handler<
io_service::strand, void(*)(),
detail::is_continuation_if_running> > yield_context;
#endif // defined(GENERATING_DOCUMENTATION)
/**
* @defgroup spawn asio::spawn
*
* @brief Start a new stackful coroutine.
*
* The spawn() function is a high-level wrapper over the Boost.Coroutine
* library. This function enables programs to implement asynchronous logic in a
* synchronous manner, as illustrated by the following example:
*
* @code 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)
* {
* // ...
* }
* } @endcode
*/
/*@{*/
/// Start a new stackful coroutine, calling the specified handler when it
/// completes.
/**
* This function is used to launch a new coroutine.
*
* @param handler A handler to be called when the coroutine exits. More
* importantly, the handler provides an execution context (via the the handler
* invocation hook) for the coroutine. The handler must have the signature:
* @code void handler(); @endcode
*
* @param function The coroutine function. The function must have the signature:
* @code void function(basic_yield_context<Handler> yield); @endcode
*
* @param attributes Boost.Coroutine attributes used to customise the coroutine.
*/
template <typename Handler, typename Function>
void spawn(ASIO_MOVE_ARG(Handler) handler,
ASIO_MOVE_ARG(Function) function,
const boost::coroutines::attributes& attributes
= boost::coroutines::attributes());
/// Start a new stackful coroutine, inheriting the execution context of another.
/**
* This function is used to launch a new coroutine.
*
* @param ctx Identifies the current coroutine as a parent of the new
* coroutine. This specifies that the new coroutine should inherit the
* execution context of the parent. For example, if the parent coroutine is
* executing in a particular strand, then the new coroutine will execute in the
* same strand.
*
* @param function The coroutine function. The function must have the signature:
* @code void function(basic_yield_context<Handler> yield); @endcode
*
* @param attributes Boost.Coroutine attributes used to customise the coroutine.
*/
template <typename Handler, typename Function>
void spawn(basic_yield_context<Handler> ctx,
ASIO_MOVE_ARG(Function) function,
const boost::coroutines::attributes& attributes
= boost::coroutines::attributes());
/// Start a new stackful coroutine that executes in the context of a strand.
/**
* This function is used to launch a new coroutine.
*
* @param strand Identifies a strand. By starting multiple coroutines on the
* same strand, the implementation ensures that none of those coroutines can
* execute simultaneously.
*
* @param function The coroutine function. The function must have the signature:
* @code void function(yield_context yield); @endcode
*
* @param attributes Boost.Coroutine attributes used to customise the coroutine.
*/
template <typename Function>
void spawn(asio::io_service::strand strand,
ASIO_MOVE_ARG(Function) function,
const boost::coroutines::attributes& attributes
= boost::coroutines::attributes());
/// Start a new stackful coroutine that executes on a given io_service.
/**
* This function is used to launch a new coroutine.
*
* @param io_service Identifies the io_service that will run the coroutine. The
* new coroutine is implicitly given its own strand within this io_service.
*
* @param function The coroutine function. The function must have the signature:
* @code void function(yield_context yield); @endcode
*
* @param attributes Boost.Coroutine attributes used to customise the coroutine.
*/
template <typename Function>
void spawn(asio::io_service& io_service,
ASIO_MOVE_ARG(Function) function,
const boost::coroutines::attributes& attributes
= boost::coroutines::attributes());
/*@}*/
} // namespace asio
#include "asio/detail/pop_options.hpp"
#include "asio/impl/spawn.hpp"
#endif // ASIO_SPAWN_HPP
|