﻿<!DOCTYPE HTML>
<!DOCTYPE html PUBLIC "" ""><HTML><HEAD><META content="IE=11.0000" 
http-equiv="X-UA-Compatible">
 <TITLE>D0054_ReportsFromTheField</TITLE> 
<META http-equiv="Content-Type" content="text/html; charset=utf-8"> 
<STYLE type="text/css">
/* GitHub stylesheet for MarkdownPad (http://markdownpad.com) */
/* Author: Nicolas Hery - http://nicolashery.com */
/* Version: b13fe65ca28d2e568c6ed5d7f06581183df8f2ff */
/* Source: https://github.com/nicolahery/markdownpad-github */

/* RESET
=============================================================================*/

html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, b, u, i, center, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td, article, aside, canvas, details, embed, figure, figcaption, footer, header, hgroup, menu, nav, output, ruby, section, summary, time, mark, audio, video {
  margin: 0;
  padding: 0;
  border: 0;
}

/* BODY
=============================================================================*/

body {
  font-family: Helvetica, arial, freesans, clean, sans-serif;
  font-size: 14px;
  line-height: 1.6;
  color: #333;
  background-color: #fff;
  padding: 20px;
  max-width: 960px;
  margin: 0 auto;
}

body>*:first-child {
  margin-top: 0 !important;
}

body>*:last-child {
  margin-bottom: 0 !important;
}

/* BLOCKS
=============================================================================*/

p, blockquote, ul, ol, dl, table, pre {
  margin: 15px 0;
}

/* HEADERS
=============================================================================*/

h1, h2, h3, h4, h5, h6 {
  margin: 20px 0 10px;
  padding: 0;
  font-weight: bold;
  -webkit-font-smoothing: antialiased;
}

h1 tt, h1 code, h2 tt, h2 code, h3 tt, h3 code, h4 tt, h4 code, h5 tt, h5 code, h6 tt, h6 code {
  font-size: inherit;
}

h1 {
  font-size: 28px;
  color: #000;
}

h2 {
  font-size: 24px;
  border-bottom: 1px solid #ccc;
  color: #000;
}

h3 {
  font-size: 18px;
}

h4 {
  font-size: 16px;
}

h5 {
  font-size: 14px;
}

h6 {
  color: #777;
  font-size: 14px;
}

body>h2:first-child, body>h1:first-child, body>h1:first-child+h2, body>h3:first-child, body>h4:first-child, body>h5:first-child, body>h6:first-child {
  margin-top: 0;
  padding-top: 0;
}

a:first-child h1, a:first-child h2, a:first-child h3, a:first-child h4, a:first-child h5, a:first-child h6 {
  margin-top: 0;
  padding-top: 0;
}

h1+p, h2+p, h3+p, h4+p, h5+p, h6+p {
  margin-top: 10px;
}

/* LINKS
=============================================================================*/

a {
  color: #4183C4;
  text-decoration: none;
}

a:hover {
  text-decoration: underline;
}

/* LISTS
=============================================================================*/

ul, ol {
  padding-left: 30px;
}

ul li > :first-child, 
ol li > :first-child, 
ul li ul:first-of-type, 
ol li ol:first-of-type, 
ul li ol:first-of-type, 
ol li ul:first-of-type {
  margin-top: 0px;
}

ul ul, ul ol, ol ol, ol ul {
  margin-bottom: 0;
}

dl {
  padding: 0;
}

dl dt {
  font-size: 14px;
  font-weight: bold;
  font-style: italic;
  padding: 0;
  margin: 15px 0 5px;
}

dl dt:first-child {
  padding: 0;
}

dl dt>:first-child {
  margin-top: 0px;
}

dl dt>:last-child {
  margin-bottom: 0px;
}

dl dd {
  margin: 0 0 15px;
  padding: 0 15px;
}

dl dd>:first-child {
  margin-top: 0px;
}

dl dd>:last-child {
  margin-bottom: 0px;
}

/* CODE
=============================================================================*/

pre, code, tt {
  font-size: 12px;
  font-family: Consolas, "Liberation Mono", Courier, monospace;
}

code, tt {
  margin: 0 0px;
  padding: 0px 0px;
  white-space: nowrap;
  border: 1px solid #eaeaea;
  background-color: #f8f8f8;
  border-radius: 3px;
}

pre>code {
  margin: 0;
  padding: 0;
  white-space: pre;
  border: none;
  background: transparent;
}

pre {
  background-color: #f8f8f8;
  border: 1px solid #ccc;
  font-size: 13px;
  line-height: 19px;
  overflow: auto;
  padding: 6px 10px;
  border-radius: 3px;
}

pre code, pre tt {
  background-color: transparent;
  border: none;
}

kbd {
    -moz-border-bottom-colors: none;
    -moz-border-left-colors: none;
    -moz-border-right-colors: none;
    -moz-border-top-colors: none;
    background-color: #DDDDDD;
    background-image: linear-gradient(#F1F1F1, #DDDDDD);
    background-repeat: repeat-x;
    border-color: #DDDDDD #CCCCCC #CCCCCC #DDDDDD;
    border-image: none;
    border-radius: 2px 2px 2px 2px;
    border-style: solid;
    border-width: 1px;
    font-family: "Helvetica Neue",Helvetica,Arial,sans-serif;
    line-height: 10px;
    padding: 1px 4px;
}

/* QUOTES
=============================================================================*/

blockquote {
  border-left: 4px solid #DDD;
  padding: 0 15px;
  color: #777;
}

blockquote>:first-child {
  margin-top: 0px;
}

blockquote>:last-child {
  margin-bottom: 0px;
}

/* HORIZONTAL RULES
=============================================================================*/

hr {
  clear: both;
  margin: 15px 0;
  height: 0px;
  overflow: hidden;
  border: none;
  background: transparent;
  border-bottom: 4px solid #ddd;
  padding: 0;
}

/* TABLES
=============================================================================*/

table th {
  font-weight: bold;
}

table th, table td {
  border: 1px solid #ccc;
  padding: 6px 13px;
}

table tr {
  border-top: 1px solid #ccc;
  background-color: #fff;
}

table tr:nth-child(2n) {
  background-color: #f8f8f8;
}

/* IMAGES
=============================================================================*/

img {
  max-width: 100%
}
</STYLE>
 
<STYLE type="text/css">
.highlight  { background: #ffffff; }
.highlight .c { color: #999988; font-style: italic } /* Comment */
.highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */
.highlight .k { font-weight: bold } /* Keyword */
.highlight .o { font-weight: bold } /* Operator */
.highlight .cm { color: #999988; font-style: italic } /* Comment.Multiline */
.highlight .cp { color: #999999; font-weight: bold } /* Comment.Preproc */
.highlight .c1 { color: #999988; font-style: italic } /* Comment.Single */
.highlight .cs { color: #999999; font-weight: bold; font-style: italic } /* Comment.Special */
.highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */
.highlight .gd .x { color: #000000; background-color: #ffaaaa } /* Generic.Deleted.Specific */
.highlight .ge { font-style: italic } /* Generic.Emph */
.highlight .gr { color: #aa0000 } /* Generic.Error */
.highlight .gh { color: #999999 } /* Generic.Heading */
.highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */
.highlight .gi .x { color: #000000; background-color: #aaffaa } /* Generic.Inserted.Specific */
.highlight .go { color: #888888 } /* Generic.Output */
.highlight .gp { color: #555555 } /* Generic.Prompt */
.highlight .gs { font-weight: bold } /* Generic.Strong */
.highlight .gu { color: #aaaaaa } /* Generic.Subheading */
.highlight .gt { color: #aa0000 } /* Generic.Traceback */
.highlight .kc { font-weight: bold } /* Keyword.Constant */
.highlight .kd { font-weight: bold } /* Keyword.Declaration */
.highlight .kp { font-weight: bold } /* Keyword.Pseudo */
.highlight .kr { font-weight: bold } /* Keyword.Reserved */
.highlight .kt { color: #445588; font-weight: bold } /* Keyword.Type */
.highlight .m { color: #009999 } /* Literal.Number */
.highlight .s { color: #d14 } /* Literal.String */
.highlight .na { color: #008080 } /* Name.Attribute */
.highlight .nb { color: #0086B3 } /* Name.Builtin */
.highlight .nc { color: #445588; font-weight: bold } /* Name.Class */
.highlight .no { color: #008080 } /* Name.Constant */
.highlight .ni { color: #800080 } /* Name.Entity */
.highlight .ne { color: #990000; font-weight: bold } /* Name.Exception */
.highlight .nf { color: #990000; font-weight: bold } /* Name.Function */
.highlight .nn { color: #555555 } /* Name.Namespace */
.highlight .nt { color: #000080 } /* Name.Tag */
.highlight .nv { color: #008080 } /* Name.Variable */
.highlight .ow { font-weight: bold } /* Operator.Word */
.highlight .w { color: #bbbbbb } /* Text.Whitespace */
.highlight .mf { color: #009999 } /* Literal.Number.Float */
.highlight .mh { color: #009999 } /* Literal.Number.Hex */
.highlight .mi { color: #009999 } /* Literal.Number.Integer */
.highlight .mo { color: #009999 } /* Literal.Number.Oct */
.highlight .sb { color: #d14 } /* Literal.String.Backtick */
.highlight .sc { color: #d14 } /* Literal.String.Char */
.highlight .sd { color: #d14 } /* Literal.String.Doc */
.highlight .s2 { color: #d14 } /* Literal.String.Double */
.highlight .se { color: #d14 } /* Literal.String.Escape */
.highlight .sh { color: #d14 } /* Literal.String.Heredoc */
.highlight .si { color: #d14 } /* Literal.String.Interpol */
.highlight .sx { color: #d14 } /* Literal.String.Other */
.highlight .sr { color: #009926 } /* Literal.String.Regex */
.highlight .s1 { color: #d14 } /* Literal.String.Single */
.highlight .ss { color: #990073 } /* Literal.String.Symbol */
.highlight .bp { color: #999999 } /* Name.Builtin.Pseudo */
.highlight .vc { color: #008080 } /* Name.Variable.Class */
.highlight .vg { color: #008080 } /* Name.Variable.Global */
.highlight .vi { color: #008080 } /* Name.Variable.Instance */
.highlight .il { color: #009999 } /* Literal.Number.Integer.Long */
.pl-c {
    color: #969896;
}

.pl-c1,.pl-mdh,.pl-mm,.pl-mp,.pl-mr,.pl-s1 .pl-v,.pl-s3,.pl-sc,.pl-sv {
    color: #0086b3;
}

.pl-e,.pl-en {
    color: #795da3;
}

.pl-s1 .pl-s2,.pl-smi,.pl-smp,.pl-stj,.pl-vo,.pl-vpf {
    color: #333;
}

.pl-ent {
    color: #63a35c;
}

.pl-k,.pl-s,.pl-st {
    color: #a71d5d;
}

.pl-pds,.pl-s1,.pl-s1 .pl-pse .pl-s2,.pl-sr,.pl-sr .pl-cce,.pl-sr .pl-sra,.pl-sr .pl-sre,.pl-src,.pl-v {
    color: #df5000;
}

.pl-id {
    color: #b52a1d;
}

.pl-ii {
    background-color: #b52a1d;
    color: #f8f8f8;
}

.pl-sr .pl-cce {
    color: #63a35c;
    font-weight: bold;
}

.pl-ml {
    color: #693a17;
}

.pl-mh,.pl-mh .pl-en,.pl-ms {
    color: #1d3e81;
    font-weight: bold;
}

.pl-mq {
    color: #008080;
}

.pl-mi {
    color: #333;
    font-style: italic;
}

.pl-mb {
    color: #333;
    font-weight: bold;
}

.pl-md,.pl-mdhf {
    background-color: #ffecec;
    color: #bd2c00;
}

.pl-mdht,.pl-mi1 {
    background-color: #eaffea;
    color: #55a532;
}

.pl-mdr {
    color: #795da3;
    font-weight: bold;
}

.pl-mo {
    color: #1d3e81;
}
.task-list {
padding-left:10px;
margin-bottom:0;
}

.task-list li {
    margin-left: 20px;
}

.task-list-item {
list-style-type:none;
padding-left:10px;
}

.task-list-item label {
font-weight:400;
}

.task-list-item.enabled label {
cursor:pointer;
}

.task-list-item+.task-list-item {
margin-top:3px;
}

.task-list-item-checkbox {
display:inline-block;
margin-left:-20px;
margin-right:3px;
vertical-align:1px;
}
</STYLE>
 
<META name="GENERATOR" content="MSHTML 11.00.9600.18036"></HEAD> 
<BODY>
<TABLE>
  <THEAD>
  <TR>
    <TH>Document Number:</TH>
    <TH>P0054R00</TH></TR></THEAD>
  <TBODY>
  <TR>
    <TD>Date:</TD>
    <TD>2015-09-12</TD></TR>
  <TR>
    <TD>Project:</TD>
    <TD>Programming Language C++, Evolution</TD></TR>
  <TR>
    <TD>Revises:</TD>
    <TD>none</TD></TR>
  <TR>
    <TD>Reply to:</TD>
    <TD>gorn@microsoft.com</TD></TR></TBODY></TABLE>
<H1 id="p0054r00-coroutines-reports-from-the-field">P0054R00: Coroutines: 
Reports from the field</H1>
<H2 id="introduction">Introduction</H2>
<P>An experimental version of the compiler supporting coroutines (aka resumable 
functions <A href="http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2014/n4134.pdf">N4134</A>, 
<A 
href="http://open-std.org/JTC1/SC22/WG21/docs/papers/2014/n4286.pdf">N4286</A>, 
<A href="https://isocpp.org/files/papers/N4402.pdf">N4402</A>) was out in the 
wild for nearly a year now. This paper proposes changes based on the feedback 
received from customers experimenting with it, the feedback from WG21 committee 
members, and learning from the experience of converting large shipping 
application to use coroutines for asynchronous operations. The updated wording 
is provided in a separate paper <A 
href="http://wg21.link/P0057R00">P0057R00</A>.</P>
<H2 id="defects">Defects</H2>
<P>In revision 4 of the resumable function proposal (<A href="https://isocpp.org/files/papers/N4402.pdf">N4402</A>), 
the requirements on the return type of <CODE>initial_suspend</CODE>, 
<CODE>final_suspend</CODE> and <CODE>yield_value</CODE> member functions were 
changed from having to return an <CODE>Awaitable</CODE> type, to a type 
contextually convertible to bool. </P>
<PRE><CODE>Before N4402: 

struct coro {
  struct promise_type {
    std::experimental::suspend_never initial_suspend() { return {}; }
    std::experimental::suspend_always  final_suspend() { return {}; }
    ...
  }
};

After N4402: 

struct coro {
  struct promise_type {
    bool initial_suspend() { return false; }
    bool final_suspend() { return false; }
    ...
  }
};
</CODE></PRE>
<P>While this made simple code slightly simpler, it also made it 
<STRONG>impossible</STRONG> to write the correct code for less trivial coroutine 
scenarios. Consider the following:</P>
<H3 id="immediately-scheduled-coroutines">Immediately Scheduled Coroutines</H3>
<P>Imagine a case where an invocation of a coroutine immediately schedules it to 
execute on a thread pool and yields control back to the caller. Murphy's law 
guarantees that a scheduler will execute the coroutine to completion and 
deallocate all the memory associated with the coroutine state even prior to 
<CODE>initial_suspend</CODE> call returning.</P>
<P>Prior to N4402, initial suspend point was defined in terms of operator 
<CODE>await</CODE>, i.e. <CODE>await $promise.initial_suspend()</CODE>. await 
operator mechanics took care of the race when the resumption of the coroutine 
happens before <CODE>await_suspend</CODE> completes, by preparing the coroutine 
for the resumption prior to the invocation of the <CODE>await_suspend</CODE>. A 
check via <CODE>await_ready</CODE> was used to avoid this potentially expensive 
preparation if the result of the computation was already available. (Expensive 
here means a few extra store operations, such as saving non-volatile registers 
in use, and storing an address or an index of the resume point, for example).  
</P><!--
N4402 defines suspension point with this pseudo-code.

```
if ($promise.initial_suspend()) {
   suspend-resume-point // initial suspend point
}
```
--> 
<P>To handle the race, N4402's initial_suspend() would need to add the logic 
similar to that of the await. Hence we propose to go back to defining initial 
suspend point via <CODE>await $promise.initial_suspend()</CODE>.</P>
<H3 id="final-suspend-racing-with-coroutine_handle-destroy-">Final suspend 
racing with coroutine_handle::destroy()</H3>
<P>Imagine a case where a library developer would like to combine the allocation 
of a <CODE>future</CODE> shared state N4527/[futures.state] with the allocation 
of the coroutine state in the case when the coroutine returns the future. <!-- (Or other future like classes such as `hpx::future`, `boost::future`, etc). This is optimization similar to what `make_shared<T>` implementations frequently do to combing the allocation of an object T with a reference count into a single allocation. --> 
 </P>
<PRE><CODE>future&lt;int&gt; deep_thought() {
  await 7'500'000'000h;
  return 42;
}
</CODE></PRE>
<P>This will require an atomic reference count in the shared state / promise. 
One reference will be held by the future, to make sure it can examine the shared 
state even when the coroutine has completed execution, and another reference 
will be from the coroutine itself, since it does not want its memory deallocated 
by the future destructor while in the middle of the execution.</P>
<P>Future destructor will decrement the reference count in the shared state and 
if the reference goes to zero will invoke <CODE>destroy()</CODE> member of the 
<CODE>coroutine_handle</CODE> to free the state. Similarly, when the coroutine 
reaches the final suspend point, it decrements the reference and if it happens 
to be zero, meaning the future is gone and no longer requires the shared state, 
the coroutine should not suspend at the final point and proceeds straight to the 
end and destroy its state.</P>
<P>However, it is possible that the future's destructor has decremented the 
reference count immediately after final_suspend() checked that the reference 
count is not zero, but before final_suspend returned. This is very similar to 
the race described in he previous section and the solution is the same: we need 
to rely on await operator to resolve it. Here is how the correct 
<CODE>final_suspend</CODE> would look like.</P>
<PRE><CODE>struct promise_type : shared_state&lt;T&gt; { // refcount is in the shared state
  auto final_suspend() {
    struct awaiter {
       promise_type * me;
       bool await_ready() { return false; }
       void await_resume() {}
       bool await_suspend(coroutine_handle&lt;&gt;) {
          auto need_suspending = (me-&gt;decrement_refcount() &gt; 0);
          return need_suspending;
       }
    };
    return awaiter{this};
  }
  ...
};
</CODE></PRE>
<H3 
id="asynchronous-generator-yield_value-races-with-consumer-going-away">Asynchronous 
generator yield_value races with consumer going away</H3>
<P>Consider an asynchronous generator:</P>
<PRE><CODE>async_generator&lt;int&gt; quick_thinker() {
  for (;;) {
    await 1ms;
    yield 42;
  }
}
</CODE></PRE>
<P>We need to coordinate between a producer i.e. the coroutine shown above and a 
consumer that is whomever is holding on to an async_generator<int> object. In 
this particular case a consumer owns the producer. After a consumer decides to 
go away, meaning async_generator<int> destructor runs, a well behaved producer 
should stop its activity and release the resources it uses, moreover the 
producer should not attempt to resume the consumer as it is gone. Thus the 
producer in its <CODE>value needs</CODE> needs to make a determination: if the 
consumer is alive, give it the value and resume it, otherwise, the producer 
coroutine need to cancel itself by invoking coroutine_handle::destroy() on 
itself. This could be implemented correctly with pre N4402 version. Again the 
fix is to revert to pre-N4402 behavior and define <CODE>yield expr</CODE> in 
terms of <CODE>await $promise.yield_value</CODE> as <CODE>await_suspend</CODE> 
allows to concurrent resumption of the coroutine either via 
<CODE>resume()</CODE> and <CODE>destroy()</CODE>. With the fix, implemenation of 
<CODE>yield_value</CODE> would look like:</int></int></P>
<PRE><CODE>template &lt;typename T&gt;
struct async_generator {
  struct promise_type {
    T const * yielded_value;
    coroutine_handle&lt;&gt; consumer;
    ...
    auto yield_value(T const&amp; v) {
      struct awaiter {
         promise_type * me;
         bool await_ready() { return false; }
         T const &amp; await_resume() { return *me-&gt;yielded_value; }
         void await_suspend(coroutine_handle&lt;&gt; myself) {
           ... if consumer is gone =&gt; myself.destroy();
           ... otherwise           =&gt; consumer.resume();
         }
      };
      yielded_value = &amp;v;
      return awaiter{this};
    }
  };
  ...
};
</CODE></PRE>
<H2 id="operator-await">operator await</H2>
<P>Currently <CODE>await expression</CODE> uses a range-based for like lookup 
for three member or non-member functions called <CODE>await_suspend</CODE>, 
<CODE>await_ready</CODE> and <CODE>await_resume</CODE>. This has not been always 
the case. An earlier iteration of the resumable functions proposal that never 
got to be an N-numbered paper had defined <CODE>operator await</CODE> that had 
to return an awaitable object that has member functions 
<CODE>await_suspend</CODE>, <CODE>await_ready</CODE> and 
<CODE>await_resume</CODE>.</P>
<P>Let's compare how await adapters used to look like and how they look in N4134 
and beyond. </P><!-- template <typename T>
auto future<T>::operator await() {
  struct awaiter {
    future<T>* me;
    bool await_ready() { return me->ready(); }
    T await_resume() { return me->get(); }
    void await_suspend(coroutine_handle<>) {...}
  }
  return awaiter{this};
}
--> 
<PRE><CODE>auto sleep_for(chrono::system_clock::duration d) {
  struct result_t {
    chrono::system_clock::duration d;

    auto operator await() {
       struct awaiter {
          chrono::system_clock::duration duration;
             ...
          awaiter(chrono::system_clock::duration d) : duration(d){}
          bool await_ready() const { return duration.count() &lt;= 0; }
          void await_resume() {}
          void await_suspend(std::experimental::coroutine_handle&lt;&gt; resume_cb){...}
       };
       return awaiter{d};
     }
  };
  return result_t{d};
}
</CODE></PRE>
<P>The authors felt that this was too much boilerplate code and one more local 
class than desired, hence the N4134 offered a range-based-for like lookup 
instead of operator await. Indeed under N4134 rules the code is simpler. </P><!--
template <typename T> bool await_ready(future<T>& f) { return f->ready(); }
template <typename T> void await_suspend(future<T>& f, coroutine_handle<>) {...}
template <typename T> T await_resume(future<T>& f) { return f->get(); }
--> 
<PRE><CODE>auto sleep_for(chrono::system_clock::duration d) {
  struct awaiter {
     chrono::system_clock::duration duration;
       ...
     awaiter(chrono::system_clock::duration d) : duration(d){}
     bool await_ready() const { return duration.count() &lt;= 0; }
     void await_resume() {}
     void await_suspend(std::experimental::coroutine_handle&lt;&gt; resume_cb){...}
  };
  return awaiter{d};
}
</CODE></PRE>
<P>However this simplification removed one powerful ability that was enabled by 
<CODE>operator await</CODE>. It was no longer possible for library author to 
rely on a temporary object on a coroutine frame during the await expansion that 
can persist for the duration of await expression and can be used to carry state 
between <CODE>await_ready</CODE>, <CODE>await_suspend</CODE> and 
<CODE>await_resume</CODE> functions. The only form that remained that allowed 
this was when awaitable was returned from a function, such as in the example of 
<CODE>sleep_for</CODE> above.</P>
<P>Consider this straightforward, but incorrect awaitable adapter for 
<CODE>boost::future</CODE>. </P>
<PRE><CODE>template &lt;typename T&gt; bool await_ready(boost::future&lt;T&gt;&amp; f) { return f.ready(); }
template &lt;typename T&gt; T await_resume(boost::future&lt;T&gt;&amp; f) { return f.get(); }
template &lt;typename T&gt; void await_suspend(boost::future&lt;T&gt;&amp; f, coroutine_handle&lt;&gt; cb) {
  f.then([cb](auto&amp;&amp;){ cb(); });
}
</CODE></PRE>
<P>The problem is that as of version 1.59, future.then returns a future that 
blocks in the destructor. Thus coroutine, after subscribing to the completion of 
f.then will block at the last curly brace of await_suspend waiting for the 
destructor that will block until the future is ready prevening coroutine from 
suspending. Though in the case of boost, we can fix boost .then, in case of 
other libraries it may not be possible to change them to adapt await within time 
constraints. Having <CODE>operator await</CODE> would have addressed this 
problem. </P>
<P>To make sure that a future returned from the <CODE>.then</CODE> won't block 
the suspend, we need to extend its life for the duration of await expression. 
With operator <CODE>await</CODE> we can do it easily:  </P>
<PRE><CODE>template &lt;typename T&gt;
auto operator await(boost::future&lt;T&gt; &amp; f) {
  struct awaiter {
    future&lt;T&gt;* me;
    future&lt;T&gt; keep_this;
    bool await_ready() { return me-&gt;ready(); }
    T await_resume() { return me-&gt;get(); }
    void await_suspend(coroutine_handle&lt;&gt; cb) {
       keep_this = f.then([cb](auto&amp;&amp;){ cb(); });
    }
  }
  return awaiter{this, {}};
}
</CODE></PRE>
<P>Another case for <CODE>operator await</CODE> is adapter efficiency. Imagine 
that we want to do a lean future that allows multiple coroutines to subscribe 
their awaits on lean_future's <CODE>.then</CODE> and make the subscription 
operation via <CODE>.then</CODE> to be <CODE>noexcept</CODE> and not perform any 
memory allocations. <CODE>operator await</CODE> makes this possible: </P>
<PRE><CODE>template &lt;typename T&gt;
auto operator await(lean_future&lt;T&gt; &amp; f) {
  struct awaiter {
    lean_future&lt;T&gt;* me;
    lean_future&lt;T&gt;::intrusive_link link;
    bool await_ready() { return me-&gt;ready(); }
    T await_resume() { return me-&gt;get(); }
    void await_suspend(coroutine_handle&lt;&gt; cb) {
       keep_this = f.then(&amp;me-&gt;link);
    }
  }
  return awaiter{this, {}};
}
</CODE></PRE>
<P>Since <CODE>operator await</CODE> enables library to control the temporary 
that lives for the duration of the await-expression, library writer can include 
in the temporary the intrusive_list::link so that it can be directly linked into 
the intrusive list in the lean_future. That removes an allocation and a failure 
mode. In kernel mode of operating system, in game development those are 
important properties.</P>
<P>Now, Some of these tecniques are possible today with N4134, but only with 
awaitables that are temporaries returned from a function, like in sleep_for in 
earlier in this section. Having <CODE>operator await</CODE> fixes existing 
assymmetry that different awaitables have different expressive power.</P>
<P>We would like to bring back operator <CODE>await</CODE> with an improvement 
that will result in less boilerplate code. The proposed change is to make an 
<CODE>operator await</CODE> to be implicitly defined for a class that has 
<CODE>await_suspend</CODE>, <CODE>await_resume</CODE> and 
<CODE>await_ready</CODE> and it is defined as an identity function. It returns 
the object itself. With this approach, we can now address the problems described 
above and retain the concise style available today.</P>
<P>As a bonus, it is now possible to write an await adapter for chrono::duration 
that we have been sneakily using throughout this paper that allows us to write 
<CODE>await 10ms</CODE>. Behold:</P>
<PRE><CODE>template &lt;class Rep, class Period&gt;
auto operator await(chrono::duration&lt;Rep, Period&gt; d) {
  struct awaiter {
     chrono::system_clock::duration duration;
       ...
     awaiter(chrono::system_clock::duration d) : duration(d){}
     bool await_ready() const { return duration.count() &lt;= 0; }
     void await_resume() {}
     void await_suspend(std::experimental::coroutine_handle&lt;&gt; resume_cb){...}
  };
  return awaiter{d};
}
</CODE></PRE>
<H2 id="it-s-2015-why-are-we-still-making-statements-that-can-t-serve-as-expressions-">It's 
2015, why are we still making statements that can't serve as 
expressions...?</H2>
<P>No good reason. Pre-N4402 it was an expression. N4402 did a lot of 
"simplifications" that are now being undone. Making yield a statement as opposed 
to an expression was one of the "simplifications".</P>
<P>The suggested change here is to let <CODE>yield expr</CODE> and <CODE>yield 
{expr}</CODE> be expressions not statements with the same precedence as a 
<CODE>throw expr</CODE>.</P>
<PRE><CODE>  assignment-expression:
    conditional-expression
    logical-or-expression assignment-operator initializer-clause
    throw-expression
    yield-expression
</CODE></PRE>
<P>This precedence would allow <CODE>yield</CODE> to be used with <CODE>comma 
operator</CODE> and at the same time to be able to write <CODE>yield 1 + 
2</CODE> without surprising parsing <CODE>(yield 1) + 2</CODE>. </P>
<P>Side effect of this change and making <CODE>yield_value</CODE> return 
awaitable as required to fix the defect described in previous section opens the 
possibility for library writers to invent and implement semantics for 
<EM>yield-expresion</EM> returning something back into the coroutine enabling 
two way communication between the generator and the consumer.</P>
<H2 id="allocators-be-gone">Allocators be gone</H2>
<P>Authors have received a strongly worded feedback that it is highly 
undesirable to make a language feature dependent on std::allocators. Other 
language features rely on allocating via <CODE>operator new</CODE> and use 
overloading of <CODE>operator new</CODE> as a way to customize allocations for 
classes that require specialized allocation strategies.</P>
<P>To address this concern and bring the coroutines more in line with other 
language features, if a coroutine requires dynamic memory allocation for its 
state, it will call <CODE>operator new</CODE> and customization of allocations 
could be done by overloading operator new. We implemented this change and 
discovered that most of the user code that customized coroutine allocations with 
stateless allocators shrunk significantly.</P>
<P>Before:</P>
<PRE><CODE>template &lt;typename T, typename... Ts&gt;
struct coroutine_traits&lt;generator&lt;T&gt;, use_counting_allocator_t, Ts...&gt; {
   template &lt;typename T&gt;
   struct counting_allocator {
      std::allocator&lt;T&gt; inner;
      using value_type = T;

      T* allocate(std::size_t n) {
        bytes_allocated += n * sizeof(T);
        return inner.allocate(n);
      }
      void deallocate(T* p, std::size_t n) {
        bytes_freed += n * sizeof(T);
        inner.deallocate(p, n);
      }
    };

    template &lt;typename... Us&gt;
    static auto get_allocator(Us&amp;&amp;...) {
        return counting_allocator&lt;char&gt;{};
    }
    using promise_type = typename generator&lt;T&gt;::promise_type;
};
</CODE></PRE>
<P>After</P>
<PRE><CODE>template &lt;typename T, typename... Ts&gt;
struct coroutine_traits&lt;generator&lt;T&gt;, use_counting_allocator_t, Ts...&gt; {
    struct promise_type : generator&lt;T&gt;::promise_type {
        void* operator new(size_t size) {
            bytes_allocated += size * sizeof(T);
            return ::operator new(size);
        };
        void operator delete(void* p, size_t size) {
            bytes_freed += size * sizeof(T);
            ::operator delete(p, size);
        }
    };
};
</CODE></PRE>
<P>Note that in the get_allocator example, get_allocator it is getting all of 
the coroutine arguments so that if it is a stateful allocator it can pick up 
required information from the arguments. The suggested change preserves an 
ability to pass information to an allocation routine, but, it keeps the simple 
case (non-stateful) simple by using the following rule: if the coroutine promise 
defines an <CODE>operator new</CODE> that take just <CODE>size_t</CODE>, it will 
be used to allocate the memory for the coroutine, otherwise, the compiler will 
use the <CODE>new-expression</CODE> of the form <CODE>promise_type::operator 
new(required-size, all of the arguments passed to a coroutine)</CODE>. The 
latter forms allows for an overloaded new to extract required allocator 
parameters. </P>
<P>Finally, to preserve parity with N4402 with respect to allocators, we need to 
address coroutine operations in the environment where allocation functions 
cannot throw. N4402 was determining the need for special handling of allocations 
by checking if <CODE>get_return_object_on_allocation_failure</CODE> static 
member function was present in <CODE>coroutine_traits</CODE>, we suggest to move 
it to <CODE>coroutine_promise</CODE> and use <CODE>std::nothrow_t&amp;</CODE> 
form of <CODE>operator new</CODE> in this case.</P>
<P>Before:</P>
<PRE><CODE>struct coro {
  struct promise_type {
    coro get_return_object();
    ...
  };
};

template &lt;typename... Args&gt; struct coroutine_traits&lt;coro, Args...&gt; {
  static coro get_return_object_on_allocation_failure();
  using promise_type = coro::promise_type;
};
</CODE></PRE>
<P>After:</P>
<PRE><CODE>struct coro {
  struct promise_type {
    static coro get_return_object_on_allocation_failure();
    coro get_return_object();
    ...
  };
};
</CODE></PRE><!-- Another side benefit from this change is that it moved all allocation matters from `coroutine_traits` to `coroutine_promise` which allows to avoid defining `coroutine_traits` for most --> 
<P>With this changes, not only we remove dependency of coroutines on 
std::allocator and friends, we also moved most of the functionality present in 
<CODE>coroutine_traits</CODE> that deal with allocation concerns into the 
coroutine promise making specializing <CODE>coroutine_traits</CODE> unnecessary 
in majority of cases. The only remaining case for using 
<CODE>coroutine_traits</CODE> is when one defines a coroutine promise for a type 
that belong to some pre-existing library that cannot be altered.</P>
<H2 id="on-the-radar">On the radar</H2>
<P>This section describe some changes we are exploring at the moment, but, did 
not have time to implement and experiment with. We plan to proposem at the next 
meeting. They are listed here for an opportunity for early feedback.</P>
<H3 id="promise_type-await_transform">promise_type::await_transform</H3>
<P>One of the pattern in use with frameworks using <CODE>.then</CODE> is to use 
a cancellation flag / token to be passed to a function and furnished to every 
<CODE>.then</CODE> to facilitate cancellation.</P>
<P>When porting the code to use <CODE>await</CODE>, every await expression was 
wrapped with an awaitable adapter that would take an existing awaitable and 
augment it to check the cancellation flag and cancel the coroutine if 
required.</P>
<PRE><CODE>  auto bytesRead = await conn.Read(buf, len);

     would become

  auto bytesRead = await CheckCancel(cancelToken, conn.Read(buf, len));
</CODE></PRE>
<P>Adding CheckCancel at every await site is cumbersome and error prone. </P>
<P>We would like to provide an ability for the coroutine type author to specify 
an <CODE>await_transform</CODE> member in the promise_type of the coroutine. If 
present, every <CODE>await expr</CODE> in that coroutine would be as if it was 
<CODE>await $promise.await_transform(expr)</CODE>.</P>
<P>Besides helping with cancellation, await_transform has other uses:</P>
<H4 id="debugging-tracing-performance-measuring">debugging / tracing / 
performance measuring</H4>
<P>With an appropriate await_transform, coroutine can trace/log when it is 
suspended, when it is resumed, whether suspension was avoided due to await_ready 
being true, etc. This allows debugging tools accumulate information for 
asynchronous activity visualization. It can be used for capturing the traces for 
problem or performance analysis. </P>
<H4 id="undo-yet-another-simplification-from-n4402">undo yet another 
"simplification" from N4402</H4>
<P>In N4402 whether <CODE>await</CODE> is allowed or not in the coroutine is 
tied to whether the coroutine promise defines 
<CODE>return_value</CODE>/<CODE>return_void</CODE> with argumentation that 
coroutines that <CODE>await</CODE> on something have an eventual value return 
value, but, generators do not. This restriction was introduces in N4402 to help 
detect mistakes at compile time when <CODE>await</CODE> is used in coroutines 
that don't support it.</P>
<P>await_transform allows library author trivially to specify a compile check 
whether coroutine is allowed or not to use await and limitation introduced in 
N4402 is no longer required.</P>
<H2 id="exploring-design-space">Exploring design space</H2>
<P>Resumable expressions paper (<A href="http://open-std.org/JTC1/SC22/WG21/docs/papers/2015/n4453.pdf">N4453</A>) 
has a compelling example of <EM>magically</EM> transforming a function template 
into a coroutine depending on the <CODE>OutputIterator</CODE> supplied. </P>
<PRE><CODE>template &lt;class OutputIterator&gt; void fib(int n, OutputIterator out) {
  int a = 0;
  int b = 1;
  while (n-‐ &gt; 0) {
    *out++ = a;
    auto next = a + b;
    a = b;
    b = next;
  }
}
</CODE></PRE>
<H3 id="automatically-awaited-awaitables">Automatically Awaited Awaitables</H3>
<P>This section sketches out an idea how coroutines can evolve to support the 
scenario above. The idea is simple. If a function returns an object of type that 
is marked with <CODE>auto await</CODE>, an <CODE>await</CODE> is injected into 
the calling function. For the example above, dereferencing of an iterator would 
return a proxy that has an overloaded operator <CODE>=</CODE> that returns 
<EM>automatically awaited awaitable</EM>.  </P>
<PRE><CODE>auto MyProxy::operator=(int output) {
  struct Awaitable auto await { ... };
  return Awaitable{...};
}
</CODE></PRE>
<P>Thus an expression <CODE>*out++ = a</CODE> will become <CODE>await (*out++ = 
a)</CODE>. Awaitable will transfer supplied value <CODE>a</CODE> to the consumer 
and suspend the function <CODE>fib</CODE> until the next value is requested. 
<STRONG>Note that this has not been designed, implemented and there is no 
immediate plan to pursue this approach.</STRONG></P>
<P>One concern with this approach is that it interferes with composability of 
awaitable expressions. If <CODE>f()</CODE> and <CODE>g()</CODE> returns 
awaitables, we would like to be able to transform awaitable in questions prior 
to applying <CODE>await</CODE> to them. For example, evaluation of <CODE>await 
f() + await g()</CODE> reduces concurrency as it would be more beneficial to 
execute it as <CODE>await (f() + g())</CODE>, where the result of <CODE>+</CODE> 
is a composite awaitable that will wait until both results of <CODE>f()</CODE> 
and <CODE>g()</CODE> are ready and will resume the coroutine providing the sum 
of the eventual results of f() and g().</P>
<P>Another concern is that it is now near impossible for the reader to figure 
out whether function is a coroutine or not unless we can audit every function 
call, implicit conversion, overloaded operator in the body of the function and 
figuire out if it can return <EM>automatically awaited awaitable</EM>.</P>
<P>Moreover, even though coroutines allow asynchrous code to be written nearly 
as simple as synchronous, they do not eliminate the need to think about and 
properly design the lifetime of the asynchronous activity. Const-ref parameters 
<CODE>const&amp;</CODE> that are perfectly fine to consume in a normal function 
may result in a crash, information disclosure and more if the function is a 
coroutine which lifetime extends beyond the lifetime of the object bound to that 
<CODE>const&amp;</CODE> parameter.</P><!--
Another concern is that though coroutines allow asynchrous code to be written nearly as simple as synchronous, they do not eliminate the need to think about and properly design the lifetime of the asynchronous activity. Our conjecture is that the *magical* unification of synchronous and asynchronous code possible via *automatically awaited awaitable* is mostly applicable to trivial samples and will break down for real code.  --> <!--
### Revisit the return type of await_suspend

In majority of cases, when writing awaitable, the library author uses the await_suspend form returning `void`, resulting in unconditional suspend.

In some cases, it is desirable to be able to veto await_suspend, for example, if a library author would like to veto suspension if an asynchronous operation launched  from within await_suspend has completed synchronously. In some scenarios it can result in 2x performance speed up. Alternative to re-resuming the coroutine from await_suspend is not only slower, but also can result in stack overflow, it we happen to land on a long string of consecutive synchronous I/O completions.

```
template <typename Awaitable>
void await_transform(Awaitable&&) { static_assert(false, "this coroutine type does not support await expressions"); }
```
--> <!--
#### Provide compile time check for coroutines returning optional<T>, value_or<T,E>, etc

A library developer can design a coroutine promise for coroutines returning `optional<T>`. `await`-ing on an optional value in such a coroutine will result in a value if it there and propagating the *value is absent* as the result of the coroutine.

The mistake that we would like to catch at compile time is that in such coroutine we should only allow to `await` on values that have *value is absent* aspect, such as `optional`, but, not *value is not here yet*, such as `future<T>`.

Await transform is helpful here again

```
template <typename Awaitable>
void await_transform(Awaitable&&) { static_assert(!std::is_suspendable<Awaitable>, "this coroutine type does not support await expressions that result in suspension"); }
```
--> 
<H2 id="acknowledgements">Acknowledgements</H2>
<P>Kavya Kotacherry, Daveed Vandevoorde, Richard Smith, Jens Maurer, Lewis 
Baker, Kirk, Shoop, Hartmut Kaiser, Kenny Kerr, Artur Laksberg, Jim Radigan, 
Chandler Carruth, Gabriel Dos Reis, Deon Brewis, Jonathan Caves, James McNellis, 
Stephan T. Lavavej, Herb Sutter, Pablo Halpern, Robert Schumacher, Viktor Tong, 
Michael Wong, Niklas Gustafsson, Nick Maliwacki, Vladimir Petter, Shahms King, 
Slava Kuznetsov, Tongari J, Lawrence Crowl, Valentin Isac and many more who 
contributed. </P>
<H2 id="references">References</H2>
<P><A href="http://wg21.link/P0055R00">P0055r00</A>: On Interactions Between 
Coroutines and Networking (<A 
href="http://wg21.link/P0055R00">http://wg21.link/P0055R00</A>)<BR><A href="http://wg21.link/P0057R00">P0057r00</A>: 
Wording for Coroutines, Revision 3 (<A 
href="http://wg21.link/P0057R00">http://wg21.link/P0057R00</A>)</P>
<P><A 
href="http://open-std.org/JTC1/SC22/WG21/docs/papers/2015/n4527.pdf">N4527</A>: 
Working Draft, Standard for Programming Language C++ (<A href="http://open-std.org/JTC1/SC22/WG21/docs/papers/2015/n4527.pdf">http://open-std.org/JTC1/SC22/WG21/docs/papers/2015/n4527.pdf</A>)<BR><A 
href="https://isocpp.org/files/papers/N4402.pdf">N4402</A>: Resumable Functions 
(revision 4) (<A 
href="https://isocpp.org/files/papers/N4402.pdf">https://isocpp.org/files/papers/N4402.pdf</A>)<BR><A 
href="http://open-std.org/JTC1/SC22/WG21/docs/papers/2014/n4286.pdf">N4286</A>: 
Resumable Functions (revision 3) (<A href="http://open-std.org/JTC1/SC22/WG21/docs/papers/2014/n4286.pdf">http://open-std.org/JTC1/SC22/WG21/docs/papers/2014/n4286.pdf</A>)<BR><A 
href="http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2014/n4134.pdf">N4134</A>: 
Resumable Functions v2 (<A href="http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2014/n4134.pdf">http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2014/n4134.pdf</A>)<BR><A 
href="http://open-std.org/JTC1/SC22/WG21/docs/papers/2015/n4453.pdf">N4453</A>: 
Resumable Expressions (<A href="http://open-std.org/JTC1/SC22/WG21/docs/papers/2015/n4453.pdf">http://open-std.org/JTC1/SC22/WG21/docs/papers/2015/n4453.pdf</A>) 
</P></BODY></HTML><!-- This document was created with MarkdownPad, the Markdown editor for Windows (http://markdownpad.com) -->
