Adds asio library and Storage Module
This commit is contained in:
1 parent
79a6ee5779
commit
30439acd43
4869 files changed
+618801
-903
No files matched your search
@@ -0,0 +1,429 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<title>coroutine</title>
|
||||
<link rel="stylesheet" href="../../boostbook.css" type="text/css">
|
||||
<meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
|
||||
<link rel="home" href="../../index.html" title="Asio">
|
||||
<link rel="up" href="../reference.html" title="Reference">
|
||||
<link rel="prev" href="const_buffers_1/value_type.html" title="const_buffers_1::value_type">
|
||||
<link rel="next" href="coroutine/coroutine.html" title="coroutine::coroutine">
|
||||
</head>
|
||||
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
|
||||
<table cellpadding="2" width="100%"><tr><td valign="top"><img alt="asio C++ library" width="250" height="60" src="../../asio.png"></td></tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="const_buffers_1/value_type.html"><img src="../../prev.png" alt="Prev"></a><a accesskey="u" href="../reference.html"><img src="../../up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../home.png" alt="Home"></a><a accesskey="n" href="coroutine/coroutine.html"><img src="../../next.png" alt="Next"></a>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="asio.reference.coroutine"></a><a class="link" href="coroutine.html" title="coroutine">coroutine</a>
|
||||
</h3></div></div></div>
|
||||
<p>
|
||||
Provides support for implementing stackless coroutines.
|
||||
</p>
|
||||
<pre class="programlisting">class coroutine
|
||||
</pre>
|
||||
<h5>
|
||||
<a name="asio.reference.coroutine.h0"></a>
|
||||
<span><a name="asio.reference.coroutine.member_functions"></a></span><a class="link" href="coroutine.html#asio.reference.coroutine.member_functions">Member
|
||||
Functions</a>
|
||||
</h5>
|
||||
<div class="informaltable"><table class="table">
|
||||
<colgroup>
|
||||
<col>
|
||||
<col>
|
||||
</colgroup>
|
||||
<thead><tr>
|
||||
<th>
|
||||
<p>
|
||||
Name
|
||||
</p>
|
||||
</th>
|
||||
<th>
|
||||
<p>
|
||||
Description
|
||||
</p>
|
||||
</th>
|
||||
</tr></thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<p>
|
||||
<a class="link" href="coroutine/coroutine.html" title="coroutine::coroutine"><span class="bold"><strong>coroutine</strong></span></a>
|
||||
<span class="silver">[constructor]</span>
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
Constructs a coroutine in its initial state.
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<p>
|
||||
<a class="link" href="coroutine/is_child.html" title="coroutine::is_child"><span class="bold"><strong>is_child</strong></span></a>
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
Returns true if the coroutine is the child of a fork.
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<p>
|
||||
<a class="link" href="coroutine/is_complete.html" title="coroutine::is_complete"><span class="bold"><strong>is_complete</strong></span></a>
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
Returns true if the coroutine has reached its terminal state.
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<p>
|
||||
<a class="link" href="coroutine/is_parent.html" title="coroutine::is_parent"><span class="bold"><strong>is_parent</strong></span></a>
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
Returns true if the coroutine is the parent of a fork.
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table></div>
|
||||
<p>
|
||||
The <code class="computeroutput">coroutine</code> class may be used to implement stackless coroutines.
|
||||
The class itself is used to store the current state of the coroutine.
|
||||
</p>
|
||||
<p>
|
||||
Coroutines are copy-constructible and assignable, and the space overhead
|
||||
is a single int. They can be used as a base class:
|
||||
</p>
|
||||
<pre class="programlisting">class session : coroutine
|
||||
{
|
||||
...
|
||||
};
|
||||
</pre>
|
||||
<p>
|
||||
or as a data member:
|
||||
</p>
|
||||
<pre class="programlisting">class session
|
||||
{
|
||||
...
|
||||
coroutine coro_;
|
||||
};
|
||||
</pre>
|
||||
<p>
|
||||
or even bound in as a function argument using lambdas or <code class="computeroutput">bind()</code>.
|
||||
The important thing is that as the application maintains a copy of the object
|
||||
for as long as the coroutine must be kept alive.
|
||||
</p>
|
||||
<h5>
|
||||
<a name="asio.reference.coroutine.h1"></a>
|
||||
<span><a name="asio.reference.coroutine.pseudo_keywords"></a></span><a class="link" href="coroutine.html#asio.reference.coroutine.pseudo_keywords">Pseudo-keywords</a>
|
||||
</h5>
|
||||
<p>
|
||||
A coroutine is used in conjunction with certain "pseudo-keywords",
|
||||
which are implemented as macros. These macros are defined by a header file:
|
||||
</p>
|
||||
<pre class="programlisting">#include <asio/yield.hpp>
|
||||
</pre>
|
||||
<p>
|
||||
and may conversely be undefined as follows:
|
||||
</p>
|
||||
<pre class="programlisting">#include <asio/unyield.hpp>
|
||||
</pre>
|
||||
<p>
|
||||
<span class="bold"><strong>reenter</strong></span>
|
||||
</p>
|
||||
<p>
|
||||
The <code class="computeroutput">reenter</code> macro is used to define the body of a coroutine.
|
||||
It takes a single argument: a pointer or reference to a coroutine object.
|
||||
For example, if the base class is a coroutine object you may write:
|
||||
</p>
|
||||
<pre class="programlisting">reenter (this)
|
||||
{
|
||||
... coroutine body ...
|
||||
}
|
||||
</pre>
|
||||
<p>
|
||||
and if a data member or other variable you can write:
|
||||
</p>
|
||||
<pre class="programlisting">reenter (coro_)
|
||||
{
|
||||
... coroutine body ...
|
||||
}
|
||||
</pre>
|
||||
<p>
|
||||
When <code class="computeroutput">reenter</code> is executed at runtime, control jumps to the location
|
||||
of the last <code class="computeroutput">yield</code> or <code class="computeroutput">fork</code>.
|
||||
</p>
|
||||
<p>
|
||||
The coroutine body may also be a single statement, such as:
|
||||
</p>
|
||||
<pre class="programlisting">reenter (this) for (;;)
|
||||
{
|
||||
...
|
||||
}
|
||||
</pre>
|
||||
<p>
|
||||
<span class="bold"><strong>Limitation:</strong></span> The <code class="computeroutput">reenter</code> macro
|
||||
is implemented using a switch. This means that you must take care when using
|
||||
local variables within the coroutine body. The local variable is not allowed
|
||||
in a position where reentering the coroutine could bypass the variable definition.
|
||||
</p>
|
||||
<p>
|
||||
<span class="bold"><strong>yield <span class="emphasis"><em>statement</em></span></strong></span>
|
||||
</p>
|
||||
<p>
|
||||
This form of the <code class="computeroutput">yield</code> keyword is often used with asynchronous
|
||||
operations:
|
||||
</p>
|
||||
<pre class="programlisting">yield socket_->async_read_some(buffer(*buffer_), *this);
|
||||
</pre>
|
||||
<p>
|
||||
This divides into four logical steps:
|
||||
</p>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" type="disc">
|
||||
<li class="listitem">
|
||||
<code class="computeroutput">yield</code> saves the current state of the coroutine.
|
||||
</li>
|
||||
<li class="listitem">
|
||||
The statement initiates the asynchronous operation.
|
||||
</li>
|
||||
<li class="listitem">
|
||||
The resume point is defined immediately following the statement.
|
||||
</li>
|
||||
<li class="listitem">
|
||||
Control is transferred to the end of the coroutine body.
|
||||
</li>
|
||||
</ul></div>
|
||||
<p>
|
||||
When the asynchronous operation completes, the function object is invoked
|
||||
and <code class="computeroutput">reenter</code> causes control to transfer to the resume point.
|
||||
It is important to remember to carry the coroutine state forward with the
|
||||
asynchronous operation. In the above snippet, the current class is a function
|
||||
object object with a coroutine object as base class or data member.
|
||||
</p>
|
||||
<p>
|
||||
The statement may also be a compound statement, and this permits us to define
|
||||
local variables with limited scope:
|
||||
</p>
|
||||
<pre class="programlisting">yield
|
||||
{
|
||||
mutable_buffers_1 b = buffer(*buffer_);
|
||||
socket_->async_read_some(b, *this);
|
||||
}
|
||||
</pre>
|
||||
<p>
|
||||
<span class="bold"><strong>yield return <span class="emphasis"><em>expression</em></span> ;</strong></span>
|
||||
</p>
|
||||
<p>
|
||||
This form of <code class="computeroutput">yield</code> is often used in generators or coroutine-based
|
||||
parsers. For example, the function object:
|
||||
</p>
|
||||
<pre class="programlisting">struct interleave : coroutine
|
||||
{
|
||||
istream& is1;
|
||||
istream& is2;
|
||||
char operator()(char c)
|
||||
{
|
||||
reenter (this) for (;;)
|
||||
{
|
||||
yield return is1.get();
|
||||
yield return is2.get();
|
||||
}
|
||||
}
|
||||
};
|
||||
</pre>
|
||||
<p>
|
||||
defines a trivial coroutine that interleaves the characters from two input
|
||||
streams.
|
||||
</p>
|
||||
<p>
|
||||
This type of <code class="computeroutput">yield</code> divides into three logical steps:
|
||||
</p>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" type="disc">
|
||||
<li class="listitem">
|
||||
<code class="computeroutput">yield</code> saves the current state of the coroutine.
|
||||
</li>
|
||||
<li class="listitem">
|
||||
The resume point is defined immediately following the semicolon.
|
||||
</li>
|
||||
<li class="listitem">
|
||||
The value of the expression is returned from the function.
|
||||
</li>
|
||||
</ul></div>
|
||||
<p>
|
||||
<span class="bold"><strong>yield ;</strong></span>
|
||||
</p>
|
||||
<p>
|
||||
This form of <code class="computeroutput">yield</code> is equivalent to the following steps:
|
||||
</p>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" type="disc">
|
||||
<li class="listitem">
|
||||
<code class="computeroutput">yield</code> saves the current state of the coroutine.
|
||||
</li>
|
||||
<li class="listitem">
|
||||
The resume point is defined immediately following the semicolon.
|
||||
</li>
|
||||
<li class="listitem">
|
||||
Control is transferred to the end of the coroutine body.
|
||||
</li>
|
||||
</ul></div>
|
||||
<p>
|
||||
This form might be applied when coroutines are used for cooperative threading
|
||||
and scheduling is explicitly managed. For example:
|
||||
</p>
|
||||
<pre class="programlisting">struct task : coroutine
|
||||
{
|
||||
...
|
||||
void operator()()
|
||||
{
|
||||
reenter (this)
|
||||
{
|
||||
while (... not finished ...)
|
||||
{
|
||||
... do something ...
|
||||
yield;
|
||||
... do some more ...
|
||||
yield;
|
||||
}
|
||||
}
|
||||
}
|
||||
...
|
||||
};
|
||||
...
|
||||
task t1, t2;
|
||||
for (;;)
|
||||
{
|
||||
t1();
|
||||
t2();
|
||||
}
|
||||
</pre>
|
||||
<p>
|
||||
<span class="bold"><strong>yield break ;</strong></span>
|
||||
</p>
|
||||
<p>
|
||||
The final form of <code class="computeroutput">yield</code> is used to explicitly terminate the
|
||||
coroutine. This form is comprised of two steps:
|
||||
</p>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" type="disc">
|
||||
<li class="listitem">
|
||||
<code class="computeroutput">yield</code> sets the coroutine state to indicate termination.
|
||||
</li>
|
||||
<li class="listitem">
|
||||
Control is transferred to the end of the coroutine body.
|
||||
</li>
|
||||
</ul></div>
|
||||
<p>
|
||||
Once terminated, calls to <code class="computeroutput">is_complete()</code> return true and the
|
||||
coroutine cannot be reentered.
|
||||
</p>
|
||||
<p>
|
||||
Note that a coroutine may also be implicitly terminated if the coroutine
|
||||
body is exited without a yield, e.g. by return, throw or by running to the
|
||||
end of the body.
|
||||
</p>
|
||||
<p>
|
||||
<span class="bold"><strong>fork <span class="emphasis"><em>statement</em></span></strong></span>
|
||||
</p>
|
||||
<p>
|
||||
The <code class="computeroutput">fork</code> pseudo-keyword is used when "forking" a coroutine,
|
||||
i.e. splitting it into two (or more) copies. One use of <code class="computeroutput">fork</code>
|
||||
is in a server, where a new coroutine is created to handle each client connection:
|
||||
</p>
|
||||
<pre class="programlisting">reenter (this)
|
||||
{
|
||||
do
|
||||
{
|
||||
socket_.reset(new tcp::socket(my_context_));
|
||||
yield acceptor->async_accept(*socket_, *this);
|
||||
fork server(*this)();
|
||||
} while (is_parent());
|
||||
... client-specific handling follows ...
|
||||
}
|
||||
</pre>
|
||||
<p>
|
||||
The logical steps involved in a <code class="computeroutput">fork</code> are:
|
||||
</p>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" type="disc">
|
||||
<li class="listitem">
|
||||
<code class="computeroutput">fork</code> saves the current state of the coroutine.
|
||||
</li>
|
||||
<li class="listitem">
|
||||
The statement creates a copy of the coroutine and either executes it
|
||||
immediately or schedules it for later execution.
|
||||
</li>
|
||||
<li class="listitem">
|
||||
The resume point is defined immediately following the semicolon.
|
||||
</li>
|
||||
<li class="listitem">
|
||||
For the "parent", control immediately continues from the next
|
||||
line.
|
||||
</li>
|
||||
</ul></div>
|
||||
<p>
|
||||
The functions <code class="computeroutput">is_parent()</code> and <code class="computeroutput">is_child()</code> can be
|
||||
used to differentiate between parent and child. You would use these functions
|
||||
to alter subsequent control flow.
|
||||
</p>
|
||||
<p>
|
||||
Note that <code class="computeroutput">fork</code> doesn't do the actual forking by itself. It is
|
||||
the application's responsibility to create a clone of the coroutine and call
|
||||
it. The clone can be called immediately, as above, or scheduled for delayed
|
||||
execution using something like <a class="link" href="post.html" title="post"><code class="computeroutput">post</code></a>.
|
||||
</p>
|
||||
<h5>
|
||||
<a name="asio.reference.coroutine.h2"></a>
|
||||
<span><a name="asio.reference.coroutine.alternate_macro_names"></a></span><a class="link" href="coroutine.html#asio.reference.coroutine.alternate_macro_names">Alternate
|
||||
macro names</a>
|
||||
</h5>
|
||||
<p>
|
||||
If preferred, an application can use macro names that follow a more typical
|
||||
naming convention, rather than the pseudo-keywords. These are:
|
||||
</p>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" type="disc">
|
||||
<li class="listitem">
|
||||
<code class="computeroutput">ASIO_CORO_REENTER</code> instead of <code class="computeroutput">reenter</code>
|
||||
</li>
|
||||
<li class="listitem">
|
||||
<code class="computeroutput">ASIO_CORO_YIELD</code> instead of <code class="computeroutput">yield</code>
|
||||
</li>
|
||||
<li class="listitem">
|
||||
<code class="computeroutput">ASIO_CORO_FORK</code> instead of <code class="computeroutput">fork</code>
|
||||
</li>
|
||||
</ul></div>
|
||||
<h5>
|
||||
<a name="asio.reference.coroutine.h3"></a>
|
||||
<span><a name="asio.reference.coroutine.requirements"></a></span><a class="link" href="coroutine.html#asio.reference.coroutine.requirements">Requirements</a>
|
||||
</h5>
|
||||
<p>
|
||||
<span class="emphasis"><em>Header: </em></span><code class="literal">asio/coroutine.hpp</code>
|
||||
</p>
|
||||
<p>
|
||||
<span class="emphasis"><em>Convenience header: </em></span><code class="literal">asio.hpp</code>
|
||||
</p>
|
||||
</div>
|
||||
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
|
||||
<td align="left"></td>
|
||||
<td align="right"><div class="copyright-footer">Copyright © 2003-2020 Christopher M.
|
||||
Kohlhoff<p>
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
|
||||
</p>
|
||||
</div></td>
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="const_buffers_1/value_type.html"><img src="../../prev.png" alt="Prev"></a><a accesskey="u" href="../reference.html"><img src="../../up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../home.png" alt="Home"></a><a accesskey="n" href="coroutine/coroutine.html"><img src="../../next.png" alt="Next"></a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
Reference in new issue
Block a user