Sophie

Sophie

distrib > Mageia > 6 > armv5tl > by-pkgid > 37eb773c4f50677290a7937043b43933 > files > 4572

boost-devel-doc-1.60.0-6.1.mga6.noarch.rpm

<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">&lt;</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">&gt;</span>
</pre>
<p>
        and may conversely be undefined as follows:
      </p>
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</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">&gt;</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">-&gt;</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">-&gt;</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">&amp;</span> <span class="identifier">is1</span><span class="special">;</span>
  <span class="identifier">istream</span><span class="special">&amp;</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">-&gt;</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 &#169; 2003-2015 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>