diff options
author | Chanho Park <chanho61.park@samsung.com> | 2014-12-11 18:55:56 +0900 |
---|---|---|
committer | Chanho Park <chanho61.park@samsung.com> | 2014-12-11 18:55:56 +0900 |
commit | 08c1e93fa36a49f49325a07fe91ff92c964c2b6c (patch) | |
tree | 7a7053ceb8874b28ec4b868d4c49b500008a102e /doc/html/boost_asio/reference/coroutine.html | |
parent | bb4dd8289b351fae6b55e303f189127a394a1edd (diff) | |
download | boost-08c1e93fa36a49f49325a07fe91ff92c964c2b6c.tar.gz boost-08c1e93fa36a49f49325a07fe91ff92c964c2b6c.tar.bz2 boost-08c1e93fa36a49f49325a07fe91ff92c964c2b6c.zip |
Imported Upstream version 1.57.0upstream/1.57.0
Diffstat (limited to 'doc/html/boost_asio/reference/coroutine.html')
-rw-r--r-- | doc/html/boost_asio/reference/coroutine.html | 454 |
1 files changed, 454 insertions, 0 deletions
diff --git a/doc/html/boost_asio/reference/coroutine.html b/doc/html/boost_asio/reference/coroutine.html new file mode 100644 index 0000000000..d8603693f1 --- /dev/null +++ b/doc/html/boost_asio/reference/coroutine.html @@ -0,0 +1,454 @@ +<html> +<head> +<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII"> +<title>coroutine</title> +<link rel="stylesheet" href="../../../../doc/src/boostbook.css" type="text/css"> +<meta name="generator" content="DocBook XSL Stylesheets V1.78.1"> +<link rel="home" href="../../boost_asio.html" title="Boost.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="Boost C++ Libraries" width="277" height="86" src="../../../../boost.png"></td> +<td align="center"><a href="../../../../index.html">Home</a></td> +<td align="center"><a href="../../../../libs/libraries.htm">Libraries</a></td> +<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td> +<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td> +<td align="center"><a href="../../../../more/index.htm">More</a></td> +</tr></table> +<hr> +<div class="spirit-nav"> +<a accesskey="p" href="const_buffers_1/value_type.html"><img src="../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../reference.html"><img src="../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../boost_asio.html"><img src="../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="coroutine/coroutine.html"><img src="../../../../doc/src/images/next.png" alt="Next"></a> +</div> +<div class="section"> +<div class="titlepage"><div><div><h3 class="title"> +<a name="boost_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"><span class="keyword">class</span> <span class="identifier">coroutine</span> +</pre> +<h5> +<a name="boost_asio.reference.coroutine.h0"></a> + <span class="phrase"><a name="boost_asio.reference.coroutine.member_functions"></a></span><a class="link" href="coroutine.html#boost_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> + </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"><span class="identifier">coroutine</span></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"><span class="keyword">class</span> <span class="identifier">session</span> <span class="special">:</span> <span class="identifier">coroutine</span> +<span class="special">{</span> + <span class="special">...</span> +<span class="special">};</span> +</pre> +<p> + or as a data member: + </p> +<pre class="programlisting"><span class="keyword">class</span> <span class="identifier">session</span> +<span class="special">{</span> + <span class="special">...</span> + <span class="identifier">coroutine</span> <span class="identifier">coro_</span><span class="special">;</span> +<span class="special">};</span> +</pre> +<p> + or even bound in as a function argument using lambdas or <code class="computeroutput"><span class="identifier">bind</span><span class="special">()</span></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="boost_asio.reference.coroutine.h1"></a> + <span class="phrase"><a name="boost_asio.reference.coroutine.pseudo_keywords"></a></span><a class="link" href="coroutine.html#boost_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"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">asio</span><span class="special">/</span><span class="identifier">yield</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> +</pre> +<p> + and may conversely be undefined as follows: + </p> +<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">asio</span><span class="special">/</span><span class="identifier">unyield</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> +</pre> +<p> + <span class="bold"><strong>reenter</strong></span> + </p> +<p> + The <code class="computeroutput"><span class="identifier">reenter</span></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"><span class="identifier">reenter</span> <span class="special">(</span><span class="keyword">this</span><span class="special">)</span> +<span class="special">{</span> + <span class="special">...</span> <span class="identifier">coroutine</span> <span class="identifier">body</span> <span class="special">...</span> +<span class="special">}</span> +</pre> +<p> + and if a data member or other variable you can write: + </p> +<pre class="programlisting"><span class="identifier">reenter</span> <span class="special">(</span><span class="identifier">coro_</span><span class="special">)</span> +<span class="special">{</span> + <span class="special">...</span> <span class="identifier">coroutine</span> <span class="identifier">body</span> <span class="special">...</span> +<span class="special">}</span> +</pre> +<p> + When <code class="computeroutput"><span class="identifier">reenter</span></code> is executed + at runtime, control jumps to the location of the last <code class="computeroutput"><span class="identifier">yield</span></code> + or <code class="computeroutput"><span class="identifier">fork</span></code>. + </p> +<p> + The coroutine body may also be a single statement, such as: + </p> +<pre class="programlisting"><span class="identifier">reenter</span> <span class="special">(</span><span class="keyword">this</span><span class="special">)</span> <span class="keyword">for</span> <span class="special">(;;)</span> +<span class="special">{</span> + <span class="special">...</span> +<span class="special">}</span> +</pre> +<p> + <span class="bold"><strong>Limitation:</strong></span> The <code class="computeroutput"><span class="identifier">reenter</span></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"><span class="identifier">yield</span></code> keyword + is often used with asynchronous operations: + </p> +<pre class="programlisting"><span class="identifier">yield</span> <span class="identifier">socket_</span><span class="special">-></span><span class="identifier">async_read_some</span><span class="special">(</span><span class="identifier">buffer</span><span class="special">(*</span><span class="identifier">buffer_</span><span class="special">),</span> <span class="special">*</span><span class="keyword">this</span><span class="special">);</span> +</pre> +<p> + This divides into four logical steps: + </p> +<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "> +<li class="listitem"> + <code class="computeroutput"><span class="identifier">yield</span></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"><span class="identifier">reenter</span></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"><span class="identifier">yield</span> +<span class="special">{</span> + <span class="identifier">mutable_buffers_1</span> <span class="identifier">b</span> <span class="special">=</span> <span class="identifier">buffer</span><span class="special">(*</span><span class="identifier">buffer_</span><span class="special">);</span> + <span class="identifier">socket_</span><span class="special">-></span><span class="identifier">async_read_some</span><span class="special">(</span><span class="identifier">b</span><span class="special">,</span> <span class="special">*</span><span class="keyword">this</span><span class="special">);</span> +<span class="special">}</span> +</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"><span class="identifier">yield</span></code> is often + used in generators or coroutine-based parsers. For example, the function + object: + </p> +<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">interleave</span> <span class="special">:</span> <span class="identifier">coroutine</span> +<span class="special">{</span> + <span class="identifier">istream</span><span class="special">&</span> <span class="identifier">is1</span><span class="special">;</span> + <span class="identifier">istream</span><span class="special">&</span> <span class="identifier">is2</span><span class="special">;</span> + <span class="keyword">char</span> <span class="keyword">operator</span><span class="special">()(</span><span class="keyword">char</span> <span class="identifier">c</span><span class="special">)</span> + <span class="special">{</span> + <span class="identifier">reenter</span> <span class="special">(</span><span class="keyword">this</span><span class="special">)</span> <span class="keyword">for</span> <span class="special">(;;)</span> + <span class="special">{</span> + <span class="identifier">yield</span> <span class="keyword">return</span> <span class="identifier">is1</span><span class="special">.</span><span class="identifier">get</span><span class="special">();</span> + <span class="identifier">yield</span> <span class="keyword">return</span> <span class="identifier">is2</span><span class="special">.</span><span class="identifier">get</span><span class="special">();</span> + <span class="special">}</span> + <span class="special">}</span> +<span class="special">};</span> +</pre> +<p> + defines a trivial coroutine that interleaves the characters from two input + streams. + </p> +<p> + This type of <code class="computeroutput"><span class="identifier">yield</span></code> divides + into three logical steps: + </p> +<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "> +<li class="listitem"> + <code class="computeroutput"><span class="identifier">yield</span></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"><span class="identifier">yield</span></code> is equivalent + to the following steps: + </p> +<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "> +<li class="listitem"> + <code class="computeroutput"><span class="identifier">yield</span></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"><span class="keyword">struct</span> <span class="identifier">task</span> <span class="special">:</span> <span class="identifier">coroutine</span> +<span class="special">{</span> + <span class="special">...</span> + <span class="keyword">void</span> <span class="keyword">operator</span><span class="special">()()</span> + <span class="special">{</span> + <span class="identifier">reenter</span> <span class="special">(</span><span class="keyword">this</span><span class="special">)</span> + <span class="special">{</span> + <span class="keyword">while</span> <span class="special">(...</span> <span class="keyword">not</span> <span class="identifier">finished</span> <span class="special">...)</span> + <span class="special">{</span> + <span class="special">...</span> <span class="keyword">do</span> <span class="identifier">something</span> <span class="special">...</span> + <span class="identifier">yield</span><span class="special">;</span> + <span class="special">...</span> <span class="keyword">do</span> <span class="identifier">some</span> <span class="identifier">more</span> <span class="special">...</span> + <span class="identifier">yield</span><span class="special">;</span> + <span class="special">}</span> + <span class="special">}</span> + <span class="special">}</span> + <span class="special">...</span> +<span class="special">};</span> +<span class="special">...</span> +<span class="identifier">task</span> <span class="identifier">t1</span><span class="special">,</span> <span class="identifier">t2</span><span class="special">;</span> +<span class="keyword">for</span> <span class="special">(;;)</span> +<span class="special">{</span> + <span class="identifier">t1</span><span class="special">();</span> + <span class="identifier">t2</span><span class="special">();</span> +<span class="special">}</span> +</pre> +<p> + <span class="bold"><strong>yield break ;</strong></span> + </p> +<p> + The final form of <code class="computeroutput"><span class="identifier">yield</span></code> is + used to explicitly terminate the coroutine. This form is comprised of two + steps: + </p> +<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "> +<li class="listitem"> + <code class="computeroutput"><span class="identifier">yield</span></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"><span class="identifier">is_complete</span><span class="special">()</span></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"><span class="identifier">fork</span></code> pseudo-keyword is + used when "forking" a coroutine, i.e. splitting it into two (or + more) copies. One use of <code class="computeroutput"><span class="identifier">fork</span></code> + is in a server, where a new coroutine is created to handle each client connection: + </p> +<pre class="programlisting"><span class="identifier">reenter</span> <span class="special">(</span><span class="keyword">this</span><span class="special">)</span> +<span class="special">{</span> + <span class="keyword">do</span> + <span class="special">{</span> + <span class="identifier">socket_</span><span class="special">.</span><span class="identifier">reset</span><span class="special">(</span><span class="keyword">new</span> <span class="identifier">tcp</span><span class="special">::</span><span class="identifier">socket</span><span class="special">(</span><span class="identifier">io_service_</span><span class="special">));</span> + <span class="identifier">yield</span> <span class="identifier">acceptor</span><span class="special">-></span><span class="identifier">async_accept</span><span class="special">(*</span><span class="identifier">socket_</span><span class="special">,</span> <span class="special">*</span><span class="keyword">this</span><span class="special">);</span> + <span class="identifier">fork</span> <span class="identifier">server</span><span class="special">(*</span><span class="keyword">this</span><span class="special">)();</span> + <span class="special">}</span> <span class="keyword">while</span> <span class="special">(</span><span class="identifier">is_parent</span><span class="special">());</span> + <span class="special">...</span> <span class="identifier">client</span><span class="special">-</span><span class="identifier">specific</span> <span class="identifier">handling</span> <span class="identifier">follows</span> <span class="special">...</span> +<span class="special">}</span> +</pre> +<p> + The logical steps involved in a <code class="computeroutput"><span class="identifier">fork</span></code> + are: + </p> +<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "> +<li class="listitem"> + <code class="computeroutput"><span class="identifier">fork</span></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"><span class="identifier">is_parent</span><span class="special">()</span></code> + and <code class="computeroutput"><span class="identifier">is_child</span><span class="special">()</span></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"><span class="identifier">fork</span></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 <code class="computeroutput"><span class="identifier">io_service</span><span class="special">::</span><span class="identifier">post</span><span class="special">()</span></code>. + </p> +<h5> +<a name="boost_asio.reference.coroutine.h2"></a> + <span class="phrase"><a name="boost_asio.reference.coroutine.alternate_macro_names"></a></span><a class="link" href="coroutine.html#boost_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" style="list-style-type: disc; "> +<li class="listitem"> + <code class="computeroutput"><span class="identifier">BOOST_ASIO_CORO_REENTER</span></code> + instead of <code class="computeroutput"><span class="identifier">reenter</span></code> + </li> +<li class="listitem"> + <code class="computeroutput"><span class="identifier">BOOST_ASIO_CORO_YIELD</span></code> + instead of <code class="computeroutput"><span class="identifier">yield</span></code> + </li> +<li class="listitem"> + <code class="computeroutput"><span class="identifier">BOOST_ASIO_CORO_FORK</span></code> + instead of <code class="computeroutput"><span class="identifier">fork</span></code> + </li> +</ul></div> +<h5> +<a name="boost_asio.reference.coroutine.h3"></a> + <span class="phrase"><a name="boost_asio.reference.coroutine.requirements"></a></span><a class="link" href="coroutine.html#boost_asio.reference.coroutine.requirements">Requirements</a> + </h5> +<p> + <span class="emphasis"><em>Header: </em></span><code class="literal">boost/asio/coroutine.hpp</code> + </p> +<p> + <span class="emphasis"><em>Convenience header: </em></span><code class="literal">boost/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-2014 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="../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../reference.html"><img src="../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../boost_asio.html"><img src="../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="coroutine/coroutine.html"><img src="../../../../doc/src/images/next.png" alt="Next"></a> +</div> +</body> +</html> |