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 <boost/asio/yield.hpp> 143</pre> 144<p> 145 and may conversely be undefined as follows: 146 </p> 147<pre class="programlisting">#include <boost/asio/unyield.hpp> 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_->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_->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& is1; 241 istream& 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->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