• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1<html>
2<head>
3<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
4<title>coroutine</title>
5<link rel="stylesheet" href="../../../../doc/src/boostbook.css" type="text/css">
6<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
7<link rel="home" href="../../boost_asio.html" title="Boost.Asio">
8<link rel="up" href="../reference.html" title="Reference">
9<link rel="prev" href="const_buffers_1/value_type.html" title="const_buffers_1::value_type">
10<link rel="next" href="coroutine/coroutine.html" title="coroutine::coroutine">
11</head>
12<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
13<table cellpadding="2" width="100%"><tr>
14<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../boost.png"></td>
15<td align="center"><a href="../../../../index.html">Home</a></td>
16<td align="center"><a href="../../../../libs/libraries.htm">Libraries</a></td>
17<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
18<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
19<td align="center"><a href="../../../../more/index.htm">More</a></td>
20</tr></table>
21<hr>
22<div class="spirit-nav">
23<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>
24</div>
25<div class="section">
26<div class="titlepage"><div><div><h3 class="title">
27<a name="boost_asio.reference.coroutine"></a><a class="link" href="coroutine.html" title="coroutine">coroutine</a>
28</h3></div></div></div>
29<p>
30        Provides support for implementing stackless coroutines.
31      </p>
32<pre class="programlisting">class coroutine
33</pre>
34<h5>
35<a name="boost_asio.reference.coroutine.h0"></a>
36        <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
37        Functions</a>
38      </h5>
39<div class="informaltable"><table class="table">
40<colgroup>
41<col>
42<col>
43</colgroup>
44<thead><tr>
45<th>
46                <p>
47                  Name
48                </p>
49              </th>
50<th>
51                <p>
52                  Description
53                </p>
54              </th>
55</tr></thead>
56<tbody>
57<tr>
58<td>
59                <p>
60                  <a class="link" href="coroutine/coroutine.html" title="coroutine::coroutine"><span class="bold"><strong>coroutine</strong></span></a> <span class="silver">[constructor]</span>
61                </p>
62              </td>
63<td>
64                <p>
65                  Constructs a coroutine in its initial state.
66                </p>
67              </td>
68</tr>
69<tr>
70<td>
71                <p>
72                  <a class="link" href="coroutine/is_child.html" title="coroutine::is_child"><span class="bold"><strong>is_child</strong></span></a>
73                </p>
74              </td>
75<td>
76                <p>
77                  Returns true if the coroutine is the child of a fork.
78                </p>
79              </td>
80</tr>
81<tr>
82<td>
83                <p>
84                  <a class="link" href="coroutine/is_complete.html" title="coroutine::is_complete"><span class="bold"><strong>is_complete</strong></span></a>
85                </p>
86              </td>
87<td>
88                <p>
89                  Returns true if the coroutine has reached its terminal state.
90                </p>
91              </td>
92</tr>
93<tr>
94<td>
95                <p>
96                  <a class="link" href="coroutine/is_parent.html" title="coroutine::is_parent"><span class="bold"><strong>is_parent</strong></span></a>
97                </p>
98              </td>
99<td>
100                <p>
101                  Returns true if the coroutine is the parent of a fork.
102                </p>
103              </td>
104</tr>
105</tbody>
106</table></div>
107<p>
108        The <code class="computeroutput">coroutine</code> class may be used to implement stackless coroutines.
109        The class itself is used to store the current state of the coroutine.
110      </p>
111<p>
112        Coroutines are copy-constructible and assignable, and the space overhead
113        is a single int. They can be used as a base class:
114      </p>
115<pre class="programlisting">class session : coroutine
116{
117  ...
118};
119</pre>
120<p>
121        or as a data member:
122      </p>
123<pre class="programlisting">class session
124{
125  ...
126  coroutine coro_;
127};
128</pre>
129<p>
130        or even bound in as a function argument using lambdas or <code class="computeroutput">bind()</code>.
131        The important thing is that as the application maintains a copy of the object
132        for as long as the coroutine must be kept alive.
133      </p>
134<h5>
135<a name="boost_asio.reference.coroutine.h1"></a>
136        <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>
137      </h5>
138<p>
139        A coroutine is used in conjunction with certain "pseudo-keywords",
140        which are implemented as macros. These macros are defined by a header file:
141      </p>
142<pre class="programlisting">#include &lt;boost/asio/yield.hpp&gt;
143</pre>
144<p>
145        and may conversely be undefined as follows:
146      </p>
147<pre class="programlisting">#include &lt;boost/asio/unyield.hpp&gt;
148</pre>
149<p>
150        <span class="bold"><strong>reenter</strong></span>
151      </p>
152<p>
153        The <code class="computeroutput">reenter</code> macro is used to define the body of a coroutine.
154        It takes a single argument: a pointer or reference to a coroutine object.
155        For example, if the base class is a coroutine object you may write:
156      </p>
157<pre class="programlisting">reenter (this)
158{
159  ... coroutine body ...
160}
161</pre>
162<p>
163        and if a data member or other variable you can write:
164      </p>
165<pre class="programlisting">reenter (coro_)
166{
167  ... coroutine body ...
168}
169</pre>
170<p>
171        When <code class="computeroutput">reenter</code> is executed at runtime, control jumps to the location
172        of the last <code class="computeroutput">yield</code> or <code class="computeroutput">fork</code>.
173      </p>
174<p>
175        The coroutine body may also be a single statement, such as:
176      </p>
177<pre class="programlisting">reenter (this) for (;;)
178{
179  ...
180}
181</pre>
182<p>
183        <span class="bold"><strong>Limitation:</strong></span> The <code class="computeroutput">reenter</code> macro
184        is implemented using a switch. This means that you must take care when using
185        local variables within the coroutine body. The local variable is not allowed
186        in a position where reentering the coroutine could bypass the variable definition.
187      </p>
188<p>
189        <span class="bold"><strong>yield <span class="emphasis"><em>statement</em></span></strong></span>
190      </p>
191<p>
192        This form of the <code class="computeroutput">yield</code> keyword is often used with asynchronous
193        operations:
194      </p>
195<pre class="programlisting">yield socket_-&gt;async_read_some(buffer(*buffer_), *this);
196</pre>
197<p>
198        This divides into four logical steps:
199      </p>
200<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
201<li class="listitem">
202            <code class="computeroutput">yield</code> saves the current state of the coroutine.
203          </li>
204<li class="listitem">
205            The statement initiates the asynchronous operation.
206          </li>
207<li class="listitem">
208            The resume point is defined immediately following the statement.
209          </li>
210<li class="listitem">
211            Control is transferred to the end of the coroutine body.
212          </li>
213</ul></div>
214<p>
215        When the asynchronous operation completes, the function object is invoked
216        and <code class="computeroutput">reenter</code> causes control to transfer to the resume point.
217        It is important to remember to carry the coroutine state forward with the
218        asynchronous operation. In the above snippet, the current class is a function
219        object object with a coroutine object as base class or data member.
220      </p>
221<p>
222        The statement may also be a compound statement, and this permits us to define
223        local variables with limited scope:
224      </p>
225<pre class="programlisting">yield
226{
227  mutable_buffers_1 b = buffer(*buffer_);
228  socket_-&gt;async_read_some(b, *this);
229}
230</pre>
231<p>
232        <span class="bold"><strong>yield return <span class="emphasis"><em>expression</em></span> ;</strong></span>
233      </p>
234<p>
235        This form of <code class="computeroutput">yield</code> is often used in generators or coroutine-based
236        parsers. For example, the function object:
237      </p>
238<pre class="programlisting">struct interleave : coroutine
239{
240  istream&amp; is1;
241  istream&amp; is2;
242  char operator()(char c)
243  {
244    reenter (this) for (;;)
245    {
246      yield return is1.get();
247      yield return is2.get();
248    }
249  }
250};
251</pre>
252<p>
253        defines a trivial coroutine that interleaves the characters from two input
254        streams.
255      </p>
256<p>
257        This type of <code class="computeroutput">yield</code> divides into three logical steps:
258      </p>
259<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
260<li class="listitem">
261            <code class="computeroutput">yield</code> saves the current state of the coroutine.
262          </li>
263<li class="listitem">
264            The resume point is defined immediately following the semicolon.
265          </li>
266<li class="listitem">
267            The value of the expression is returned from the function.
268          </li>
269</ul></div>
270<p>
271        <span class="bold"><strong>yield ;</strong></span>
272      </p>
273<p>
274        This form of <code class="computeroutput">yield</code> is equivalent to the following steps:
275      </p>
276<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
277<li class="listitem">
278            <code class="computeroutput">yield</code> saves the current state of the coroutine.
279          </li>
280<li class="listitem">
281            The resume point is defined immediately following the semicolon.
282          </li>
283<li class="listitem">
284            Control is transferred to the end of the coroutine body.
285          </li>
286</ul></div>
287<p>
288        This form might be applied when coroutines are used for cooperative threading
289        and scheduling is explicitly managed. For example:
290      </p>
291<pre class="programlisting">struct task : coroutine
292{
293  ...
294  void operator()()
295  {
296    reenter (this)
297    {
298      while (... not finished ...)
299      {
300        ... do something ...
301        yield;
302        ... do some more ...
303        yield;
304      }
305    }
306  }
307  ...
308};
309...
310task t1, t2;
311for (;;)
312{
313  t1();
314  t2();
315}
316</pre>
317<p>
318        <span class="bold"><strong>yield break ;</strong></span>
319      </p>
320<p>
321        The final form of <code class="computeroutput">yield</code> is used to explicitly terminate the
322        coroutine. This form is comprised of two steps:
323      </p>
324<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
325<li class="listitem">
326            <code class="computeroutput">yield</code> sets the coroutine state to indicate termination.
327          </li>
328<li class="listitem">
329            Control is transferred to the end of the coroutine body.
330          </li>
331</ul></div>
332<p>
333        Once terminated, calls to <code class="computeroutput">is_complete()</code> return true and the
334        coroutine cannot be reentered.
335      </p>
336<p>
337        Note that a coroutine may also be implicitly terminated if the coroutine
338        body is exited without a yield, e.g. by return, throw or by running to the
339        end of the body.
340      </p>
341<p>
342        <span class="bold"><strong>fork <span class="emphasis"><em>statement</em></span></strong></span>
343      </p>
344<p>
345        The <code class="computeroutput">fork</code> pseudo-keyword is used when "forking" a coroutine,
346        i.e. splitting it into two (or more) copies. One use of <code class="computeroutput">fork</code>
347        is in a server, where a new coroutine is created to handle each client connection:
348      </p>
349<pre class="programlisting">reenter (this)
350{
351  do
352  {
353    socket_.reset(new tcp::socket(my_context_));
354    yield acceptor-&gt;async_accept(*socket_, *this);
355    fork server(*this)();
356  } while (is_parent());
357  ... client-specific handling follows ...
358}
359</pre>
360<p>
361        The logical steps involved in a <code class="computeroutput">fork</code> are:
362      </p>
363<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
364<li class="listitem">
365            <code class="computeroutput">fork</code> saves the current state of the coroutine.
366          </li>
367<li class="listitem">
368            The statement creates a copy of the coroutine and either executes it
369            immediately or schedules it for later execution.
370          </li>
371<li class="listitem">
372            The resume point is defined immediately following the semicolon.
373          </li>
374<li class="listitem">
375            For the "parent", control immediately continues from the next
376            line.
377          </li>
378</ul></div>
379<p>
380        The functions <code class="computeroutput">is_parent()</code> and <code class="computeroutput">is_child()</code> can be
381        used to differentiate between parent and child. You would use these functions
382        to alter subsequent control flow.
383      </p>
384<p>
385        Note that <code class="computeroutput">fork</code> doesn't do the actual forking by itself. It is
386        the application's responsibility to create a clone of the coroutine and call
387        it. The clone can be called immediately, as above, or scheduled for delayed
388        execution using something like <a class="link" href="post.html" title="post"><code class="computeroutput">post</code></a>.
389      </p>
390<h5>
391<a name="boost_asio.reference.coroutine.h2"></a>
392        <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
393        macro names</a>
394      </h5>
395<p>
396        If preferred, an application can use macro names that follow a more typical
397        naming convention, rather than the pseudo-keywords. These are:
398      </p>
399<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
400<li class="listitem">
401            <code class="computeroutput">BOOST_ASIO_CORO_REENTER</code> instead of <code class="computeroutput">reenter</code>
402          </li>
403<li class="listitem">
404            <code class="computeroutput">BOOST_ASIO_CORO_YIELD</code> instead of <code class="computeroutput">yield</code>
405          </li>
406<li class="listitem">
407            <code class="computeroutput">BOOST_ASIO_CORO_FORK</code> instead of <code class="computeroutput">fork</code>
408          </li>
409</ul></div>
410<h5>
411<a name="boost_asio.reference.coroutine.h3"></a>
412        <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>
413      </h5>
414<p>
415        <span class="emphasis"><em>Header: </em></span><code class="literal">boost/asio/coroutine.hpp</code>
416      </p>
417<p>
418        <span class="emphasis"><em>Convenience header: </em></span><code class="literal">boost/asio.hpp</code>
419      </p>
420</div>
421<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
422<td align="left"></td>
423<td align="right"><div class="copyright-footer">Copyright © 2003-2020 Christopher M.
424      Kohlhoff<p>
425        Distributed under the Boost Software License, Version 1.0. (See accompanying
426        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>)
427      </p>
428</div></td>
429</tr></table>
430<hr>
431<div class="spirit-nav">
432<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>
433</div>
434</body>
435</html>
436