Topic: Comments on N4286: Resumable Functions


Author: TONGARI J <tongari95@gmail.com>
Date: Fri, 16 Jan 2015 23:57:47 -0800 (PST)
Raw View
------=_Part_1270_737202422.1421481467489
Content-Type: multipart/alternative;
 boundary="----=_Part_1271_1327947011.1421481467489"

------=_Part_1271_1327947011.1421481467489
Content-Type: text/plain; charset=UTF-8

Hi,

It has been months since the paper, but not until recently did I have a
chance to read it and play with VS2015 preview.
Here are my comments:

   - It should be stated clear that a coroutine destroys itself, I thought
   it's ref-counted and coroutine_handle is kinda intrinsic_ptr, but it's not.
   Users have to ensure that the coroutine will be fully executed or you'll
   leak resources.

   - await_ready is probably unnecessary, the check can be done
   within await_suspend.

   - Appendix D: "Exceptionless error propagation..." is not really
   exceptionless:
   if you await on a future which is already in error-state (i.e. is_ready
   == true), then await_suspend won't we executed and the exception won't be
   set for the promise, while in await_resume, an exception will still be
   thrown.

   - The idiom shown in N4287 returns an awaiter that won't submit the real
   work untill await is called on it, it's thus similar to
   std::async(std::launch::deferred, ...).
   For example, I want to run Op1 & Op2 asynchronously:
   auto op1 = Op1(...);
   auto op2 = Op2(...);

   // work of Op1 & Op2 is *not* submitted, it's just deferred

   await op1; // now Op1 is submitted
   await op2; // now Op2 is submitted
   As you can see, they're just deferred. To make them run asynchronously,
   we still need some kind of async/future to help:
   auto op1 = async_wait(Op1(...));
   auto op2 = async_wait(Op2(...));

   // both work of Op1 & Op2 is submitted

   await op1; // now wait for the result
   await op2; // now wait for the result
   which may be implemented as:
   template<class F>
   await_future<await_result_t<F>> async_wait(F&& f)
   {
       return await f;
   }
   I've implemented such a thing myself, but when await_result_t<F> is
   void, MSVC somewhat complains that promise::set_result doesn't take 1
   argument, which I believe is a compiler bug.

   Is there better way to reintroduce the asynchronism than the way I shown
   above (which fires another coroutine)?


--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

------=_Part_1271_1327947011.1421481467489
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div style=3D"font-family: arial, sans-serif; font-size: s=
mall;">Hi,</div><div style=3D"font-family: arial, sans-serif; font-size: sm=
all;"><br></div><div style=3D"font-family: arial, sans-serif; font-size: sm=
all;">It has been months since the paper, but not until recently did I have=
 a chance to read it and play with VS2015 preview.</div><div style=3D"font-=
family: arial, sans-serif; font-size: small;">Here are my comments:</div><u=
l><li style=3D"font-family: arial, sans-serif; font-size: small;">It should=
 be stated clear that a coroutine destroys itself, I thought it's ref-count=
ed and&nbsp;coroutine_handle is kinda intrinsic_ptr, but it's not.<br>Users=
 have to ensure that the&nbsp;coroutine&nbsp;will be fully executed or you'=
ll leak resources.<br><br></li><li><span style=3D"font-family: arial, sans-=
serif; font-size: small;">await_ready is probably unnecessary, the check ca=
n be done within&nbsp;await_suspend.<br><br></span></li><li><span style=3D"=
font-family: arial, sans-serif; font-size: small;">Appendix D: "Exceptionle=
ss error propagation..." is not really exceptionless:<br></span><span style=
=3D"font-family: arial, sans-serif; font-size: small;">if you await on a fu=
ture which is already in error-state (i.e. is_ready =3D=3D true), then awai=
t_suspend won't we executed and the exception won't be set for the promise,=
 while in&nbsp;await_resume, an exception will still be thrown.<br><br></sp=
an></li><li><font face=3D"arial, sans-serif" size=3D"2">The idiom shown in =
N4287 returns an&nbsp;awaiter that won't submit the real work untill await =
is called on it, it's thus similar to std::async(std::launch::deferred, ...=
).<br>For example,&nbsp;I want to run Op1 &amp; Op2 asynchronously:<br><div=
 class=3D"prettyprint" style=3D"border: 1px solid rgb(187, 187, 187); word-=
wrap: break-word; background-color: rgb(250, 250, 250);"><code class=3D"pre=
ttyprint"><div class=3D"subprettyprint"><span style=3D"color: #008;" class=
=3D"styled-by-prettify">auto</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"> op1 </span><span style=3D"color: #660;" class=3D"styled-=
by-prettify">=3D</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"> </span><span style=3D"color: #606;" class=3D"styled-by-prettify">Op1=
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(...);</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><sp=
an style=3D"color: #008;" class=3D"styled-by-prettify">auto</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"> op2 </span><span style=3D=
"color: #660;" class=3D"styled-by-prettify">=3D</span><span style=3D"color:=
 #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #606;" c=
lass=3D"styled-by-prettify">Op2</span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">(...);</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"><br><br></span><span style=3D"color: #800;" class=3D"style=
d-by-prettify">// work of Op1 &amp; Op2 is *not* submitted, it's just defer=
red</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br><br=
>await op1</span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><=
span style=3D"color: #800;" class=3D"styled-by-prettify">// now Op1 is subm=
itted</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>a=
wait op2</span><span style=3D"color: #660;" class=3D"styled-by-prettify">;<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><sp=
an style=3D"color: #800;" class=3D"styled-by-prettify">// now Op2 is submit=
ted</span></div></code></div>As you can see, they're just&nbsp;deferred. To=
 make them run&nbsp;asynchronously, we still need s</font>ome kind of async=
/future to help:<font face=3D"arial, sans-serif" size=3D"2"><div class=3D"p=
rettyprint" style=3D"border: 1px solid rgb(187, 187, 187); word-wrap: break=
-word; background-color: rgb(250, 250, 250);"><code class=3D"prettyprint"><=
div class=3D"subprettyprint"><span style=3D"color: #008;" class=3D"styled-b=
y-prettify">auto</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"> op1 </span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>=3D</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> async=
_wait</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</sp=
an><span style=3D"color: #606;" class=3D"styled-by-prettify">Op1</span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">(...));</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span style=
=3D"color: #008;" class=3D"styled-by-prettify">auto</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"> op2 </span><span style=3D"color: =
#660;" class=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"> async_wait</span><span style=3D"color: #660;"=
 class=3D"styled-by-prettify">(</span><span style=3D"color: #606;" class=3D=
"styled-by-prettify">Op2</span><span style=3D"color: #660;" class=3D"styled=
-by-prettify">(...));</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"><br><br></span><span style=3D"color: #800;" class=3D"styled-by-p=
rettify">// both work of Op1 &amp; Op2 is submitted</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"><br><br>await op1</span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">;</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #800;"=
 class=3D"styled-by-prettify">// now wait for the result</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"><br>await op2</span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">;</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #800=
;" class=3D"styled-by-prettify">// now wait for the result</span></div></co=
de></div>which may be implemented as:<br><div class=3D"prettyprint" style=
=3D"border: 1px solid rgb(187, 187, 187); word-wrap: break-word; background=
-color: rgb(250, 250, 250);"><code class=3D"prettyprint"><div class=3D"subp=
rettyprint"><span style=3D"color: #008;" class=3D"styled-by-prettify">templ=
ate</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</s=
pan><span style=3D"color: #008;" class=3D"styled-by-prettify">class</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify"> F</span><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">&gt;</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify"><br>await_future</span><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">&lt;</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify">await_result_t</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">&lt;</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify">F</span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">&gt;&gt;</span><span style=3D"color: #000;"=
 class=3D"styled-by-prettify"> async_wait</span><span style=3D"color: #660;=
" class=3D"styled-by-prettify">(</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify">F</span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">&amp;&amp;</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"> f</span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">)</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><b=
r></span><span style=3D"color: #660;" class=3D"styled-by-prettify">{</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify"><br>&nbsp; &nbsp;=
 </span><span style=3D"color: #008;" class=3D"styled-by-prettify">return</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"> await f</spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">;</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">}</span></div></code></div>I=
've&nbsp;implemented such a thing myself, but wh</font>en await_result_t&lt=
;F&gt; is void, MSVC somewhat complains that promise::set_result doesn't ta=
ke 1 argument, which I believe is a compiler bug.<br><font face=3D"arial, s=
ans-serif" size=3D"2"><br>Is there better way to reintroduce the&nbsp;async=
hronism than the way I shown above (which fires another coroutine)?</font><=
/li></ul><div><font face=3D"arial, sans-serif" size=3D"2"><span style=3D"li=
ne-height: 17px;"><br></span></font></div></div>

<p></p>

-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_1271_1327947011.1421481467489--
------=_Part_1270_737202422.1421481467489--

.


Author: Gor Nishanov <gornishanov@gmail.com>
Date: Tue, 20 Jan 2015 18:07:53 -0800 (PST)
Raw View
------=_Part_3719_1548576515.1421806074062
Content-Type: multipart/alternative;
 boundary="----=_Part_3720_1571169612.1421806074062"

------=_Part_3720_1571169612.1421806074062
Content-Type: text/plain; charset=UTF-8

Thank you very much for your feedback.


>    - It should be stated clear that a coroutine destroys itself, I
>    thought it's ref-counted and coroutine_handle is kinda intrinsic_ptr, but
>    it's not.
>
> Good point. I'll clarify that coroutine_handle is a low level class for
library implementers, concrete coroutines, such as generator have expected
RAII semantics and destroy the coroutine even if it is not fully executed.
You can find an example generator in the appendix


>
>    - await_ready is probably unnecessary, the check can be done
>    within await_suspend.
>
> There is an invisible "save state" that happens between await_ready and
await_suspend. Having an await_ready allows to bypass save state altogether
and continue execution.


>    - Appendix D: "Exceptionless error propagation..." is not really
>    exceptionless:
>    if you await on a future which is already in error-state (i.e.
>    is_ready == true), then await_suspend won't we executed and the exception
>    won't be set for the promise, while in await_resume, an exception will
>    still be thrown.
>
> You are right. The fix would be to check in await ready if the future is
in error and if so, return false, thus sending it onto await_suspend
path. await_suspend has access to the promise and can set_exception
directly.


>
>    - I've implemented such a thing myself, but when await_result_t<F> is
>    void, MSVC somewhat complains that promise::set_result doesn't take 1
>    argument, which I believe is a compiler bug.
>
>  If you can send me a self-contained repro, I can debug it and suggest a
workaround (and fix it in MSVC as well)

Thank you very much for your feedback.

Gor

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

------=_Part_3720_1571169612.1421806074062
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">Thank you very much for your feedback.<br><br><blockquote =
class=3D"gmail_quote" style=3D"margin: 0px 0px 0px 0.8ex; padding-left: 1ex=
; border-left-color: rgb(204, 204, 204); border-left-width: 1px; border-lef=
t-style: solid;"><div dir=3D"ltr"><ul><li style=3D"font-family: arial,sans-=
serif; font-size: small;">It should be stated clear that a coroutine destro=
ys itself, I thought it's ref-counted and&nbsp;coroutine_handle is kinda in=
trinsic_ptr, but it's not.<br></li></ul></div></blockquote><div>Good point.=
 I'll clarify that coroutine_handle is a low level class for library implem=
enters, concrete coroutines, such as generator have expected RAII semantics=
 and destroy the coroutine even if it is not fully executed. You can find a=
n example generator in the appendix</div><div>&nbsp;</div><blockquote class=
=3D"gmail_quote" style=3D"margin: 0px 0px 0px 0.8ex; padding-left: 1ex; bor=
der-left-color: rgb(204, 204, 204); border-left-width: 1px; border-left-sty=
le: solid;"><div dir=3D"ltr"><ul><li><span style=3D"font-family: arial,sans=
-serif; font-size: small;">await_ready is probably unnecessary, the check c=
an be done within&nbsp;await_suspend.<br></span></li></ul></div></blockquot=
e><div>There is an invisible "save state" that happens between await_ready =
and await_suspend. Having an await_ready allows to bypass save state altoge=
ther and continue execution. </div><div><span style=3D"font-family: arial,s=
ans-serif; font-size: small;"><br></span></div><blockquote class=3D"gmail_q=
uote" style=3D"margin: 0px 0px 0px 0.8ex; padding-left: 1ex; border-left-co=
lor: rgb(204, 204, 204); border-left-width: 1px; border-left-style: solid;"=
><div dir=3D"ltr"><ul><li><span style=3D"font-family: arial,sans-serif; fon=
t-size: small;">Appendix D: "Exceptionless error propagation..." is not rea=
lly exceptionless:<br></span><span style=3D"font-family: arial,sans-serif; =
font-size: small;">if you await on a future which is already in error-state=
 (i.e. is_ready =3D=3D true), then await_suspend won't we executed and the =
exception won't be set for the promise, while in&nbsp;await_resume, an exce=
ption will still be thrown.<br></span></li></ul></div></blockquote><div>You=
 are right. The fix would be to check in await ready if the future is in er=
ror and if so, return false, thus sending it onto await_suspend path.&nbsp;=
await_suspend has access to the promise and can set_exception directly.</di=
v><div>&nbsp;<span style=3D"font-family: arial,sans-serif; font-size: small=
;"><br></span></div><blockquote class=3D"gmail_quote" style=3D"margin: 0px =
0px 0px 0.8ex; padding-left: 1ex; border-left-color: rgb(204, 204, 204); bo=
rder-left-width: 1px; border-left-style: solid;"><div dir=3D"ltr"><ul><li><=
font face=3D"arial, sans-serif" size=3D"2">I've&nbsp;implemented such a thi=
ng myself, but wh</font>en await_result_t&lt;F&gt; is void, MSVC somewhat c=
omplains that promise::set_result doesn't take 1 argument, which I believe =
is a compiler bug.<font face=3D"arial, sans-serif" size=3D"2"><br></font></=
li></ul></div></blockquote><div>&nbsp;If you can send me a self-contained r=
epro, I can debug it and suggest a workaround (and fix it in MSVC as well)<=
/div><div><br></div><div>Thank you very much for your feedback.</div><div><=
br></div><div>Gor<font face=3D"arial, sans-serif" size=3D"2"><span style=3D=
"line-height: 17px;"><br></span></font></div></div>

<p></p>

-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_3720_1571169612.1421806074062--
------=_Part_3719_1548576515.1421806074062--

.


Author: TONGARI J <tongari95@gmail.com>
Date: Tue, 20 Jan 2015 19:48:26 -0800 (PST)
Raw View
------=_Part_52_284958465.1421812106744
Content-Type: multipart/alternative;
 boundary="----=_Part_53_408388445.1421812106744"

------=_Part_53_408388445.1421812106744
Content-Type: text/plain; charset=UTF-8

Hi Gor,

On Wednesday, January 21, 2015 at 10:07:54 AM UTC+8, Gor Nishanov wrote:
>
> Thank you very much for your feedback.
>
>
>>    - It should be stated clear that a coroutine destroys itself, I
>>    thought it's ref-counted and coroutine_handle is kinda intrinsic_ptr, but
>>    it's not.
>>
>> Good point. I'll clarify that coroutine_handle is a low level class for
> library implementers, concrete coroutines, such as generator have expected
> RAII semantics and destroy the coroutine even if it is not fully executed.
> You can find an example generator in the appendix
>

Actually I'm thinking if you should make coroutine_handle ref-counted for
safety instead, consider this:

std::future<void> task()
{
 std::vector<int> v(100);
 await std::suspend_always{};
 // Both the data of vector and the coroutine frame itself are leaked!
}

It's quite dangerous - I didn't allocate anything explicitly but I leaked
resources implicitly.
>
>
>>    - await_ready is probably unnecessary, the check can be done
>>    within await_suspend.
>>
>> There is an invisible "save state" that happens between await_ready and
> await_suspend. Having an await_ready allows to bypass save state altogether
> and continue execution.
>

Can I find the info somewhere in the paper? Doesn't "save state" happen in
suspend-resume-point?

>
>>    - Appendix D: "Exceptionless error propagation..." is not really
>>    exceptionless:
>>    if you await on a future which is already in error-state (i.e.
>>    is_ready == true), then await_suspend won't we executed and the exception
>>    won't be set for the promise, while in await_resume, an exception will
>>    still be thrown.
>>
>> You are right. The fix would be to check in await ready if the future is
> in error and if so, return false, thus sending it onto await_suspend
> path. await_suspend has access to the promise and can set_exception
> directly.
>

People on Boost ML also pointed out that the use of `future.then` in
`await_suspend` is incorrect because it's expected to block when the
returned future dies.

And I wonder if the exceptionless mechanism & exception way are mutually
exclusive? Can we write an awaitable type in uniform fashion regardless if
exception is available or not?

For example, I want my awaitable type to report errors, and I also want to
allow the user of such type to catch errors where he likes, but the current
exceptionless mechanism has some drawbacks:
1) `promise_type::cancellation_requested()` probably won't respect whether
`set_exception` is called or not
2) when `cancellation_requested` happened, it always return to the end
instead of the user catch hook, which makes it useless in exception context

so I concluded that we can't have an exceptionless awaitable implementation
that can be also used in exception context, is that correct?

>
>>    - I've implemented such a thing myself, but when await_result_t<F> is
>>    void, MSVC somewhat complains that promise::set_result doesn't take 1
>>    argument, which I believe is a compiler bug.
>>
>>  If you can send me a self-contained repro, I can debug it and suggest a
> workaround (and fix it in MSVC as well)
>

Try this:
void void_fn() {}

std::future<void> test()
{
 __await std::suspend_never{};
 return void_fn();
}

The compiler complains that it can't find `set_result` that accepts a void
arg.

I've reported another runtime issue here:
https://connect.microsoft.com/VisualStudio/feedback/details/1092244/unexpected-await-crashes


BTW, is it possible to implement something like:
await when_any(...)
?


Thanks for your response.

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

------=_Part_53_408388445.1421812106744
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">Hi&nbsp;Gor,<br><br>On Wednesday, January 21, 2015 at 10:0=
7:54 AM UTC+8, Gor Nishanov wrote:<blockquote class=3D"gmail_quote" style=
=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: =
1ex;"><div dir=3D"ltr">Thank you very much for your feedback.<br><br><block=
quote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;padding-left:=
1ex;border-left-color:rgb(204,204,204);border-left-width:1px;border-left-st=
yle:solid"><div dir=3D"ltr"><ul><li style=3D"font-family:arial,sans-serif;f=
ont-size:small">It should be stated clear that a coroutine destroys itself,=
 I thought it's ref-counted and&nbsp;coroutine_handle is kinda intrinsic_pt=
r, but it's not.<br></li></ul></div></blockquote><div>Good point. I'll clar=
ify that coroutine_handle is a low level class for library implementers, co=
ncrete coroutines, such as generator have expected RAII semantics and destr=
oy the coroutine even if it is not fully executed. You can find an example =
generator in the appendix</div></div></blockquote><div><br></div><div style=
=3D"font-family: arial, sans-serif; font-size: small;">Actually I'm thinkin=
g if you should make coroutine_handle ref-counted&nbsp;for safety&nbsp;inst=
ead, consider this:</div><div style=3D"font-family: arial, sans-serif; font=
-size: small;"><br></div><div class=3D"prettyprint" style=3D"border: 1px so=
lid rgb(187, 187, 187); word-wrap: break-word; background-color: rgb(250, 2=
50, 250);"><code class=3D"prettyprint"><div class=3D"subprettyprint"><span =
style=3D"color: #000;" class=3D"styled-by-prettify">std</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">::</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify">future</span><span style=3D"color: #=
080;" class=3D"styled-by-prettify">&lt;void&gt;</span><span style=3D"color:=
 #000;" class=3D"styled-by-prettify"> task</span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">()</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"><br></span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">{</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"><br>&nbsp;std</span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">::</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy">vector</span><span style=3D"color: #080;" class=3D"styled-by-prettify">=
&lt;int&gt;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
> v</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span=
><span style=3D"color: #066;" class=3D"styled-by-prettify">100</span><span =
style=3D"color: #660;" class=3D"styled-by-prettify">);</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify"><br>&nbsp;await std</span><span=
 style=3D"color: #660;" class=3D"styled-by-prettify">::</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify">suspend_always</span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">{};</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify"><br>&nbsp;</span><span style=3D=
"color: #800;" class=3D"styled-by-prettify">// Both the data of vector and =
the coroutine frame itself are leaked!</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"><br></span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">}</span></div></code></div><br>It's quite dangerous=
 - I didn't allocate anything explicitly but I leaked resources implicitly.=
&nbsp;<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8=
ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><blockq=
uote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;padding-left:1=
ex;border-left-color:rgb(204,204,204);border-left-width:1px;border-left-sty=
le:solid"><div dir=3D"ltr"><ul><li><span style=3D"font-family:arial,sans-se=
rif;font-size:small">await_ready is probably unnecessary, the check can be =
done within&nbsp;await_suspend.<br></span></li></ul></div></blockquote><div=
>There is an invisible "save state" that happens between await_ready and aw=
ait_suspend. Having an await_ready allows to bypass save state altogether a=
nd continue execution.</div></div></blockquote><div><br></div><div>Can I fi=
nd the info somewhere in the paper? Doesn't "save state" happen in suspend-=
resume-point?</div><blockquote class=3D"gmail_quote" style=3D"margin: 0;mar=
gin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D=
"ltr"><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;p=
adding-left:1ex;border-left-color:rgb(204,204,204);border-left-width:1px;bo=
rder-left-style:solid"><div dir=3D"ltr"><ul><li><span style=3D"font-family:=
arial,sans-serif;font-size:small">Appendix D: "Exceptionless error propagat=
ion..." is not really exceptionless:<br></span><span style=3D"font-family:a=
rial,sans-serif;font-size:small">if you await on a future which is already =
in error-state (i.e. is_ready =3D=3D true), then await_suspend won't we exe=
cuted and the exception won't be set for the promise, while in&nbsp;await_r=
esume, an exception will still be thrown.<br></span></li></ul></div></block=
quote><div>You are right. The fix would be to check in await ready if the f=
uture is in error and if so, return false, thus sending it onto await_suspe=
nd path.&nbsp;await_suspend has access to the promise and can set_exception=
 directly.</div></div></blockquote><div>&nbsp;</div><div>People on Boost ML=
 also pointed out that the use of `future.then` in `await_suspend` is incor=
rect because it's expected to block when the returned future dies.</div><di=
v><br></div><div>And I wonder if the exceptionless mechanism &amp; exceptio=
n way are mutually exclusive? Can we write an awaitable type in uniform fas=
hion regardless if exception is available or not?</div><div><br></div><div>=
For example, I want my awaitable type to report errors, and I also want to =
allow the user of such type to catch errors where he likes, but the current=
 exceptionless mechanism has some drawbacks:<br>1) `promise_type::cancellat=
ion_requested()` probably won't respect&nbsp;whether `set_exception` is cal=
led or not</div><div>2) when `cancellation_requested` happened, it always r=
eturn to the end instead of the user catch hook, which makes it useless in =
exception context</div><div><br></div><div>so I concluded that we can't hav=
e an exceptionless awaitable implementation that can be also used in except=
ion context, is that correct?</div><blockquote class=3D"gmail_quote" style=
=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: =
1ex;"><div dir=3D"ltr"><blockquote class=3D"gmail_quote" style=3D"margin:0p=
x 0px 0px 0.8ex;padding-left:1ex;border-left-color:rgb(204,204,204);border-=
left-width:1px;border-left-style:solid"><div dir=3D"ltr"><ul><li><font face=
=3D"arial, sans-serif" size=3D"2">I've&nbsp;implemented such a thing myself=
, but wh</font>en await_result_t&lt;F&gt; is void, MSVC somewhat complains =
that promise::set_result doesn't take 1 argument, which I believe is a comp=
iler bug.<font face=3D"arial, sans-serif" size=3D"2"><br></font></li></ul><=
/div></blockquote><div>&nbsp;If you can send me a self-contained repro, I c=
an debug it and suggest a workaround (and fix it in MSVC as well)</div></di=
v></blockquote><div><br></div><div>Try this:</div><div class=3D"prettyprint=
" style=3D"border: 1px solid rgb(187, 187, 187); word-wrap: break-word; bac=
kground-color: rgb(250, 250, 250);"><code class=3D"prettyprint"><div class=
=3D"subprettyprint"><span style=3D"color: #008;" class=3D"styled-by-prettif=
y">void</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> vo=
id_fn</span><span style=3D"color: #660;" class=3D"styled-by-prettify">()</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span=
 style=3D"color: #660;" class=3D"styled-by-prettify">{}</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"><br><br>std</span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">::</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify">future</span><span style=3D"color: =
#080;" class=3D"styled-by-prettify">&lt;void&gt;</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"> test</span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">()</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"><br></span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify">{</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"><br>&nbsp;__await std</span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">::</span><span style=3D"color: #000;" class=3D"styled-=
by-prettify">suspend_never</span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">{};</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"><br>&nbsp;</span><span style=3D"color: #008;" class=3D"styled-by-p=
rettify">return</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify"> void_fn</span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">();</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">}</span></=
div></code></div><br><div>The compiler complains that it can't find `set_re=
sult` that accepts a void arg.</div><div><br></div><div>I've reported anoth=
er runtime issue here:</div><div>https://connect.microsoft.com/VisualStudio=
/feedback/details/1092244/unexpected-await-crashes<br></div><div><br></div>=
<div><br></div><div>BTW, is it possible to implement something like:</div><=
div><div class=3D"prettyprint" style=3D"border: 1px solid rgb(187, 187, 187=
); word-wrap: break-word; background-color: rgb(250, 250, 250);"><code clas=
s=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D"color: #000;=
" class=3D"styled-by-prettify">await when_any</span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">(...)</span></div></code></div>?</div><d=
iv><br></div><div><br></div><div>Thanks for your response.</div></div>

<p></p>

-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_53_408388445.1421812106744--
------=_Part_52_284958465.1421812106744--

.


Author: shahms.king@gmail.com
Date: Thu, 12 Mar 2015 10:04:56 -0700 (PDT)
Raw View
------=_Part_143_1940145023.1426179896840
Content-Type: multipart/alternative;
 boundary="----=_Part_144_625705513.1426179896840"

------=_Part_144_625705513.1426179896840
Content-Type: text/plain; charset=UTF-8



On Tuesday, January 20, 2015 at 6:07:54 PM UTC-8, Gor Nishanov wrote:
>
> Thank you very much for your feedback.
>
>
>>    - It should be stated clear that a coroutine destroys itself, I
>>    thought it's ref-counted and coroutine_handle is kinda intrinsic_ptr, but
>>    it's not.
>>
>> Good point. I'll clarify that coroutine_handle is a low level class for
> library implementers, concrete coroutines, such as generator have expected
> RAII semantics and destroy the coroutine even if it is not fully executed.
> You can find an example generator in the appendix
>
>
>>
>>    - await_ready is probably unnecessary, the check can be done
>>    within await_suspend.
>>
>> There is an invisible "save state" that happens between await_ready and
> await_suspend. Having an await_ready allows to bypass save state altogether
> and continue execution.
>
>
>>    - Appendix D: "Exceptionless error propagation..." is not really
>>    exceptionless:
>>    if you await on a future which is already in error-state (i.e.
>>    is_ready == true), then await_suspend won't we executed and the exception
>>    won't be set for the promise, while in await_resume, an exception will
>>    still be thrown.
>>
>> You are right. The fix would be to check in await ready if the future is
> in error and if so, return false, thus sending it onto await_suspend
> path. await_suspend has access to the promise and can set_exception
> directly.
>

Except this incurs an unnecessary save-state (and suspension?) of the
awaiting function, which it would be nice to avoid.  The simplest way I can
see to avoid this would be passing just the promise to an await function,
although this potentially complicates the case where the promise type is
void, e.g.

template <typename _PromsieT>
bool await_ready(_PromiseT&) const;
bool await_ready() const;


--Shahms


>
>
>>
>>    - I've implemented such a thing myself, but when await_result_t<F> is
>>    void, MSVC somewhat complains that promise::set_result doesn't take 1
>>    argument, which I believe is a compiler bug.
>>
>>  If you can send me a self-contained repro, I can debug it and suggest a
> workaround (and fix it in MSVC as well)
>
> Thank you very much for your feedback.
>
> Gor
>

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

------=_Part_144_625705513.1426179896840
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>On Tuesday, January 20, 2015 at 6:07:54 PM UTC-8, =
Gor Nishanov wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;mar=
gin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D=
"ltr">Thank you very much for your feedback.<br><br><blockquote class=3D"gm=
ail_quote" style=3D"margin:0px 0px 0px 0.8ex;padding-left:1ex;border-left-c=
olor:rgb(204,204,204);border-left-width:1px;border-left-style:solid"><div d=
ir=3D"ltr"><ul><li style=3D"font-family:arial,sans-serif;font-size:small">I=
t should be stated clear that a coroutine destroys itself, I thought it's r=
ef-counted and&nbsp;coroutine_handle is kinda intrinsic_ptr, but it's not.<=
br></li></ul></div></blockquote><div>Good point. I'll clarify that coroutin=
e_handle is a low level class for library implementers, concrete coroutines=
, such as generator have expected RAII semantics and destroy the coroutine =
even if it is not fully executed. You can find an example generator in the =
appendix</div><div>&nbsp;</div><blockquote class=3D"gmail_quote" style=3D"m=
argin:0px 0px 0px 0.8ex;padding-left:1ex;border-left-color:rgb(204,204,204)=
;border-left-width:1px;border-left-style:solid"><div dir=3D"ltr"><ul><li><s=
pan style=3D"font-family:arial,sans-serif;font-size:small">await_ready is p=
robably unnecessary, the check can be done within&nbsp;await_suspend.<br></=
span></li></ul></div></blockquote><div>There is an invisible "save state" t=
hat happens between await_ready and await_suspend. Having an await_ready al=
lows to bypass save state altogether and continue execution. </div><div><sp=
an style=3D"font-family:arial,sans-serif;font-size:small"><br></span></div>=
<blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;padding=
-left:1ex;border-left-color:rgb(204,204,204);border-left-width:1px;border-l=
eft-style:solid"><div dir=3D"ltr"><ul><li><span style=3D"font-family:arial,=
sans-serif;font-size:small">Appendix D: "Exceptionless error propagation...=
" is not really exceptionless:<br></span><span style=3D"font-family:arial,s=
ans-serif;font-size:small">if you await on a future which is already in err=
or-state (i.e. is_ready =3D=3D true), then await_suspend won't we executed =
and the exception won't be set for the promise, while in&nbsp;await_resume,=
 an exception will still be thrown.<br></span></li></ul></div></blockquote>=
<div>You are right. The fix would be to check in await ready if the future =
is in error and if so, return false, thus sending it onto await_suspend pat=
h.&nbsp;await_suspend has access to the promise and can set_exception direc=
tly.</div></div></blockquote><div><br></div><div>Except this incurs an unne=
cessary save-state (and suspension?) of the awaiting function, which it wou=
ld be nice to avoid. &nbsp;The simplest way I can see to avoid this would b=
e passing just the promise to an await function, although this potentially =
complicates the case where the promise type is void, e.g.</div><div><br></d=
iv><div>template &lt;typename _PromsieT&gt;</div><div>bool await_ready(_Pro=
miseT&amp;) const;</div><div>bool await_ready() const;</div><div><br></div>=
<div><br></div><div>--Shahms</div><div>&nbsp;</div><blockquote class=3D"gma=
il_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid=
;padding-left: 1ex;"><div dir=3D"ltr"><div>&nbsp;<span style=3D"font-family=
:arial,sans-serif;font-size:small"><br></span></div><blockquote class=3D"gm=
ail_quote" style=3D"margin:0px 0px 0px 0.8ex;padding-left:1ex;border-left-c=
olor:rgb(204,204,204);border-left-width:1px;border-left-style:solid"><div d=
ir=3D"ltr"><ul><li><font face=3D"arial, sans-serif" size=3D"2">I've&nbsp;im=
plemented such a thing myself, but wh</font>en await_result_t&lt;F&gt; is v=
oid, MSVC somewhat complains that promise::set_result doesn't take 1 argume=
nt, which I believe is a compiler bug.<font face=3D"arial, sans-serif" size=
=3D"2"><br></font></li></ul></div></blockquote><div>&nbsp;If you can send m=
e a self-contained repro, I can debug it and suggest a workaround (and fix =
it in MSVC as well)</div><div><br></div><div>Thank you very much for your f=
eedback.</div><div><br></div><div>Gor<font face=3D"arial, sans-serif" size=
=3D"2"><span style=3D"line-height:17px"><br></span></font></div></div></blo=
ckquote></div>

<p></p>

-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_144_625705513.1426179896840--
------=_Part_143_1940145023.1426179896840--

.


Author: Gor Nishanov <gornishanov@gmail.com>
Date: Fri, 13 Mar 2015 10:23:00 -0700
Raw View
--001a11c1dab292bf9105112ec022
Content-Type: text/plain; charset=UTF-8

I like it. Having await_ready to take promise as a parameter also
simplifies unpacking things like optional<T> or expected<T> where
suspension is not even an option.

I avoided doing it before to keep the await_xxx functions simple, but, now
we have at least two cases that can benefit from it.

On Thu, Mar 12, 2015 at 10:04 AM, <shahms.king@gmail.com> wrote:

>
>
> On Tuesday, January 20, 2015 at 6:07:54 PM UTC-8, Gor Nishanov wrote:
>>
>> Thank you very much for your feedback.
>>
>>
>>>    - It should be stated clear that a coroutine destroys itself, I
>>>    thought it's ref-counted and coroutine_handle is kinda intrinsic_ptr, but
>>>    it's not.
>>>
>>> Good point. I'll clarify that coroutine_handle is a low level class for
>> library implementers, concrete coroutines, such as generator have expected
>> RAII semantics and destroy the coroutine even if it is not fully executed.
>> You can find an example generator in the appendix
>>
>>
>>>
>>>    - await_ready is probably unnecessary, the check can be done
>>>    within await_suspend.
>>>
>>> There is an invisible "save state" that happens between await_ready and
>> await_suspend. Having an await_ready allows to bypass save state altogether
>> and continue execution.
>>
>>
>>>    - Appendix D: "Exceptionless error propagation..." is not really
>>>    exceptionless:
>>>    if you await on a future which is already in error-state (i.e.
>>>    is_ready == true), then await_suspend won't we executed and the exception
>>>    won't be set for the promise, while in await_resume, an exception will
>>>    still be thrown.
>>>
>>> You are right. The fix would be to check in await ready if the future is
>> in error and if so, return false, thus sending it onto await_suspend
>> path. await_suspend has access to the promise and can set_exception
>> directly.
>>
>
> Except this incurs an unnecessary save-state (and suspension?) of the
> awaiting function, which it would be nice to avoid.  The simplest way I can
> see to avoid this would be passing just the promise to an await function,
> although this potentially complicates the case where the promise type is
> void, e.g.
>
> template <typename _PromsieT>
> bool await_ready(_PromiseT&) const;
> bool await_ready() const;
>
>
> --Shahms
>
>
>>
>>
>>>
>>>    - I've implemented such a thing myself, but when await_result_t<F>
>>>    is void, MSVC somewhat complains that promise::set_result doesn't take 1
>>>    argument, which I believe is a compiler bug.
>>>
>>>  If you can send me a self-contained repro, I can debug it and suggest a
>> workaround (and fix it in MSVC as well)
>>
>> Thank you very much for your feedback.
>>
>> Gor
>>
>  --
>
> ---
> You received this message because you are subscribed to a topic in the
> Google Groups "ISO C++ Standard - Future Proposals" group.
> To unsubscribe from this topic, visit
> https://groups.google.com/a/isocpp.org/d/topic/std-proposals/RF7OEseYcHI/unsubscribe
> .
> To unsubscribe from this group and all its topics, send an email to
> std-proposals+unsubscribe@isocpp.org.
> To post to this group, send email to std-proposals@isocpp.org.
> Visit this group at
> http://groups.google.com/a/isocpp.org/group/std-proposals/.
>

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

--001a11c1dab292bf9105112ec022
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div>I like it. Having await_ready to take promise as a pa=
rameter also simplifies unpacking things like optional&lt;T&gt; or expected=
&lt;T&gt; where suspension is not even an option.</div><div><br></div><div>=
I avoided doing it before to keep the await_xxx functions simple, but, now =
we have at least two cases that can benefit from it.</div></div><div class=
=3D"gmail_extra"><br><div class=3D"gmail_quote">On Thu, Mar 12, 2015 at 10:=
04 AM,  <span dir=3D"ltr">&lt;<a href=3D"mailto:shahms.king@gmail.com" targ=
et=3D"_blank">shahms.king@gmail.com</a>&gt;</span> wrote:<br><blockquote cl=
ass=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;p=
adding-left:1ex"><div dir=3D"ltr"><span><br><br>On Tuesday, January 20, 201=
5 at 6:07:54 PM UTC-8, Gor Nishanov wrote:<blockquote class=3D"gmail_quote"=
 style=3D"margin:0px 0px 0px 0.8ex;padding-left:1ex;border-left-color:rgb(2=
04,204,204);border-left-width:1px;border-left-style:solid"><div dir=3D"ltr"=
>Thank you very much for your feedback.<br><br><blockquote class=3D"gmail_q=
uote" style=3D"margin:0px 0px 0px 0.8ex;padding-left:1ex;border-left-color:=
rgb(204,204,204);border-left-width:1px;border-left-style:solid"><div dir=3D=
"ltr"><ul><li style=3D"font-family:arial,sans-serif;font-size:small">It sho=
uld be stated clear that a coroutine destroys itself, I thought it&#39;s re=
f-counted and=C2=A0coroutine_handle is kinda intrinsic_ptr, but it&#39;s no=
t.<br></li></ul></div></blockquote><div>Good point. I&#39;ll clarify that c=
oroutine_handle is a low level class for library implementers, concrete cor=
outines, such as generator have expected RAII semantics and destroy the cor=
outine even if it is not fully executed. You can find an example generator =
in the appendix</div><div>=C2=A0</div><blockquote class=3D"gmail_quote" sty=
le=3D"margin:0px 0px 0px 0.8ex;padding-left:1ex;border-left-color:rgb(204,2=
04,204);border-left-width:1px;border-left-style:solid"><div dir=3D"ltr"><ul=
><li><span style=3D"font-family:arial,sans-serif;font-size:small">await_rea=
dy is probably unnecessary, the check can be done within=C2=A0await_suspend=
..<br></span></li></ul></div></blockquote><div>There is an invisible &quot;s=
ave state&quot; that happens between await_ready and await_suspend. Having =
an await_ready allows to bypass save state altogether and continue executio=
n. </div><div><span style=3D"font-family:arial,sans-serif;font-size:small">=
<br></span></div><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px =
0px 0.8ex;padding-left:1ex;border-left-color:rgb(204,204,204);border-left-w=
idth:1px;border-left-style:solid"><div dir=3D"ltr"><ul><li><span style=3D"f=
ont-family:arial,sans-serif;font-size:small">Appendix D: &quot;Exceptionles=
s error propagation...&quot; is not really exceptionless:<br></span><span s=
tyle=3D"font-family:arial,sans-serif;font-size:small">if you await on a fut=
ure which is already in error-state (i.e. is_ready =3D=3D true), then await=
_suspend won&#39;t we executed and the exception won&#39;t be set for the p=
romise, while in=C2=A0await_resume, an exception will still be thrown.<br><=
/span></li></ul></div></blockquote><div>You are right. The fix would be to =
check in await ready if the future is in error and if so, return false, thu=
s sending it onto await_suspend path.=C2=A0await_suspend has access to the =
promise and can set_exception directly.</div></div></blockquote><div><br></=
div></span><div>Except this incurs an unnecessary save-state (and suspensio=
n?) of the awaiting function, which it would be nice to avoid.=C2=A0 The si=
mplest way I can see to avoid this would be passing just the promise to an =
await function, although this potentially complicates the case where the pr=
omise type is void, e.g.</div><div><br></div><div>template &lt;typename _Pr=
omsieT&gt;</div><div>bool await_ready(_PromiseT&amp;) const;</div><div>bool=
 await_ready() const;</div><div><br></div><div><br></div><div>--Shahms</div=
><span><div>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"margin:0=
px 0px 0px 0.8ex;padding-left:1ex;border-left-color:rgb(204,204,204);border=
-left-width:1px;border-left-style:solid"><div dir=3D"ltr"><div>=C2=A0<span =
style=3D"font-family:arial,sans-serif;font-size:small"><br></span></div><bl=
ockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;padding-le=
ft:1ex;border-left-color:rgb(204,204,204);border-left-width:1px;border-left=
-style:solid"><div dir=3D"ltr"><ul><li><font face=3D"arial, sans-serif">I&#=
39;ve=C2=A0implemented such a thing myself, but wh</font>en await_result_t&=
lt;F&gt; is void, MSVC somewhat complains that promise::set_result doesn&#3=
9;t take 1 argument, which I believe is a compiler bug.<font face=3D"arial,=
 sans-serif"><br></font></li></ul></div></blockquote><div>=C2=A0If you can =
send me a self-contained repro, I can debug it and suggest a workaround (an=
d fix it in MSVC as well)</div><div><br></div><div>Thank you very much for =
your feedback.</div><div><br></div><div>Gor<font face=3D"arial, sans-serif"=
><span style=3D"line-height:17px"><br></span></font></div></div></blockquot=
e></span></div><div class=3D"HOEnZb"><div class=3D"h5">

<p></p>

-- <br>
<br>
--- <br>
You received this message because you are subscribed to a topic in the Goog=
le Groups &quot;ISO C++ Standard - Future Proposals&quot; group.<br>
To unsubscribe from this topic, visit <a href=3D"https://groups.google.com/=
a/isocpp.org/d/topic/std-proposals/RF7OEseYcHI/unsubscribe" target=3D"_blan=
k">https://groups.google.com/a/isocpp.org/d/topic/std-proposals/RF7OEseYcHI=
/unsubscribe</a>.<br>
To unsubscribe from this group and all its topics, send an email to <a href=
=3D"mailto:std-proposals+unsubscribe@isocpp.org" target=3D"_blank">std-prop=
osals+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">std-proposals@isocpp.org</a>.<br>
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/" target=3D"_blank">http://groups.google.com/a/isocpp.org/gro=
up/std-proposals/</a>.<br>
</div></div></blockquote></div><br></div>

<p></p>

-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--001a11c1dab292bf9105112ec022--

.


Author: Gor Nishanov <gornishanov@gmail.com>
Date: Fri, 13 Mar 2015 13:16:25 -0700
Raw View
--001a11c2d3b2c2cde50511312cbb
Content-Type: text/plain; charset=UTF-8

Hi Tongari:

I apologize not getting back to your earlier. Two of the bugs you mentioned
are fixed and the fix will be available in VS 2015 RC coming out soon.


> std::future<void> task()
> {
>  std::vector<int> v(100);
>  await std::suspend_always{};
>  // Both the data of vector and the coroutine frame itself are leaked!
> }
>
> It's quite dangerous - I didn't allocate anything explicitly but I leaked
> resources implicitly.
>

This is related to lifetime of an object referred to by the future.
std::future is somewhat of two minds here. For the futures returned from
std::async it will block in the destructor. For futures obtained via
..get_future() from promise, it will leak the asynchronous activity and
allow it to live beyond the lifetime of the future.

So, if a library developer choose to bind lifetime coroutine to a task
object returned from the coroutine, library designer can chose to cancel
the coroutine synchronously (which may result in blocking in the task
object destructor until coroutine is destroyed, initiate cancellation but
don't wait for it to complete, or just leak it, as std::future is doing)


> Can I find the info somewhere in the paper? Doesn't "save state" happen in
> suspend-resume-point?
>

This is an implementation detail that is not exposed in the paper. The
reason why "save" cannot be done as suspend-resume point is that by the
time await_suspend returns, a different thread may have already resumed the
coroutine, it run to completion and has its memory destroyed.

Thus saving at suspend point is too late.


>
>>>    -
>>>
>>> People on Boost ML also pointed out that the use of `future.then` in
> `await_suspend` is incorrect because it's expected to block when the
> returned future dies.
>

Can you provide more details on this.


> And I wonder if the exceptionless mechanism & exception way are mutually
> exclusive? Can we write an awaitable type in uniform fashion regardless if
> exception is available or not?
>

Somewhat.

If a particular awaitable is written with exception short-circuiting, it
means that:

try { await bla(); } catch(...) { bar(); }

will never execute bar, since exception reported by bla() will immediately
result in completion of the current coroutine and setting set_error on its
promise.

If you expect something to fail, you will need some kind of wrapper to to
transform future<T> that can throw into future<expected<T>> that never
throws. and then use expected.error() to figure out what you want to do.

auto result = await as_expected(bla());
if (result.error()) bar;
else doSomething(result.value());



> so I concluded that we can't have an exceptionless awaitable
> implementation that can be also used in exception context, is that correct?
>

It can with some extra typing. I assume that expected<T>::value() will
throw if error is stored, than to transform, "awaitable that supports
exception-short circuiting, into awaitable that throws on error, will be
something like:

(await as_expected(bla()).value();

Thank you for the bug reports and yes, it should be possible to write
when_any / when_all for arbitrary awaitables.

Gor

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

--001a11c2d3b2c2cde50511312cbb
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div>Hi Tongari:</div><div><br></div><div>I apologize not =
getting back to your earlier. Two of the bugs you mentioned are fixed and t=
he fix will be available in VS 2015 RC coming out soon.</div><div><br></div=
><div class=3D"gmail_extra"><div class=3D"gmail_quote"><blockquote class=3D=
"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;padding-left:1ex;border-lef=
t-color:rgb(204,204,204);border-left-width:1px;border-left-style:solid"><di=
v dir=3D"ltr"><div style=3D"font-family:arial,sans-serif;font-size:small"><=
br></div><div style=3D"border:1px solid rgb(187,187,187);background-color:r=
gb(250,250,250)"><code><div><span style=3D"color:rgb(0,0,0)">std</span><spa=
n style=3D"color:rgb(102,102,0)">::</span><span style=3D"color:rgb(0,0,0)">=
future</span><span style=3D"color:rgb(0,136,0)">&lt;void&gt;</span><span st=
yle=3D"color:rgb(0,0,0)"> task</span><span style=3D"color:rgb(102,102,0)">(=
)</span><span style=3D"color:rgb(0,0,0)"><br></span><span style=3D"color:rg=
b(102,102,0)">{</span><span style=3D"color:rgb(0,0,0)"><br>=C2=A0std</span>=
<span style=3D"color:rgb(102,102,0)">::</span><span style=3D"color:rgb(0,0,=
0)">vector</span><span style=3D"color:rgb(0,136,0)">&lt;int&gt;</span><span=
 style=3D"color:rgb(0,0,0)"> v</span><span style=3D"color:rgb(102,102,0)">(=
</span><span style=3D"color:rgb(0,102,102)">100</span><span style=3D"color:=
rgb(102,102,0)">);</span><span style=3D"color:rgb(0,0,0)"><br>=C2=A0await s=
td</span><span style=3D"color:rgb(102,102,0)">::</span><span style=3D"color=
:rgb(0,0,0)">suspend_always</span><span style=3D"color:rgb(102,102,0)">{};<=
/span><span style=3D"color:rgb(0,0,0)"><br>=C2=A0</span><span style=3D"colo=
r:rgb(136,0,0)">// Both the data of vector and the coroutine frame itself a=
re leaked!</span><span style=3D"color:rgb(0,0,0)"><br></span><span style=3D=
"color:rgb(102,102,0)">}</span></div></code></div><br>It&#39;s quite danger=
ous - I didn&#39;t allocate anything explicitly but I leaked resources impl=
icitly.=C2=A0</div></blockquote><div><br></div><div>This is related to life=
time of=C2=A0an object referred to by the future.</div><div>std::future is =
somewhat of two minds here. For the futures returned from std::async it wil=
l block in the destructor. For futures obtained via .get_future() from prom=
ise, it will leak the asynchronous activity and allow it to live beyond the=
 lifetime of the future.</div><div><br></div><div>So, if a library develope=
r choose to bind lifetime coroutine to a=C2=A0task object returned from the=
 coroutine, library designer can chose to cancel the coroutine synchronousl=
y (which may result in blocking in the task object destructor until corouti=
ne is destroyed, initiate cancellation but don&#39;t wait for it to complet=
e, or just leak it, as std::future is doing)</div><div>=C2=A0<span><br></sp=
an></div><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8e=
x;padding-left:1ex;border-left-color:rgb(204,204,204);border-left-width:1px=
;border-left-style:solid"><div dir=3D"ltr"><div>Can I find the info somewhe=
re in the paper? Doesn&#39;t &quot;save state&quot; happen in suspend-resum=
e-point?</div></div></blockquote><div><br></div><div>This is an implementat=
ion detail that is not exposed in the paper. The reason why &quot;save&quot=
; cannot be done as suspend-resume point is that by the time await_suspend =
returns, a different thread may have already resumed the coroutine, it run =
to completion and has its memory destroyed.</div><div><br>Thus saving at su=
spend point is too late.</div><div>=C2=A0</div><blockquote class=3D"gmail_q=
uote" style=3D"margin:0px 0px 0px 0.8ex;padding-left:1ex;border-left-color:=
rgb(204,204,204);border-left-width:1px;border-left-style:solid"><div dir=3D=
"ltr"><span><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0=
..8ex;padding-left:1ex;border-left-color:rgb(204,204,204);border-left-width:=
1px;border-left-style:solid"><div dir=3D"ltr"><blockquote class=3D"gmail_qu=
ote" style=3D"margin:0px 0px 0px 0.8ex;padding-left:1ex;border-left-color:r=
gb(204,204,204);border-left-width:1px;border-left-style:solid"><div dir=3D"=
ltr"><ul><li><br></li></ul></div></blockquote></div></blockquote></span><di=
v>People on Boost ML also pointed out that the use of `future.then` in `awa=
it_suspend` is incorrect because it&#39;s expected to block when the return=
ed future dies.<br></div></div></blockquote><div><br></div><div>Can you pro=
vide more details on this.=C2=A0</div><div>=C2=A0</div><blockquote class=3D=
"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;padding-left:1ex;border-lef=
t-color:rgb(204,204,204);border-left-width:1px;border-left-style:solid"><di=
v dir=3D"ltr"><div></div><div>And I wonder if the exceptionless mechanism &=
amp; exception way are mutually exclusive? Can we write an awaitable type i=
n uniform fashion regardless if exception is available or not?</div></div><=
/blockquote><div><br></div><div>Somewhat.</div><div><br></div><div>If a par=
ticular awaitable is written with exception short-circuiting, it means that=
:</div><div><br></div><div>try { await bla(); } catch(...) { bar(); } </div=
><div><br></div><div>will never execute bar, since exception reported by bl=
a() will immediately result in completion of the current coroutine and sett=
ing set_error on its promise.</div><div><br></div><div>If you expect=C2=A0s=
omething to fail, you will need some kind of wrapper to=C2=A0to transform=
=C2=A0future&lt;T&gt;=C2=A0that can throw into future&lt;expected&lt;T&gt;&=
gt; that=C2=A0never throws. and then use expected.error() to figure out wha=
t you want to do.</div><div><br></div><div>auto=C2=A0result =3D await as_ex=
pected(bla());=C2=A0</div><div>if (result.error()) bar;</div><div>else doSo=
mething(result.value());</div><div><br></div><div>=C2=A0<br></div><blockquo=
te class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;padding-left:1ex=
;border-left-color:rgb(204,204,204);border-left-width:1px;border-left-style=
:solid"><div dir=3D"ltr"><div>so I concluded that we can&#39;t have an exce=
ptionless awaitable implementation that can be also used in exception conte=
xt, is that correct?</div></div></blockquote><div><br></div><div>It can wit=
h some extra typing.=C2=A0I assume that expected&lt;T&gt;::value() will thr=
ow if error is stored, than to transform, &quot;awaitable that supports exc=
eption-short circuiting, into awaitable that throws on error, will be somet=
hing like:</div><div><br></div><div>(await as_expected(bla()).value();</div=
><div>=C2=A0</div><div>Thank you for the bug reports and yes, it should be =
possible to write when_any / when_all=C2=A0for arbitrary awaitables.</div><=
div><br>Gor</div></div><br></div></div>

<p></p>

-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--001a11c2d3b2c2cde50511312cbb--

.


Author: TONGARI J <tongari95@gmail.com>
Date: Sat, 14 Mar 2015 15:37:53 +0800
Raw View
--089e01184e22da8e8905113ab137
Content-Type: text/plain; charset=UTF-8

Hi Gor,

glad to hear from you :)

2015-03-14 4:16 GMT+08:00 Gor Nishanov <gornishanov@gmail.com>:

> Hi Tongari:
>
> I apologize not getting back to your earlier. Two of the bugs you
> mentioned are fixed and the fix will be available in VS 2015 RC coming out
> soon.
>

Great news!


> std::future<void> task()
>> {
>>  std::vector<int> v(100);
>>  await std::suspend_always{};
>>  // Both the data of vector and the coroutine frame itself are leaked!
>> }
>>
>> It's quite dangerous - I didn't allocate anything explicitly but I leaked
>> resources implicitly.
>>
>
> This is related to lifetime of an object referred to by the future.
> std::future is somewhat of two minds here. For the futures returned from
> std::async it will block in the destructor. For futures obtained via
> .get_future() from promise, it will leak the asynchronous activity and
> allow it to live beyond the lifetime of the future.
>
> So, if a library developer choose to bind lifetime coroutine to a task
> object returned from the coroutine, library designer can chose to cancel
> the coroutine synchronously (which may result in blocking in the task
> object destructor until coroutine is destroyed, initiate cancellation but
> don't wait for it to complete, or just leak it, as std::future is doing)
>

The problem is not restricted to std::future, the use of std::future is
just for example. The problem I wanted to show is that `coroutine_handle`
is just like raw-pointer, no RAII, that is, if the awaiter just drop the
coroutine_handle and so doesn't call it eventually, the coroutine-context
is lost forever (i.e. memory leak).

Instead, if you make coroutine_handle ref-counted, it will destroys the
coroutine-context finally if no one refers to that, so even if the awaiter
just drop the coroutine_handle, it's safe that the resource will be
collected.


> Can I find the info somewhere in the paper? Doesn't "save state" happen in
>> suspend-resume-point?
>>
>
> This is an implementation detail that is not exposed in the paper. The
> reason why "save" cannot be done as suspend-resume point is that by the
> time await_suspend returns, a different thread may have already resumed the
> coroutine, it run to completion and has its memory destroyed.
>
> Thus saving at suspend point is too late.
>

Yeah, after implementing an emulation library myself, I understand that
well now.

>
>>>>    -
>>>>
>>>> People on Boost ML also pointed out that the use of `future.then` in
>> `await_suspend` is incorrect because it's expected to block when the
>> returned future dies.
>>
>
> Can you provide more details on this.
>

The future returned from future.then is like the one returned from
std::async, it will block in the destructor.

See: http://tinyurl.com/kt9kd3o


> And I wonder if the exceptionless mechanism & exception way are mutually
>> exclusive? Can we write an awaitable type in uniform fashion regardless if
>> exception is available or not?
>>
>
> Somewhat.
>
> If a particular awaitable is written with exception short-circuiting, it
> means that:
>
> try { await bla(); } catch(...) { bar(); }
>
> will never execute bar, since exception reported by bla() will immediately
> result in completion of the current coroutine and setting set_error on its
> promise.
>
> If you expect something to fail, you will need some kind of wrapper to to
> transform future<T> that can throw into future<expected<T>> that never
> throws. and then use expected.error() to figure out what you want to do.
>
> auto result = await as_expected(bla());
> if (result.error()) bar;
> else doSomething(result.value());
>
>
>
>> so I concluded that we can't have an exceptionless awaitable
>> implementation that can be also used in exception context, is that correct?
>>
>
> It can with some extra typing. I assume that expected<T>::value() will
> throw if error is stored, than to transform, "awaitable that supports
> exception-short circuiting, into awaitable that throws on error, will be
> something like:
>
> (await as_expected(bla()).value();
>
> Thank you for the bug reports and yes, it should be possible to write
> when_any / when_all for arbitrary awaitables.
>

In the meantime waiting for your progress, I've implemented an emulation
library called CO2:

    https://github.com/jamboree/co2

which diverges from N4286 a bit:

    https://github.com/jamboree/co2#difference-from-n4286

that is, it's ref-counted and thus doesn't need `final_suspend` (replaced
with `finalize`).

What do you think about the optional customization points (i.e.
before_resume/after_suspend) for promise?

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

--089e01184e22da8e8905113ab137
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">Hi Gor,<div><br></div><div>glad to hear from you :)<br><di=
v class=3D"gmail_extra"><br><div class=3D"gmail_quote">2015-03-14 4:16 GMT+=
08:00 Gor Nishanov <span dir=3D"ltr">&lt;<a href=3D"mailto:gornishanov@gmai=
l.com" target=3D"_blank">gornishanov@gmail.com</a>&gt;</span>:<br><blockquo=
te class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left-widt=
h:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-le=
ft:1ex"><div dir=3D"ltr"><div>Hi Tongari:</div><div><br></div><div>I apolog=
ize not getting back to your earlier. Two of the bugs you mentioned are fix=
ed and the fix will be available in VS 2015 RC coming out soon.</div></div>=
</blockquote><div><br></div><div>Great news!=C2=A0</div><div>=C2=A0</div><b=
lockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-le=
ft-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;pad=
ding-left:1ex"><div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gm=
ail_quote"><span class=3D""><blockquote class=3D"gmail_quote" style=3D"marg=
in:0px 0px 0px 0.8ex;padding-left:1ex;border-left-color:rgb(204,204,204);bo=
rder-left-width:1px;border-left-style:solid"><div dir=3D"ltr"><div style=3D=
"font-family:arial,sans-serif;font-size:small"></div><div style=3D"border:1=
px solid rgb(187,187,187);background-color:rgb(250,250,250)"><code><div><sp=
an style=3D"color:rgb(0,0,0)">std</span><span style=3D"color:rgb(102,102,0)=
">::</span><span style=3D"color:rgb(0,0,0)">future</span><span style=3D"col=
or:rgb(0,136,0)">&lt;void&gt;</span><span style=3D"color:rgb(0,0,0)"> task<=
/span><span style=3D"color:rgb(102,102,0)">()</span><span style=3D"color:rg=
b(0,0,0)"><br></span><span style=3D"color:rgb(102,102,0)">{</span><span sty=
le=3D"color:rgb(0,0,0)"><br>=C2=A0std</span><span style=3D"color:rgb(102,10=
2,0)">::</span><span style=3D"color:rgb(0,0,0)">vector</span><span style=3D=
"color:rgb(0,136,0)">&lt;int&gt;</span><span style=3D"color:rgb(0,0,0)"> v<=
/span><span style=3D"color:rgb(102,102,0)">(</span><span style=3D"color:rgb=
(0,102,102)">100</span><span style=3D"color:rgb(102,102,0)">);</span><span =
style=3D"color:rgb(0,0,0)"><br>=C2=A0await std</span><span style=3D"color:r=
gb(102,102,0)">::</span><span style=3D"color:rgb(0,0,0)">suspend_always</sp=
an><span style=3D"color:rgb(102,102,0)">{};</span><span style=3D"color:rgb(=
0,0,0)"><br>=C2=A0</span><span style=3D"color:rgb(136,0,0)">// Both the dat=
a of vector and the coroutine frame itself are leaked!</span><span style=3D=
"color:rgb(0,0,0)"><br></span><span style=3D"color:rgb(102,102,0)">}</span>=
</div></code></div><br>It&#39;s quite dangerous - I didn&#39;t allocate any=
thing explicitly but I leaked resources implicitly.=C2=A0</div></blockquote=
><div><br></div></span><div>This is related to lifetime of=C2=A0an object r=
eferred to by the future.</div><div>std::future is somewhat of two minds he=
re. For the futures returned from std::async it will block in the destructo=
r. For futures obtained via .get_future() from promise, it will leak the as=
ynchronous activity and allow it to live beyond the lifetime of the future.=
</div><div><br></div><div>So, if a library developer choose to bind lifetim=
e coroutine to a=C2=A0task object returned from the coroutine, library desi=
gner can chose to cancel the coroutine synchronously (which may result in b=
locking in the task object destructor until coroutine is destroyed, initiat=
e cancellation but don&#39;t wait for it to complete, or just leak it, as s=
td::future is doing)</div></div></div></div></blockquote><div><br></div><di=
v>The problem is not restricted to std::future, the use of std::future is j=
ust for example. The problem I wanted to show is that `coroutine_handle` is=
 just like raw-pointer, no RAII, that is, if the awaiter just drop the coro=
utine_handle and so doesn&#39;t call it eventually, the coroutine-context i=
s lost forever (i.e. memory leak).</div><div><br></div><div>Instead, if you=
 make coroutine_handle ref-counted, it will destroys the coroutine-context =
finally if no one refers to that, so even if the awaiter just drop the coro=
utine_handle, it&#39;s safe that the resource will be collected.</div><div>=
=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0=
..8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-s=
tyle:solid;padding-left:1ex"><div dir=3D"ltr"><div class=3D"gmail_extra"><d=
iv class=3D"gmail_quote"><span class=3D""><div><span></span></div><blockquo=
te class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;padding-left:1ex=
;border-left-color:rgb(204,204,204);border-left-width:1px;border-left-style=
:solid"><div dir=3D"ltr"><div>Can I find the info somewhere in the paper? D=
oesn&#39;t &quot;save state&quot; happen in suspend-resume-point?</div></di=
v></blockquote><div><br></div></span><div>This is an implementation detail =
that is not exposed in the paper. The reason why &quot;save&quot; cannot be=
 done as suspend-resume point is that by the time await_suspend returns, a =
different thread may have already resumed the coroutine, it run to completi=
on and has its memory destroyed.</div><div><br>Thus saving at suspend point=
 is too late.</div></div></div></div></blockquote><div><br></div><div>Yeah,=
 after implementing an emulation library myself, I understand that well now=
..=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px =
0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-=
style:solid;padding-left:1ex"><div dir=3D"ltr"><div class=3D"gmail_extra"><=
div class=3D"gmail_quote"><span class=3D""><blockquote class=3D"gmail_quote=
" style=3D"margin:0px 0px 0px 0.8ex;padding-left:1ex;border-left-color:rgb(=
204,204,204);border-left-width:1px;border-left-style:solid"><div dir=3D"ltr=
"><span><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex=
;padding-left:1ex;border-left-color:rgb(204,204,204);border-left-width:1px;=
border-left-style:solid"><div dir=3D"ltr"><blockquote class=3D"gmail_quote"=
 style=3D"margin:0px 0px 0px 0.8ex;padding-left:1ex;border-left-color:rgb(2=
04,204,204);border-left-width:1px;border-left-style:solid"><div dir=3D"ltr"=
><ul><li><br></li></ul></div></blockquote></div></blockquote></span><div>Pe=
ople on Boost ML also pointed out that the use of `future.then` in `await_s=
uspend` is incorrect because it&#39;s expected to block when the returned f=
uture dies.<br></div></div></blockquote><div><br></div></span><div>Can you =
provide more details on this.=C2=A0</div></div></div></div></blockquote><di=
v><br></div><div>The future returned from future.then is like the one retur=
ned from std::async, it will block in the destructor.</div><div><br></div><=
div>See:=C2=A0<a href=3D"http://tinyurl.com/kt9kd3o">http://tinyurl.com/kt9=
kd3o</a></div><div>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"m=
argin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204=
,204);border-left-style:solid;padding-left:1ex"><div dir=3D"ltr"><div class=
=3D"gmail_extra"><div class=3D"gmail_quote"><span class=3D""><blockquote cl=
ass=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;padding-left:1ex;bord=
er-left-color:rgb(204,204,204);border-left-width:1px;border-left-style:soli=
d"><div dir=3D"ltr"><div></div><div>And I wonder if the exceptionless mecha=
nism &amp; exception way are mutually exclusive? Can we write an awaitable =
type in uniform fashion regardless if exception is available or not?</div><=
/div></blockquote><div><br></div></span><div>Somewhat.</div><div><br></div>=
<div>If a particular awaitable is written with exception short-circuiting, =
it means that:</div><div><br></div><div>try { await bla(); } catch(...) { b=
ar(); } </div><div><br></div><div>will never execute bar, since exception r=
eported by bla() will immediately result in completion of the current corou=
tine and setting set_error on its promise.</div><div><br></div><div>If you =
expect=C2=A0something to fail, you will need some kind of wrapper to=C2=A0t=
o transform=C2=A0future&lt;T&gt;=C2=A0that can throw into future&lt;expecte=
d&lt;T&gt;&gt; that=C2=A0never throws. and then use expected.error() to fig=
ure out what you want to do.</div><div><br></div><div>auto=C2=A0result =3D =
await as_expected(bla());=C2=A0</div><div>if (result.error()) bar;</div><di=
v>else doSomething(result.value());</div><span class=3D""><div><br></div><d=
iv>=C2=A0<br></div><blockquote class=3D"gmail_quote" style=3D"margin:0px 0p=
x 0px 0.8ex;padding-left:1ex;border-left-color:rgb(204,204,204);border-left=
-width:1px;border-left-style:solid"><div dir=3D"ltr"><div>so I concluded th=
at we can&#39;t have an exceptionless awaitable implementation that can be =
also used in exception context, is that correct?</div></div></blockquote><d=
iv><br></div></span><div>It can with some extra typing.=C2=A0I assume that =
expected&lt;T&gt;::value() will throw if error is stored, than to transform=
, &quot;awaitable that supports exception-short circuiting, into awaitable =
that throws on error, will be something like:</div><div><br></div><div>(awa=
it as_expected(bla()).value();</div><div>=C2=A0</div><div>Thank you for the=
 bug reports and yes, it should be possible to write when_any / when_all=C2=
=A0for arbitrary awaitables.</div></div></div></div></blockquote><div><br><=
/div><div>In the meantime waiting for your progress, I&#39;ve implemented a=
n emulation library called CO2:</div><div><br></div><div>=C2=A0 =C2=A0 <a h=
ref=3D"https://github.com/jamboree/co2">https://github.com/jamboree/co2</a>=
<br></div><div><br></div><div>which diverges from N4286 a bit:</div><div><b=
r></div><div>=C2=A0 =C2=A0 <a href=3D"https://github.com/jamboree/co2#diffe=
rence-from-n4286">https://github.com/jamboree/co2#difference-from-n4286</a>=
</div><div><br></div><div>that is, it&#39;s ref-counted and thus doesn&#39;=
t need `final_suspend` (replaced with `finalize`).</div><div><br></div><div=
>What do you think about the optional=C2=A0customization points (i.e. befor=
e_resume/after_suspend) for promise?</div></div></div></div></div>

<p></p>

-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--089e01184e22da8e8905113ab137--

.


Author: Shahms King <shahms.king@gmail.com>
Date: Tue, 17 Mar 2015 19:51:48 +0000
Raw View
--001a113a6786168d900511814c5d
Content-Type: text/plain; charset=UTF-8

On Fri, Mar 13, 2015 at 10:23 AM Gor Nishanov <gornishanov@gmail.com> wrote:

> I like it. Having await_ready to take promise as a parameter also
> simplifies unpacking things like optional<T> or expected<T> where
> suspension is not even an option.
>
> I avoided doing it before to keep the await_xxx functions simple, but, now
> we have at least two cases that can benefit from it.
>

Thanks, my comment came after attempting to implement the requisite
interfaces for a type similar to expected<T> in an exception-less
environment.

After a bit of thought, it occurs to me that the current proposal may also
defeat opportunities for optimization in the case where the awaited-on
object is always "ready" as would be the case for optional<T> or
expected<T>.

While I don't have any experience with such things, it would be nice if
await could be as close to zero-overhead as possible and am suspicious that
the mere inclusion of the suspend-point may preclude optimizations.

In that vein, I wonder if allowing the omission or explicit deletion of
await_suspend(coroutine_handle<T>) for always-ready types wouldn't be
desirable?

--Shahms


> On Thu, Mar 12, 2015 at 10:04 AM, <shahms.king@gmail.com> wrote:
>
>>
>>
>> On Tuesday, January 20, 2015 at 6:07:54 PM UTC-8, Gor Nishanov wrote:
>>>
>>> Thank you very much for your feedback.
>>>
>>>
>>>>    - It should be stated clear that a coroutine destroys itself, I
>>>>    thought it's ref-counted and coroutine_handle is kinda intrinsic_ptr, but
>>>>    it's not.
>>>>
>>>> Good point. I'll clarify that coroutine_handle is a low level class for
>>> library implementers, concrete coroutines, such as generator have expected
>>> RAII semantics and destroy the coroutine even if it is not fully executed.
>>> You can find an example generator in the appendix
>>>
>>>
>>>>
>>>>    - await_ready is probably unnecessary, the check can be done
>>>>    within await_suspend.
>>>>
>>>> There is an invisible "save state" that happens between await_ready and
>>> await_suspend. Having an await_ready allows to bypass save state altogether
>>> and continue execution.
>>>
>>>
>>>>    - Appendix D: "Exceptionless error propagation..." is not really
>>>>    exceptionless:
>>>>    if you await on a future which is already in error-state (i.e.
>>>>    is_ready == true), then await_suspend won't we executed and the exception
>>>>    won't be set for the promise, while in await_resume, an exception will
>>>>    still be thrown.
>>>>
>>>> You are right. The fix would be to check in await ready if the future
>>> is in error and if so, return false, thus sending it onto await_suspend
>>> path. await_suspend has access to the promise and can set_exception
>>> directly.
>>>
>>
>> Except this incurs an unnecessary save-state (and suspension?) of the
>> awaiting function, which it would be nice to avoid.  The simplest way I can
>> see to avoid this would be passing just the promise to an await function,
>> although this potentially complicates the case where the promise type is
>> void, e.g.
>>
>> template <typename _PromsieT>
>> bool await_ready(_PromiseT&) const;
>> bool await_ready() const;
>>
>>
>> --Shahms
>>
>>
>>>
>>>
>>>>
>>>>    - I've implemented such a thing myself, but when await_result_t<F>
>>>>    is void, MSVC somewhat complains that promise::set_result doesn't take 1
>>>>    argument, which I believe is a compiler bug.
>>>>
>>>>  If you can send me a self-contained repro, I can debug it and suggest
>>> a workaround (and fix it in MSVC as well)
>>>
>>> Thank you very much for your feedback.
>>>
>>> Gor
>>>
>>  --
>>
>> ---
>> You received this message because you are subscribed to a topic in the
>> Google Groups "ISO C++ Standard - Future Proposals" group.
>> To unsubscribe from this topic, visit
>> https://groups.google.com/a/isocpp.org/d/topic/std-proposals/RF7OEseYcHI/unsubscribe
>> .
>> To unsubscribe from this group and all its topics, send an email to
>> std-proposals+unsubscribe@isocpp.org.
>> To post to this group, send email to std-proposals@isocpp.org.
>> Visit this group at
>> http://groups.google.com/a/isocpp.org/group/std-proposals/.
>>
>
>  --
>
> ---
> You received this message because you are subscribed to a topic in the
> Google Groups "ISO C++ Standard - Future Proposals" group.
> To unsubscribe from this topic, visit
> https://groups.google.com/a/isocpp.org/d/topic/std-proposals/RF7OEseYcHI/unsubscribe
> .
> To unsubscribe from this group and all its topics, send an email to
> std-proposals+unsubscribe@isocpp.org.
> To post to this group, send email to std-proposals@isocpp.org.
> Visit this group at
> http://groups.google.com/a/isocpp.org/group/std-proposals/.
>

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

--001a113a6786168d900511814c5d
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br><div class=3D"gmail_quote">On Fri, Mar 13, 2015 at=
 10:23 AM Gor Nishanov &lt;<a href=3D"mailto:gornishanov@gmail.com">gornish=
anov@gmail.com</a>&gt; wrote:<br><blockquote class=3D"gmail_quote" style=3D=
"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D=
"ltr"><div>I like it. Having await_ready to take promise as a parameter als=
o simplifies unpacking things like optional&lt;T&gt; or expected&lt;T&gt; w=
here suspension is not even an option.</div><div><br></div><div>I avoided d=
oing it before to keep the await_xxx functions simple, but, now we have at =
least two cases that can benefit from it.</div></div></blockquote><div><br>=
</div><div>Thanks, my comment came after attempting to implement the requis=
ite interfaces for a type similar to expected&lt;T&gt; in an exception-less=
 environment. =C2=A0</div><div><br></div><div>After a bit of thought, it oc=
curs to me that the current proposal may also defeat opportunities for opti=
mization in the case where the awaited-on object is always &quot;ready&quot=
; as would be the case for optional&lt;T&gt; or expected&lt;T&gt;.</div><di=
v><br></div><div>While I don&#39;t have any experience with such things, it=
 would be nice if await could be as close to zero-overhead as possible and =
am suspicious that the mere inclusion of the suspend-point may preclude opt=
imizations.</div><div><br></div><div>In that vein, I wonder if allowing the=
 omission or explicit deletion of await_suspend(coroutine_handle&lt;T&gt;) =
for always-ready types wouldn&#39;t be desirable?</div><div><br></div><div>=
--Shahms</div><div><br></div><blockquote class=3D"gmail_quote" style=3D"mar=
gin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class=3D"g=
mail_extra"><br><div class=3D"gmail_quote">On Thu, Mar 12, 2015 at 10:04 AM=
,  <span dir=3D"ltr">&lt;<a href=3D"mailto:shahms.king@gmail.com" target=3D=
"_blank">shahms.king@gmail.com</a>&gt;</span> wrote:<br><blockquote class=
=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padd=
ing-left:1ex"><div dir=3D"ltr"><span><br><br>On Tuesday, January 20, 2015 a=
t 6:07:54 PM UTC-8, Gor Nishanov wrote:<blockquote class=3D"gmail_quote" st=
yle=3D"margin:0px 0px 0px 0.8ex;padding-left:1ex;border-left-color:rgb(204,=
204,204);border-left-width:1px;border-left-style:solid"><div dir=3D"ltr">Th=
ank you very much for your feedback.<br><br><blockquote class=3D"gmail_quot=
e" style=3D"margin:0px 0px 0px 0.8ex;padding-left:1ex;border-left-color:rgb=
(204,204,204);border-left-width:1px;border-left-style:solid"><div dir=3D"lt=
r"><ul><li style=3D"font-family:arial,sans-serif;font-size:small">It should=
 be stated clear that a coroutine destroys itself, I thought it&#39;s ref-c=
ounted and=C2=A0coroutine_handle is kinda intrinsic_ptr, but it&#39;s not.<=
br></li></ul></div></blockquote><div>Good point. I&#39;ll clarify that coro=
utine_handle is a low level class for library implementers, concrete corout=
ines, such as generator have expected RAII semantics and destroy the corout=
ine even if it is not fully executed. You can find an example generator in =
the appendix</div><div>=C2=A0</div><blockquote class=3D"gmail_quote" style=
=3D"margin:0px 0px 0px 0.8ex;padding-left:1ex;border-left-color:rgb(204,204=
,204);border-left-width:1px;border-left-style:solid"><div dir=3D"ltr"><ul><=
li><span style=3D"font-family:arial,sans-serif;font-size:small">await_ready=
 is probably unnecessary, the check can be done within=C2=A0await_suspend.<=
br></span></li></ul></div></blockquote><div>There is an invisible &quot;sav=
e state&quot; that happens between await_ready and await_suspend. Having an=
 await_ready allows to bypass save state altogether and continue execution.=
 </div><div><span style=3D"font-family:arial,sans-serif;font-size:small"><b=
r></span></div><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0p=
x 0.8ex;padding-left:1ex;border-left-color:rgb(204,204,204);border-left-wid=
th:1px;border-left-style:solid"><div dir=3D"ltr"><ul><li><span style=3D"fon=
t-family:arial,sans-serif;font-size:small">Appendix D: &quot;Exceptionless =
error propagation...&quot; is not really exceptionless:<br></span><span sty=
le=3D"font-family:arial,sans-serif;font-size:small">if you await on a futur=
e which is already in error-state (i.e. is_ready =3D=3D true), then await_s=
uspend won&#39;t we executed and the exception won&#39;t be set for the pro=
mise, while in=C2=A0await_resume, an exception will still be thrown.<br></s=
pan></li></ul></div></blockquote><div>You are right. The fix would be to ch=
eck in await ready if the future is in error and if so, return false, thus =
sending it onto await_suspend path.=C2=A0await_suspend has access to the pr=
omise and can set_exception directly.</div></div></blockquote><div><br></di=
v></span><div>Except this incurs an unnecessary save-state (and suspension?=
) of the awaiting function, which it would be nice to avoid.=C2=A0 The simp=
lest way I can see to avoid this would be passing just the promise to an aw=
ait function, although this potentially complicates the case where the prom=
ise type is void, e.g.</div><div><br></div><div>template &lt;typename _Prom=
sieT&gt;</div><div>bool await_ready(_PromiseT&amp;) const;</div><div>bool a=
wait_ready() const;</div><div><br></div><div><br></div><div>--Shahms</div><=
span><div>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"margin:0px=
 0px 0px 0.8ex;padding-left:1ex;border-left-color:rgb(204,204,204);border-l=
eft-width:1px;border-left-style:solid"><div dir=3D"ltr"><div>=C2=A0<span st=
yle=3D"font-family:arial,sans-serif;font-size:small"><br></span></div><bloc=
kquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;padding-left=
:1ex;border-left-color:rgb(204,204,204);border-left-width:1px;border-left-s=
tyle:solid"><div dir=3D"ltr"><ul><li><font face=3D"arial, sans-serif">I&#39=
;ve=C2=A0implemented such a thing myself, but wh</font>en await_result_t&lt=
;F&gt; is void, MSVC somewhat complains that promise::set_result doesn&#39;=
t take 1 argument, which I believe is a compiler bug.<font face=3D"arial, s=
ans-serif"><br></font></li></ul></div></blockquote><div>=C2=A0If you can se=
nd me a self-contained repro, I can debug it and suggest a workaround (and =
fix it in MSVC as well)</div><div><br></div><div>Thank you very much for yo=
ur feedback.</div><div><br></div><div>Gor<font face=3D"arial, sans-serif"><=
span style=3D"line-height:17px"><br></span></font></div></div></blockquote>=
</span></div><div><div>

<p></p>

-- <br>
<br>
--- <br>
You received this message because you are subscribed to a topic in the Goog=
le Groups &quot;ISO C++ Standard - Future Proposals&quot; group.<br>
To unsubscribe from this topic, visit <a href=3D"https://groups.google.com/=
a/isocpp.org/d/topic/std-proposals/RF7OEseYcHI/unsubscribe" target=3D"_blan=
k">https://groups.google.com/a/isocpp.org/d/topic/std-proposals/RF7OEseYcHI=
/unsubscribe</a>.<br>
To unsubscribe from this group and all its topics, send an email to <a href=
=3D"mailto:std-proposals+unsubscribe@isocpp.org" target=3D"_blank">std-prop=
osals+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">std-proposals@isocpp.org</a>.<br>
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/" target=3D"_blank">http://groups.google.com/a/isocpp.org/gro=
up/std-proposals/</a>.<br>
</div></div></blockquote></div><br></div>

<p></p>

-- <br>
<br>
--- <br>
You received this message because you are subscribed to a topic in the Goog=
le Groups &quot;ISO C++ Standard - Future Proposals&quot; group.<br>
To unsubscribe from this topic, visit <a href=3D"https://groups.google.com/=
a/isocpp.org/d/topic/std-proposals/RF7OEseYcHI/unsubscribe" target=3D"_blan=
k">https://groups.google.com/a/isocpp.org/d/topic/std-proposals/RF7OEseYcHI=
/unsubscribe</a>.<br>
To unsubscribe from this group and all its topics, send an email to <a href=
=3D"mailto:std-proposals+unsubscribe@isocpp.org" target=3D"_blank">std-prop=
osals+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">std-proposals@isocpp.org</a>.<br>
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/" target=3D"_blank">http://groups.google.com/a/isocpp.org/gro=
up/std-proposals/</a>.<br>
</blockquote></div></div>

<p></p>

-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--001a113a6786168d900511814c5d--

.


Author: Gor Nishanov <gornishanov@gmail.com>
Date: Wed, 18 Mar 2015 08:56:54 -0700
Raw View
--089e0112c4bedbf0da05119221c8
Content-Type: text/plain; charset=UTF-8

Hi Shahms:

I am having second thoughts about giving coroutine_handle to await_ready
too.
There was one change to the design that was not published yet. Namely
cancellation_requested() member of promise was eliminated. Instead,
coroutine_handle acquired two member functions resume() and destroy().
Resume is just another name for operator(), but destroy means resume the
coroutine in the "cancel" mode, run the destructors from the current
suspension point and destroy the coroutine.

With this change, we cannot short circuit from await_ready. Since if you
return "ready", it will resume the coroutine (and there is no
cancellation_check() at resumption point).

If we want to short-circuit error propagation, it should go to suspend path
and there it could do:

await_suspend(expected<T> & v, coroutine_handle<Promise> p)
if (v.has_error()) {
   p.promise().set_error(v.error());
   p.destroy();
}
return true;
}

It is counter-intuitive that we need to suspend here, but, it is required.
Since there is no "free" cancel check at every resume point that could have
jumped to the end.

I was thinking that in the coroutine_promise, omission of initial_suspend /
final_suspend could mean to indicate that the coroutine is never meant to
be suspended for real (expected / optional do not have a notion that the
value is not here yet) and that will have slightly different codegen to
make it work with zero overhead. (Let's call those coroutines,
error-unrolling).

Also, we would need some traits or some other mechanism to flag optional /
expected as not-suspendable, so that we can allow to await on them in error
unrolling coroutines, but fail to compile if inside somebody awaits on a
future or a task.

Gor

On Tue, Mar 17, 2015 at 12:51 PM, Shahms King <shahms.king@gmail.com> wrote:

>
>
> On Fri, Mar 13, 2015 at 10:23 AM Gor Nishanov <gornishanov@gmail.com>
> wrote:
>
>> I like it. Having await_ready to take promise as a parameter also
>> simplifies unpacking things like optional<T> or expected<T> where
>> suspension is not even an option.
>>
>> I avoided doing it before to keep the await_xxx functions simple, but,
>> now we have at least two cases that can benefit from it.
>>
>
> Thanks, my comment came after attempting to implement the requisite
> interfaces for a type similar to expected<T> in an exception-less
> environment.
>
> After a bit of thought, it occurs to me that the current proposal may also
> defeat opportunities for optimization in the case where the awaited-on
> object is always "ready" as would be the case for optional<T> or
> expected<T>.
>
> While I don't have any experience with such things, it would be nice if
> await could be as close to zero-overhead as possible and am suspicious that
> the mere inclusion of the suspend-point may preclude optimizations.
>
> In that vein, I wonder if allowing the omission or explicit deletion of
> await_suspend(coroutine_handle<T>) for always-ready types wouldn't be
> desirable?
>
> --Shahms
>
>
>> On Thu, Mar 12, 2015 at 10:04 AM, <shahms.king@gmail.com> wrote:
>>
>>>
>>>
>>> On Tuesday, January 20, 2015 at 6:07:54 PM UTC-8, Gor Nishanov wrote:
>>>>
>>>> Thank you very much for your feedback.
>>>>
>>>>
>>>>>    - It should be stated clear that a coroutine destroys itself, I
>>>>>    thought it's ref-counted and coroutine_handle is kinda intrinsic_ptr, but
>>>>>    it's not.
>>>>>
>>>>> Good point. I'll clarify that coroutine_handle is a low level class
>>>> for library implementers, concrete coroutines, such as generator have
>>>> expected RAII semantics and destroy the coroutine even if it is not fully
>>>> executed. You can find an example generator in the appendix
>>>>
>>>>
>>>>>
>>>>>    - await_ready is probably unnecessary, the check can be done
>>>>>    within await_suspend.
>>>>>
>>>>> There is an invisible "save state" that happens between await_ready
>>>> and await_suspend. Having an await_ready allows to bypass save state
>>>> altogether and continue execution.
>>>>
>>>>
>>>>>    - Appendix D: "Exceptionless error propagation..." is not really
>>>>>    exceptionless:
>>>>>    if you await on a future which is already in error-state (i.e.
>>>>>    is_ready == true), then await_suspend won't we executed and the exception
>>>>>    won't be set for the promise, while in await_resume, an exception will
>>>>>    still be thrown.
>>>>>
>>>>> You are right. The fix would be to check in await ready if the future
>>>> is in error and if so, return false, thus sending it onto await_suspend
>>>> path. await_suspend has access to the promise and can set_exception
>>>> directly.
>>>>
>>>
>>> Except this incurs an unnecessary save-state (and suspension?) of the
>>> awaiting function, which it would be nice to avoid.  The simplest way I can
>>> see to avoid this would be passing just the promise to an await function,
>>> although this potentially complicates the case where the promise type is
>>> void, e.g.
>>>
>>> template <typename _PromsieT>
>>> bool await_ready(_PromiseT&) const;
>>> bool await_ready() const;
>>>
>>>
>>> --Shahms
>>>
>>>
>>>>
>>>>
>>>>>
>>>>>    - I've implemented such a thing myself, but when await_result_t<F>
>>>>>    is void, MSVC somewhat complains that promise::set_result doesn't take 1
>>>>>    argument, which I believe is a compiler bug.
>>>>>
>>>>>  If you can send me a self-contained repro, I can debug it and suggest
>>>> a workaround (and fix it in MSVC as well)
>>>>
>>>> Thank you very much for your feedback.
>>>>
>>>> Gor
>>>>
>>>  --
>>>
>>> ---
>>> You received this message because you are subscribed to a topic in the
>>> Google Groups "ISO C++ Standard - Future Proposals" group.
>>> To unsubscribe from this topic, visit
>>> https://groups.google.com/a/isocpp.org/d/topic/std-proposals/RF7OEseYcHI/unsubscribe
>>> .
>>> To unsubscribe from this group and all its topics, send an email to
>>> std-proposals+unsubscribe@isocpp.org.
>>> To post to this group, send email to std-proposals@isocpp.org.
>>> Visit this group at
>>> http://groups.google.com/a/isocpp.org/group/std-proposals/.
>>>
>>
>>  --
>>
>> ---
>> You received this message because you are subscribed to a topic in the
>> Google Groups "ISO C++ Standard - Future Proposals" group.
>> To unsubscribe from this topic, visit
>> https://groups.google.com/a/isocpp.org/d/topic/std-proposals/RF7OEseYcHI/unsubscribe
>> .
>> To unsubscribe from this group and all its topics, send an email to
>> std-proposals+unsubscribe@isocpp.org.
>> To post to this group, send email to std-proposals@isocpp.org.
>> Visit this group at
>> http://groups.google.com/a/isocpp.org/group/std-proposals/.
>>
>  --
>
> ---
> You received this message because you are subscribed to a topic in the
> Google Groups "ISO C++ Standard - Future Proposals" group.
> To unsubscribe from this topic, visit
> https://groups.google.com/a/isocpp.org/d/topic/std-proposals/RF7OEseYcHI/unsubscribe
> .
> To unsubscribe from this group and all its topics, send an email to
> std-proposals+unsubscribe@isocpp.org.
> To post to this group, send email to std-proposals@isocpp.org.
> Visit this group at
> http://groups.google.com/a/isocpp.org/group/std-proposals/.
>

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

--089e0112c4bedbf0da05119221c8
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div>Hi Shahms:</div><div><br></div><div>I am having secon=
d thoughts about giving coroutine_handle to await_ready too.</div><div>Ther=
e was one change to the design that was not published yet. Namely cancellat=
ion_requested() member of promise was eliminated. Instead, coroutine_handle=
 acquired two member functions resume() and destroy(). Resume is just anoth=
er name for operator(), but destroy means resume the coroutine in the &quot=
;cancel&quot; mode, run the destructors from the current suspension point a=
nd destroy the coroutine.</div><div><br></div><div>With this change, we can=
not short circuit from await_ready. Since if you return &quot;ready&quot;, =
it will resume the coroutine (and there is no cancellation_check() at resum=
ption point).</div><div><br></div><div>If we want to short-circuit error pr=
opagation, it should go to suspend path and there it could do:</div><div><b=
r></div><div>await_suspend(expected&lt;T&gt; &amp;=C2=A0v, coroutine_handle=
&lt;Promise&gt; p)</div><div>if (v.has_error()) {</div><div>=C2=A0=C2=A0 p.=
promise().set_error(v.error());</div><div>=C2=A0=C2=A0 p.destroy();</div><d=
iv>}</div><div>return true;</div><div>}</div><div><br></div><div>It is coun=
ter-intuitive that we need to suspend here, but, it is required. Since ther=
e is no &quot;free&quot; cancel check at every resume point that could have=
 jumped to the end.</div><div><br></div><div>I was thinking that in the cor=
outine_promise, omission of initial_suspend=C2=A0/ final_suspend could mean=
 to indicate that the coroutine is never meant to be suspended for real (ex=
pected / optional do not have a notion that the value is not here yet) and =
that will have slightly different codegen to make it work with zero overhea=
d. (Let&#39;s call those coroutines, error-unrolling).</div><div><br></div>=
<div>Also, we would need some traits or some other mechanism to flag option=
al / expected as not-suspendable, so that we can allow to await on them in =
error unrolling coroutines, but fail to compile if inside somebody awaits o=
n a future or a task.</div><div><br></div><div>Gor</div></div><div class=3D=
"gmail_extra"><br><div class=3D"gmail_quote">On Tue, Mar 17, 2015 at 12:51 =
PM, Shahms King <span dir=3D"ltr">&lt;<a href=3D"mailto:shahms.king@gmail.c=
om" target=3D"_blank">shahms.king@gmail.com</a>&gt;</span> wrote:<br><block=
quote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc=
 solid;padding-left:1ex"><div dir=3D"ltr"><br><br><div class=3D"gmail_quote=
"><span>On Fri, Mar 13, 2015 at 10:23 AM Gor Nishanov &lt;<a href=3D"mailto=
:gornishanov@gmail.com" target=3D"_blank">gornishanov@gmail.com</a>&gt; wro=
te:<br><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;=
padding-left:1ex;border-left-color:rgb(204,204,204);border-left-width:1px;b=
order-left-style:solid"><div dir=3D"ltr"><div>I like it. Having await_ready=
 to take promise as a parameter also simplifies unpacking things like optio=
nal&lt;T&gt; or expected&lt;T&gt; where suspension is not even an option.</=
div><div><br></div><div>I avoided doing it before to keep the await_xxx fun=
ctions simple, but, now we have at least two cases that can benefit from it=
..</div></div></blockquote><div><br></div></span><div>Thanks, my comment cam=
e after attempting to implement the requisite interfaces for a type similar=
 to expected&lt;T&gt; in an exception-less environment. =C2=A0</div><div><b=
r></div><div>After a bit of thought, it occurs to me that the current propo=
sal may also defeat opportunities for optimization in the case where the aw=
aited-on object is always &quot;ready&quot; as would be the case for option=
al&lt;T&gt; or expected&lt;T&gt;.</div><div><br></div><div>While I don&#39;=
t have any experience with such things, it would be nice if await could be =
as close to zero-overhead as possible and am suspicious that the mere inclu=
sion of the suspend-point may preclude optimizations.</div><div><br></div><=
div>In that vein, I wonder if allowing the omission or explicit deletion of=
 await_suspend(coroutine_handle&lt;T&gt;) for always-ready types wouldn&#39=
;t be desirable?</div><div><br></div><div>--Shahms</div><div><div class=3D"=
h5"><div><br></div><blockquote class=3D"gmail_quote" style=3D"margin:0px 0p=
x 0px 0.8ex;padding-left:1ex;border-left-color:rgb(204,204,204);border-left=
-width:1px;border-left-style:solid"><div class=3D"gmail_extra"><br><div cla=
ss=3D"gmail_quote">On Thu, Mar 12, 2015 at 10:04 AM,  <span dir=3D"ltr">&lt=
;<a href=3D"mailto:shahms.king@gmail.com" target=3D"_blank">shahms.king@gma=
il.com</a>&gt;</span> wrote:<br><blockquote class=3D"gmail_quote" style=3D"=
margin:0px 0px 0px 0.8ex;padding-left:1ex;border-left-color:rgb(204,204,204=
);border-left-width:1px;border-left-style:solid"><div dir=3D"ltr"><span><br=
><br>On Tuesday, January 20, 2015 at 6:07:54 PM UTC-8, Gor Nishanov wrote:<=
blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;padding-=
left:1ex;border-left-color:rgb(204,204,204);border-left-width:1px;border-le=
ft-style:solid"><div dir=3D"ltr">Thank you very much for your feedback.<br>=
<br><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;pad=
ding-left:1ex;border-left-color:rgb(204,204,204);border-left-width:1px;bord=
er-left-style:solid"><div dir=3D"ltr"><ul><li style=3D"font-family:arial,sa=
ns-serif;font-size:small">It should be stated clear that a coroutine destro=
ys itself, I thought it&#39;s ref-counted and=C2=A0coroutine_handle is kind=
a intrinsic_ptr, but it&#39;s not.<br></li></ul></div></blockquote><div>Goo=
d point. I&#39;ll clarify that coroutine_handle is a low level class for li=
brary implementers, concrete coroutines, such as generator have expected RA=
II semantics and destroy the coroutine even if it is not fully executed. Yo=
u can find an example generator in the appendix</div><div>=C2=A0</div><bloc=
kquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;padding-left=
:1ex;border-left-color:rgb(204,204,204);border-left-width:1px;border-left-s=
tyle:solid"><div dir=3D"ltr"><ul><li><span style=3D"font-family:arial,sans-=
serif;font-size:small">await_ready is probably unnecessary, the check can b=
e done within=C2=A0await_suspend.<br></span></li></ul></div></blockquote><d=
iv>There is an invisible &quot;save state&quot; that happens between await_=
ready and await_suspend. Having an await_ready allows to bypass save state =
altogether and continue execution. </div><div><span style=3D"font-family:ar=
ial,sans-serif;font-size:small"><br></span></div><blockquote class=3D"gmail=
_quote" style=3D"margin:0px 0px 0px 0.8ex;padding-left:1ex;border-left-colo=
r:rgb(204,204,204);border-left-width:1px;border-left-style:solid"><div dir=
=3D"ltr"><ul><li><span style=3D"font-family:arial,sans-serif;font-size:smal=
l">Appendix D: &quot;Exceptionless error propagation...&quot; is not really=
 exceptionless:<br></span><span style=3D"font-family:arial,sans-serif;font-=
size:small">if you await on a future which is already in error-state (i.e. =
is_ready =3D=3D true), then await_suspend won&#39;t we executed and the exc=
eption won&#39;t be set for the promise, while in=C2=A0await_resume, an exc=
eption will still be thrown.<br></span></li></ul></div></blockquote><div>Yo=
u are right. The fix would be to check in await ready if the future is in e=
rror and if so, return false, thus sending it onto await_suspend path.=C2=
=A0await_suspend has access to the promise and can set_exception directly.<=
/div></div></blockquote><div><br></div></span><div>Except this incurs an un=
necessary save-state (and suspension?) of the awaiting function, which it w=
ould be nice to avoid.=C2=A0 The simplest way I can see to avoid this would=
 be passing just the promise to an await function, although this potentiall=
y complicates the case where the promise type is void, e.g.</div><div><br><=
/div><div>template &lt;typename _PromsieT&gt;</div><div>bool await_ready(_P=
romiseT&amp;) const;</div><div>bool await_ready() const;</div><div><br></di=
v><div><br></div><div>--Shahms</div><span><div>=C2=A0</div><blockquote clas=
s=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;padding-left:1ex;border=
-left-color:rgb(204,204,204);border-left-width:1px;border-left-style:solid"=
><div dir=3D"ltr"><div>=C2=A0<span style=3D"font-family:arial,sans-serif;fo=
nt-size:small"><br></span></div><blockquote class=3D"gmail_quote" style=3D"=
margin:0px 0px 0px 0.8ex;padding-left:1ex;border-left-color:rgb(204,204,204=
);border-left-width:1px;border-left-style:solid"><div dir=3D"ltr"><ul><li><=
font face=3D"arial, sans-serif">I&#39;ve=C2=A0implemented such a thing myse=
lf, but wh</font>en await_result_t&lt;F&gt; is void, MSVC somewhat complain=
s that promise::set_result doesn&#39;t take 1 argument, which I believe is =
a compiler bug.<font face=3D"arial, sans-serif"><br></font></li></ul></div>=
</blockquote><div>=C2=A0If you can send me a self-contained repro, I can de=
bug it and suggest a workaround (and fix it in MSVC as well)</div><div><br>=
</div><div>Thank you very much for your feedback.</div><div><br></div><div>=
Gor<font face=3D"arial, sans-serif"><span style=3D"line-height:17px"><br></=
span></font></div></div></blockquote></span></div><div><div>

<p></p>

-- <br>
<br>
--- <br>
You received this message because you are subscribed to a topic in the Goog=
le Groups &quot;ISO C++ Standard - Future Proposals&quot; group.<br>
To unsubscribe from this topic, visit <a href=3D"https://groups.google.com/=
a/isocpp.org/d/topic/std-proposals/RF7OEseYcHI/unsubscribe" target=3D"_blan=
k">https://groups.google.com/a/isocpp.org/d/topic/std-proposals/RF7OEseYcHI=
/unsubscribe</a>.<br>
To unsubscribe from this group and all its topics, send an email to <a href=
=3D"mailto:std-proposals+unsubscribe@isocpp.org" target=3D"_blank">std-prop=
osals+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">std-proposals@isocpp.org</a>.<br>
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/" target=3D"_blank">http://groups.google.com/a/isocpp.org/gro=
up/std-proposals/</a>.<br>
</div></div></blockquote></div><br></div>

<p></p>

-- <br>
<br>
--- <br>
You received this message because you are subscribed to a topic in the Goog=
le Groups &quot;ISO C++ Standard - Future Proposals&quot; group.<br>
To unsubscribe from this topic, visit <a href=3D"https://groups.google.com/=
a/isocpp.org/d/topic/std-proposals/RF7OEseYcHI/unsubscribe" target=3D"_blan=
k">https://groups.google.com/a/isocpp.org/d/topic/std-proposals/RF7OEseYcHI=
/unsubscribe</a>.<br>
To unsubscribe from this group and all its topics, send an email to <a href=
=3D"mailto:std-proposals+unsubscribe@isocpp.org" target=3D"_blank">std-prop=
osals+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">std-proposals@isocpp.org</a>.<br>
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/" target=3D"_blank">http://groups.google.com/a/isocpp.org/gro=
up/std-proposals/</a>.<br>
</blockquote></div></div></div></div><div class=3D"HOEnZb"><div class=3D"h5=
">

<p></p>

-- <br>
<br>
--- <br>
You received this message because you are subscribed to a topic in the Goog=
le Groups &quot;ISO C++ Standard - Future Proposals&quot; group.<br>
To unsubscribe from this topic, visit <a href=3D"https://groups.google.com/=
a/isocpp.org/d/topic/std-proposals/RF7OEseYcHI/unsubscribe" target=3D"_blan=
k">https://groups.google.com/a/isocpp.org/d/topic/std-proposals/RF7OEseYcHI=
/unsubscribe</a>.<br>
To unsubscribe from this group and all its topics, send an email to <a href=
=3D"mailto:std-proposals+unsubscribe@isocpp.org" target=3D"_blank">std-prop=
osals+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">std-proposals@isocpp.org</a>.<br>
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/" target=3D"_blank">http://groups.google.com/a/isocpp.org/gro=
up/std-proposals/</a>.<br>
</div></div></blockquote></div><br></div>

<p></p>

-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--089e0112c4bedbf0da05119221c8--

.


Author: Gor Nishanov <gornishanov@gmail.com>
Date: Wed, 18 Mar 2015 09:17:00 -0700
Raw View
--089e0112c4bebb54f60511926934
Content-Type: text/plain; charset=UTF-8

Hi Tongari:

The problem is not restricted to std::future, the use of std::future is
> just for example. The problem I wanted to show is that `coroutine_handle`
> is just like raw-pointer, no RAII, that is, if the awaiter just drop the
> coroutine_handle and so doesn't call it eventually, the coroutine-context
> is lost forever (i.e. memory leak).
>

This is intentional. coroutine_handle is meant to be low level construct to
build safe abstractions on top. Mandating ref-counting will needlessly
pessimize performance where it is not needed. Interlocked operations are
expensive and in generator scenarios they are unneeded.

In the updated proposal (not published yet), coroutine_handle acquired
destroy() method that destroy the coroutine (subsuming functionality
previously handled by cancellation_requested() member in the promise). I
can see potential evolution of coroutine_handle of getting RAII behavior.


> The future returned from future.then is like the one returned from
> std::async, it will block in the destructor.
>
> See: http://tinyurl.com/kt9kd3o
>
>
I am not sure that creates a problem for awaitable adapter for boost future.
await <expr> expansion keep <expr> == boost::future in a temporary that
lives like all temporaries until the end of the full expression.

When function is suspended, future is kept alive until the function is
resumed.


Thank you for the bug reports and yes, it should be possible to write
when_any / when_all for arbitrary awaitables.

In the meantime waiting for your progress, I've implemented an emulation
> library called CO2:
>
>     https://github.com/jamboree/co2
>


I saw it. Very cool :-) .


> What do you think about the optional customization points (i.e.
> before_resume/after_suspend) for promise?
>

To solve async cancellation (cancel coroutine why it is awaiting on some
I/O in flight, it will need something like that.
N4286 has a sketch of how async cancellation could be handled (page 22). It
does not change the existing model, but, if awaitable / coroutine_promise
want to support async cancellation they need to have a little dance to
perform when launching an async operation.

I had to add:

set_cancel_routine(cb) - informs that we are just about to launch async
operation and the cb needs to be called to cancel async operation (example,
issue cancellation for an I/O in flight, set a flag somewhere that is
periodically checked, etc)

These three were needed to solve various races:
begin_suspend()
done_suspend()
cancel_suspend()

Cheers,
Gor

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

--089e0112c4bebb54f60511926934
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">Hi Tongari:<br><div class=3D"gmail_extra"><br><div class=
=3D"gmail_quote"><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px =
0px 0.8ex;padding-left:1ex;border-left-color:rgb(204,204,204);border-left-w=
idth:1px;border-left-style:solid"><div dir=3D"ltr"><div><div class=3D"gmail=
_extra"><div class=3D"gmail_quote"><div>The problem is not restricted to st=
d::future, the use of std::future is just for example. The problem I wanted=
 to show is that `coroutine_handle` is just like raw-pointer, no RAII, that=
 is, if the awaiter just drop the coroutine_handle and so doesn&#39;t call =
it eventually, the coroutine-context is lost forever (i.e. memory leak).</d=
iv></div></div></div></div></blockquote><div><br></div><div>This is intenti=
onal. coroutine_handle is meant to be low level construct to build safe abs=
tractions on top. Mandating ref-counting will needlessly pessimize performa=
nce where it is not needed. Interlocked operations are expensive and in gen=
erator scenarios they are unneeded.</div><div><br></div><div>In the updated=
 proposal (not published yet), coroutine_handle acquired destroy() method t=
hat destroy the coroutine (subsuming functionality previously handled by ca=
ncellation_requested() member in the promise). I can see=C2=A0potential evo=
lution of coroutine_handle of getting RAII behavior.</div><div>=C2=A0</div>=
<blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;padding=
-left:1ex;border-left-color:rgb(204,204,204);border-left-width:1px;border-l=
eft-style:solid"><div dir=3D"ltr"><div><div class=3D"gmail_extra"><div clas=
s=3D"gmail_quote"><div>The future returned from future.then is like the one=
 returned from std::async, it will block in the destructor.</div><div><br><=
/div><div>See:=C2=A0<a href=3D"http://tinyurl.com/kt9kd3o" target=3D"_blank=
">http://tinyurl.com/kt9kd3o</a></div><span><div><br></div></span></div></d=
iv></div></div></blockquote><div><br></div><div>I=C2=A0am not sure that cre=
ates a problem for awaitable adapter for boost future.</div><div>await &lt;=
expr&gt; expansion keep &lt;expr&gt; =3D=3D boost::future in a temporary th=
at lives like all temporaries until the end of the full expression.</div><d=
iv><br></div><div>When function is suspended, future is kept alive until th=
e function is resumed. </div><div><br></div><div><br></div><span><div>Thank=
 you for the bug reports and yes, it should be possible to write when_any /=
 when_all=C2=A0for arbitrary awaitables.</div><div><br></div></span><blockq=
uote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;padding-left:1=
ex;border-left-color:rgb(204,204,204);border-left-width:1px;border-left-sty=
le:solid"><div dir=3D"ltr"><div><div class=3D"gmail_extra"><div class=3D"gm=
ail_quote"><div>In the meantime waiting for your progress, I&#39;ve impleme=
nted an emulation library called CO2:</div><div><br></div><div>=C2=A0 =C2=
=A0 <a href=3D"https://github.com/jamboree/co2" target=3D"_blank">https://g=
ithub.com/jamboree/co2</a><br></div></div></div></div></div></blockquote><d=
iv><br></div><div><br></div><div>I saw it. Very cool :-) .</div><div>=C2=A0=
<br></div><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8=
ex;padding-left:1ex;border-left-color:rgb(204,204,204);border-left-width:1p=
x;border-left-style:solid"><div dir=3D"ltr"><div><div class=3D"gmail_extra"=
><div class=3D"gmail_quote"><div>What do you think about the optional=C2=A0=
customization points (i.e. before_resume/after_suspend) for promise?</div><=
/div></div></div></div></blockquote><div><br></div><div>To solve async canc=
ellation (cancel coroutine why it is awaiting on some I/O in flight, it wil=
l need something like that.</div><div>N4286 has a sketch of how async cance=
llation could be handled (page 22). It does not change the existing model, =
but, if awaitable / coroutine_promise want to support async cancellation th=
ey need to have a little dance to perform when launching an async operation=
..</div><div><br></div><div>I had to add:</div><div><br></div><div>set_cance=
l_routine(cb) - informs that we are just about to launch async operation an=
d the cb needs to be called to cancel async operation (example, issue cance=
llation for an I/O in flight, set a flag somewhere that is periodically che=
cked, etc)</div><div><br></div><div>These three were needed to solve variou=
s races:</div><div>begin_suspend()</div><div>done_suspend()</div><div>cance=
l_suspend()</div><div><br></div><div>Cheers,</div><div>Gor</div></div><br><=
/div></div>

<p></p>

-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--089e0112c4bebb54f60511926934--

.


Author: shahms.king@gmail.com
Date: Fri, 10 Apr 2015 09:50:46 -0700 (PDT)
Raw View
------=_Part_197_1750760000.1428684646289
Content-Type: multipart/alternative;
 boundary="----=_Part_198_202388806.1428684646289"

------=_Part_198_202388806.1428684646289
Content-Type: text/plain; charset=UTF-8



On Wednesday, March 18, 2015 at 8:56:57 AM UTC-7, Gor Nishanov wrote:
>
> Hi Shahms:
>
> I am having second thoughts about giving coroutine_handle to await_ready
> too.
> There was one change to the design that was not published yet. Namely
> cancellation_requested() member of promise was eliminated. Instead,
> coroutine_handle acquired two member functions resume() and destroy().
> Resume is just another name for operator(), but destroy means resume the
> coroutine in the "cancel" mode, run the destructors from the current
> suspension point and destroy the coroutine.
>

I'm anxiously awaiting the updated proposal :-)


>
> With this change, we cannot short circuit from await_ready. Since if you
> return "ready", it will resume the coroutine (and there is no
> cancellation_check() at resumption point).
>
> If we want to short-circuit error propagation, it should go to suspend
> path and there it could do:
>
> await_suspend(expected<T> & v, coroutine_handle<Promise> p)
> if (v.has_error()) {
>    p.promise().set_error(v.error());
>    p.destroy();
> }
> return true;
> }
>
> It is counter-intuitive that we need to suspend here, but, it is required.
> Since there is no "free" cancel check at every resume point that could have
> jumped to the end.
>
> I was thinking that in the coroutine_promise, omission of
> initial_suspend / final_suspend could mean to indicate that the coroutine
> is never meant to be suspended for real (expected / optional do not have a
> notion that the value is not here yet) and that will have slightly
> different codegen to make it work with zero overhead. (Let's call those
> coroutines, error-unrolling).
>
> Also, we would need some traits or some other mechanism to flag optional /
> expected as not-suspendable, so that we can allow to await on them in error
> unrolling coroutines, but fail to compile if inside somebody awaits on a
> future or a task.
>

Unless I'm misinterpreting, that seems incomplete.  We fundamentally have
an interaction that depends on both the Promise and Awaitable such that
(assuming a suitable await_suspend() can be found) we should have the
following behaviors (where S stands for suspendable and NS not-suspendable):

                 Awaitable
        ___|____S____|___NS___|
Promise S  | Suspend | Unwrap |
        NS | Block   | Unwrap |

Where 'Block' is basically just unwrapping a suspendable awaitable return
(think future<T>.get()).  For a non-suspendable Awaitable, it is always
just unwrapped, which can be done with zero overhead, regardless of the
Promise type.  Similarly, a non-suspendable Promise always unwraps the
awaitable.  It's only for the Suspendable/Suspendable case where the
overhead of saving state is required.  From above it sounds like you're
suggesting that the 'Block' case should be a compile-time error?  That
would be surprising to me and seems inconsistent.  One advantage of
treating `await` consistently in all of the cases is that the only
complicated case to optimize is awaiting on a non-suspendable Awaitable
with a suspendable Promise.  That should be zero overhead (as the await
will be an error-unrolling await), but requires a signal from the Awaitable
(be it a trait or or different overload signature) that it is
not-suspendable.

Thanks for all the effort on this, I think the `await` semantics so far
presented could an exciting new idiom for C++ and possibly a "best of both
worlds" for error-handling!

--Shahms


> Gor
>
> On Tue, Mar 17, 2015 at 12:51 PM, Shahms King <shahm...@gmail.com
> <javascript:>> wrote:
>
>>
>>
>> On Fri, Mar 13, 2015 at 10:23 AM Gor Nishanov <gorni...@gmail.com
>> <javascript:>> wrote:
>>
>>> I like it. Having await_ready to take promise as a parameter also
>>> simplifies unpacking things like optional<T> or expected<T> where
>>> suspension is not even an option.
>>>
>>> I avoided doing it before to keep the await_xxx functions simple, but,
>>> now we have at least two cases that can benefit from it.
>>>
>>
>> Thanks, my comment came after attempting to implement the requisite
>> interfaces for a type similar to expected<T> in an exception-less
>> environment.
>>
>> After a bit of thought, it occurs to me that the current proposal may
>> also defeat opportunities for optimization in the case where the awaited-on
>> object is always "ready" as would be the case for optional<T> or
>> expected<T>.
>>
>> While I don't have any experience with such things, it would be nice if
>> await could be as close to zero-overhead as possible and am suspicious that
>> the mere inclusion of the suspend-point may preclude optimizations.
>>
>> In that vein, I wonder if allowing the omission or explicit deletion of
>> await_suspend(coroutine_handle<T>) for always-ready types wouldn't be
>> desirable?
>>
>> --Shahms
>>
>>
>>> On Thu, Mar 12, 2015 at 10:04 AM, <shahm...@gmail.com <javascript:>>
>>> wrote:
>>>
>>>>
>>>>
>>>> On Tuesday, January 20, 2015 at 6:07:54 PM UTC-8, Gor Nishanov wrote:
>>>>>
>>>>> Thank you very much for your feedback.
>>>>>
>>>>>
>>>>>>    - It should be stated clear that a coroutine destroys itself, I
>>>>>>    thought it's ref-counted and coroutine_handle is kinda intrinsic_ptr, but
>>>>>>    it's not.
>>>>>>
>>>>>> Good point. I'll clarify that coroutine_handle is a low level class
>>>>> for library implementers, concrete coroutines, such as generator have
>>>>> expected RAII semantics and destroy the coroutine even if it is not fully
>>>>> executed. You can find an example generator in the appendix
>>>>>
>>>>>
>>>>>>
>>>>>>    - await_ready is probably unnecessary, the check can be done
>>>>>>    within await_suspend.
>>>>>>
>>>>>> There is an invisible "save state" that happens between await_ready
>>>>> and await_suspend. Having an await_ready allows to bypass save state
>>>>> altogether and continue execution.
>>>>>
>>>>>
>>>>>>    - Appendix D: "Exceptionless error propagation..." is not really
>>>>>>    exceptionless:
>>>>>>    if you await on a future which is already in error-state (i.e.
>>>>>>    is_ready == true), then await_suspend won't we executed and the exception
>>>>>>    won't be set for the promise, while in await_resume, an exception will
>>>>>>    still be thrown.
>>>>>>
>>>>>> You are right. The fix would be to check in await ready if the future
>>>>> is in error and if so, return false, thus sending it onto await_suspend
>>>>> path. await_suspend has access to the promise and can set_exception
>>>>> directly.
>>>>>
>>>>
>>>> Except this incurs an unnecessary save-state (and suspension?) of the
>>>> awaiting function, which it would be nice to avoid.  The simplest way I can
>>>> see to avoid this would be passing just the promise to an await function,
>>>> although this potentially complicates the case where the promise type is
>>>> void, e.g.
>>>>
>>>> template <typename _PromsieT>
>>>> bool await_ready(_PromiseT&) const;
>>>> bool await_ready() const;
>>>>
>>>>
>>>> --Shahms
>>>>
>>>>
>>>>>
>>>>>
>>>>>>
>>>>>>    - I've implemented such a thing myself, but when
>>>>>>    await_result_t<F> is void, MSVC somewhat complains that promise::set_result
>>>>>>    doesn't take 1 argument, which I believe is a compiler bug.
>>>>>>
>>>>>>  If you can send me a self-contained repro, I can debug it and
>>>>> suggest a workaround (and fix it in MSVC as well)
>>>>>
>>>>> Thank you very much for your feedback.
>>>>>
>>>>> Gor
>>>>>
>>>>  --
>>>>
>>>> ---
>>>> You received this message because you are subscribed to a topic in the
>>>> Google Groups "ISO C++ Standard - Future Proposals" group.
>>>> To unsubscribe from this topic, visit
>>>> https://groups.google.com/a/isocpp.org/d/topic/std-proposals/RF7OEseYcHI/unsubscribe
>>>> .
>>>> To unsubscribe from this group and all its topics, send an email to
>>>> std-proposal...@isocpp.org <javascript:>.
>>>> To post to this group, send email to std-pr...@isocpp.org <javascript:>
>>>> .
>>>> Visit this group at
>>>> http://groups.google.com/a/isocpp.org/group/std-proposals/.
>>>>
>>>
>>>  --
>>>
>>> ---
>>> You received this message because you are subscribed to a topic in the
>>> Google Groups "ISO C++ Standard - Future Proposals" group.
>>> To unsubscribe from this topic, visit
>>> https://groups.google.com/a/isocpp.org/d/topic/std-proposals/RF7OEseYcHI/unsubscribe
>>> .
>>> To unsubscribe from this group and all its topics, send an email to
>>> std-proposal...@isocpp.org <javascript:>.
>>> To post to this group, send email to std-pr...@isocpp.org <javascript:>.
>>> Visit this group at
>>> http://groups.google.com/a/isocpp.org/group/std-proposals/.
>>>
>>  --
>>
>> ---
>> You received this message because you are subscribed to a topic in the
>> Google Groups "ISO C++ Standard - Future Proposals" group.
>> To unsubscribe from this topic, visit
>> https://groups.google.com/a/isocpp.org/d/topic/std-proposals/RF7OEseYcHI/unsubscribe
>> .
>> To unsubscribe from this group and all its topics, send an email to
>> std-proposal...@isocpp.org <javascript:>.
>> To post to this group, send email to std-pr...@isocpp.org <javascript:>.
>> Visit this group at
>> http://groups.google.com/a/isocpp.org/group/std-proposals/.
>>
>
>

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

------=_Part_198_202388806.1428684646289
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>On Wednesday, March 18, 2015 at 8:56:57 AM UTC-7, =
Gor Nishanov wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;mar=
gin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D=
"ltr"><div>Hi Shahms:</div><div><br></div><div>I am having second thoughts =
about giving coroutine_handle to await_ready too.</div><div>There was one c=
hange to the design that was not published yet. Namely cancellation_request=
ed() member of promise was eliminated. Instead, coroutine_handle acquired t=
wo member functions resume() and destroy(). Resume is just another name for=
 operator(), but destroy means resume the coroutine in the "cancel" mode, r=
un the destructors from the current suspension point and destroy the corout=
ine.</div></div></blockquote><div><br></div><div>I'm anxiously awaiting the=
 updated proposal :-)</div><div>&nbsp;</div><blockquote class=3D"gmail_quot=
e" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;paddin=
g-left: 1ex;"><div dir=3D"ltr"><div><br></div><div>With this change, we can=
not short circuit from await_ready. Since if you return "ready", it will re=
sume the coroutine (and there is no cancellation_check() at resumption poin=
t).</div><div><br></div><div>If we want to short-circuit error propagation,=
 it should go to suspend path and there it could do:</div><div><br></div><d=
iv>await_suspend(expected&lt;T&gt; &amp;&nbsp;v, coroutine_handle&lt;Promis=
e&gt; p)</div><div>if (v.has_error()) {</div><div>&nbsp;&nbsp; p.promise().=
set_error(v.error(<wbr>));</div><div>&nbsp;&nbsp; p.destroy();</div><div>}<=
/div><div>return true;</div><div>}</div><div><br></div><div>It is counter-i=
ntuitive that we need to suspend here, but, it is required. Since there is =
no "free" cancel check at every resume point that could have jumped to the =
end.</div><div><br></div><div>I was thinking that in the coroutine_promise,=
 omission of initial_suspend&nbsp;/ final_suspend could mean to indicate th=
at the coroutine is never meant to be suspended for real (expected / option=
al do not have a notion that the value is not here yet) and that will have =
slightly different codegen to make it work with zero overhead. (Let's call =
those coroutines, error-unrolling).</div><div><br></div><div>Also, we would=
 need some traits or some other mechanism to flag optional / expected as no=
t-suspendable, so that we can allow to await on them in error unrolling cor=
outines, but fail to compile if inside somebody awaits on a future or a tas=
k.</div></div></blockquote><div><br></div><div>Unless I'm misinterpreting, =
that seems incomplete. &nbsp;We fundamentally have an interaction that depe=
nds on both the Promise and Awaitable such that (assuming a suitable await_=
suspend() can be found) we should have the following behaviors (where S sta=
nds for suspendable and NS not-suspendable):</div><div><br></div><div><font=
 face=3D"courier new, monospace">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; =
&nbsp; &nbsp; &nbsp;Awaitable</font></div><div><font face=3D"courier new, m=
onospace">&nbsp; &nbsp; &nbsp; &nbsp; ___|____S____|___NS___|</font></div><=
div><font face=3D"courier new, monospace">Promise S &nbsp;| Suspend | Unwra=
p |</font></div><div><font face=3D"courier new, monospace">&nbsp; &nbsp; &n=
bsp; &nbsp; NS | Block &nbsp; | Unwrap |</font></div><div><br></div><div>Wh=
ere 'Block' is basically just unwrapping a suspendable awaitable return (th=
ink future&lt;T&gt;.get()). &nbsp;For a non-suspendable Awaitable, it is al=
ways just unwrapped, which can be done with zero overhead, regardless of th=
e Promise type. &nbsp;Similarly, a non-suspendable Promise always unwraps t=
he awaitable. &nbsp;It's only for the Suspendable/Suspendable case where th=
e overhead of saving state is required. &nbsp;From above it sounds like you=
're suggesting that the 'Block' case should be a compile-time error? &nbsp;=
That would be surprising to me and seems inconsistent. &nbsp;One advantage =
of treating `await` consistently in all of the cases is that the only compl=
icated case to optimize is awaiting on a non-suspendable Awaitable with a s=
uspendable Promise. &nbsp;That should be zero overhead (as the await will b=
e an error-unrolling await), but requires a signal from the Awaitable (be i=
t a trait or or different overload signature) that it is not-suspendable.</=
div><div><br></div><div>Thanks for all the effort on this, I think the `awa=
it` semantics so far presented could an exciting new idiom for C++ and poss=
ibly a "best of both worlds" for error-handling!</div><div><br></div><div>-=
-Shahms</div><div><br></div><blockquote class=3D"gmail_quote" style=3D"marg=
in: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><d=
iv dir=3D"ltr"><div><br></div><div>Gor</div></div><div><br><div class=3D"gm=
ail_quote">On Tue, Mar 17, 2015 at 12:51 PM, Shahms King <span dir=3D"ltr">=
&lt;<a href=3D"javascript:" target=3D"_blank" gdf-obfuscated-mailto=3D"-vjR=
bj3rmNIJ" rel=3D"nofollow" onmousedown=3D"this.href=3D'javascript:';return =
true;" onclick=3D"this.href=3D'javascript:';return true;">shahm...@gmail.co=
m</a>&gt;</span> wrote:<br><blockquote class=3D"gmail_quote" style=3D"margi=
n:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr">=
<br><br><div class=3D"gmail_quote"><span>On Fri, Mar 13, 2015 at 10:23 AM G=
or Nishanov &lt;<a href=3D"javascript:" target=3D"_blank" gdf-obfuscated-ma=
ilto=3D"-vjRbj3rmNIJ" rel=3D"nofollow" onmousedown=3D"this.href=3D'javascri=
pt:';return true;" onclick=3D"this.href=3D'javascript:';return true;">gorni=
....@gmail.com</a>&gt; wrote:<br><blockquote class=3D"gmail_quote" style=3D"=
margin:0px 0px 0px 0.8ex;padding-left:1ex;border-left-color:rgb(204,204,204=
);border-left-width:1px;border-left-style:solid"><div dir=3D"ltr"><div>I li=
ke it. Having await_ready to take promise as a parameter also simplifies un=
packing things like optional&lt;T&gt; or expected&lt;T&gt; where suspension=
 is not even an option.</div><div><br></div><div>I avoided doing it before =
to keep the await_xxx functions simple, but, now we have at least two cases=
 that can benefit from it.</div></div></blockquote><div><br></div></span><d=
iv>Thanks, my comment came after attempting to implement the requisite inte=
rfaces for a type similar to expected&lt;T&gt; in an exception-less environ=
ment. &nbsp;</div><div><br></div><div>After a bit of thought, it occurs to =
me that the current proposal may also defeat opportunities for optimization=
 in the case where the awaited-on object is always "ready" as would be the =
case for optional&lt;T&gt; or expected&lt;T&gt;.</div><div><br></div><div>W=
hile I don't have any experience with such things, it would be nice if awai=
t could be as close to zero-overhead as possible and am suspicious that the=
 mere inclusion of the suspend-point may preclude optimizations.</div><div>=
<br></div><div>In that vein, I wonder if allowing the omission or explicit =
deletion of await_suspend(coroutine_<wbr>handle&lt;T&gt;) for always-ready =
types wouldn't be desirable?</div><div><br></div><div>--Shahms</div><div><d=
iv><div><br></div><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px=
 0px 0.8ex;padding-left:1ex;border-left-color:rgb(204,204,204);border-left-=
width:1px;border-left-style:solid"><div><br><div class=3D"gmail_quote">On T=
hu, Mar 12, 2015 at 10:04 AM,  <span dir=3D"ltr">&lt;<a href=3D"javascript:=
" target=3D"_blank" gdf-obfuscated-mailto=3D"-vjRbj3rmNIJ" rel=3D"nofollow"=
 onmousedown=3D"this.href=3D'javascript:';return true;" onclick=3D"this.hre=
f=3D'javascript:';return true;">shahm...@gmail.com</a>&gt;</span> wrote:<br=
><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;paddin=
g-left:1ex;border-left-color:rgb(204,204,204);border-left-width:1px;border-=
left-style:solid"><div dir=3D"ltr"><span><br><br>On Tuesday, January 20, 20=
15 at 6:07:54 PM UTC-8, Gor Nishanov wrote:<blockquote class=3D"gmail_quote=
" style=3D"margin:0px 0px 0px 0.8ex;padding-left:1ex;border-left-color:rgb(=
204,204,204);border-left-width:1px;border-left-style:solid"><div dir=3D"ltr=
">Thank you very much for your feedback.<br><br><blockquote class=3D"gmail_=
quote" style=3D"margin:0px 0px 0px 0.8ex;padding-left:1ex;border-left-color=
:rgb(204,204,204);border-left-width:1px;border-left-style:solid"><div dir=
=3D"ltr"><ul><li style=3D"font-family:arial,sans-serif;font-size:small">It =
should be stated clear that a coroutine destroys itself, I thought it's ref=
-counted and&nbsp;coroutine_handle is kinda intrinsic_ptr, but it's not.<br=
></li></ul></div></blockquote><div>Good point. I'll clarify that coroutine_=
handle is a low level class for library implementers, concrete coroutines, =
such as generator have expected RAII semantics and destroy the coroutine ev=
en if it is not fully executed. You can find an example generator in the ap=
pendix</div><div>&nbsp;</div><blockquote class=3D"gmail_quote" style=3D"mar=
gin:0px 0px 0px 0.8ex;padding-left:1ex;border-left-color:rgb(204,204,204);b=
order-left-width:1px;border-left-style:solid"><div dir=3D"ltr"><ul><li><spa=
n style=3D"font-family:arial,sans-serif;font-size:small">await_ready is pro=
bably unnecessary, the check can be done within&nbsp;await_suspend.<br></sp=
an></li></ul></div></blockquote><div>There is an invisible "save state" tha=
t happens between await_ready and await_suspend. Having an await_ready allo=
ws to bypass save state altogether and continue execution. </div><div><span=
 style=3D"font-family:arial,sans-serif;font-size:small"><br></span></div><b=
lockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;padding-l=
eft:1ex;border-left-color:rgb(204,204,204);border-left-width:1px;border-lef=
t-style:solid"><div dir=3D"ltr"><ul><li><span style=3D"font-family:arial,sa=
ns-serif;font-size:small">Appendix D: "Exceptionless error propagation..." =
is not really exceptionless:<br></span><span style=3D"font-family:arial,san=
s-serif;font-size:small">if you await on a future which is already in error=
-state (i.e. is_ready =3D=3D true), then await_suspend won't we executed an=
d the exception won't be set for the promise, while in&nbsp;await_resume, a=
n exception will still be thrown.<br></span></li></ul></div></blockquote><d=
iv>You are right. The fix would be to check in await ready if the future is=
 in error and if so, return false, thus sending it onto await_suspend path.=
&nbsp;await_suspend has access to the promise and can set_exception directl=
y.</div></div></blockquote><div><br></div></span><div>Except this incurs an=
 unnecessary save-state (and suspension?) of the awaiting function, which i=
t would be nice to avoid.&nbsp; The simplest way I can see to avoid this wo=
uld be passing just the promise to an await function, although this potenti=
ally complicates the case where the promise type is void, e.g.</div><div><b=
r></div><div>template &lt;typename _PromsieT&gt;</div><div>bool await_ready=
(_PromiseT&amp;) const;</div><div>bool await_ready() const;</div><div><br><=
/div><div><br></div><div>--Shahms</div><span><div>&nbsp;</div><blockquote c=
lass=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;padding-left:1ex;bor=
der-left-color:rgb(204,204,204);border-left-width:1px;border-left-style:sol=
id"><div dir=3D"ltr"><div>&nbsp;<span style=3D"font-family:arial,sans-serif=
;font-size:small"><br></span></div><blockquote class=3D"gmail_quote" style=
=3D"margin:0px 0px 0px 0.8ex;padding-left:1ex;border-left-color:rgb(204,204=
,204);border-left-width:1px;border-left-style:solid"><div dir=3D"ltr"><ul><=
li><font face=3D"arial, sans-serif">I've&nbsp;implemented such a thing myse=
lf, but wh</font>en await_result_t&lt;F&gt; is void, MSVC somewhat complain=
s that promise::set_result doesn't take 1 argument, which I believe is a co=
mpiler bug.<font face=3D"arial, sans-serif"><br></font></li></ul></div></bl=
ockquote><div>&nbsp;If you can send me a self-contained repro, I can debug =
it and suggest a workaround (and fix it in MSVC as well)</div><div><br></di=
v><div>Thank you very much for your feedback.</div><div><br></div><div>Gor<=
font face=3D"arial, sans-serif"><span style=3D"line-height:17px"><br></span=
></font></div></div></blockquote></span></div><div><div>

<p></p>

-- <br>
<br>
--- <br>
You received this message because you are subscribed to a topic in the Goog=
le Groups "ISO C++ Standard - Future Proposals" group.<br>
To unsubscribe from this topic, visit <a href=3D"https://groups.google.com/=
a/isocpp.org/d/topic/std-proposals/RF7OEseYcHI/unsubscribe" target=3D"_blan=
k" rel=3D"nofollow" onmousedown=3D"this.href=3D'https://groups.google.com/a=
/isocpp.org/d/topic/std-proposals/RF7OEseYcHI/unsubscribe';return true;" on=
click=3D"this.href=3D'https://groups.google.com/a/isocpp.org/d/topic/std-pr=
oposals/RF7OEseYcHI/unsubscribe';return true;">https://groups.google.com/a/=
<wbr>isocpp.org/d/topic/std-<wbr>proposals/RF7OEseYcHI/<wbr>unsubscribe</a>=
..<br>
To unsubscribe from this group and all its topics, send an email to <a href=
=3D"javascript:" target=3D"_blank" gdf-obfuscated-mailto=3D"-vjRbj3rmNIJ" r=
el=3D"nofollow" onmousedown=3D"this.href=3D'javascript:';return true;" oncl=
ick=3D"this.href=3D'javascript:';return true;">std-proposal...@<wbr>isocpp.=
org</a>.<br>
To post to this group, send email to <a href=3D"javascript:" target=3D"_bla=
nk" gdf-obfuscated-mailto=3D"-vjRbj3rmNIJ" rel=3D"nofollow" onmousedown=3D"=
this.href=3D'javascript:';return true;" onclick=3D"this.href=3D'javascript:=
';return true;">std-pr...@isocpp.org</a>.<br>
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/" target=3D"_blank" rel=3D"nofollow" onmousedown=3D"this.href=
=3D'http://groups.google.com/a/isocpp.org/group/std-proposals/';return true=
;" onclick=3D"this.href=3D'http://groups.google.com/a/isocpp.org/group/std-=
proposals/';return true;">http://groups.google.com/a/<wbr>isocpp.org/group/=
std-<wbr>proposals/</a>.<br>
</div></div></blockquote></div><br></div>

<p></p>

-- <br>
<br>
--- <br>
You received this message because you are subscribed to a topic in the Goog=
le Groups "ISO C++ Standard - Future Proposals" group.<br>
To unsubscribe from this topic, visit <a href=3D"https://groups.google.com/=
a/isocpp.org/d/topic/std-proposals/RF7OEseYcHI/unsubscribe" target=3D"_blan=
k" rel=3D"nofollow" onmousedown=3D"this.href=3D'https://groups.google.com/a=
/isocpp.org/d/topic/std-proposals/RF7OEseYcHI/unsubscribe';return true;" on=
click=3D"this.href=3D'https://groups.google.com/a/isocpp.org/d/topic/std-pr=
oposals/RF7OEseYcHI/unsubscribe';return true;">https://groups.google.com/a/=
<wbr>isocpp.org/d/topic/std-<wbr>proposals/RF7OEseYcHI/<wbr>unsubscribe</a>=
..<br>
To unsubscribe from this group and all its topics, send an email to <a href=
=3D"javascript:" target=3D"_blank" gdf-obfuscated-mailto=3D"-vjRbj3rmNIJ" r=
el=3D"nofollow" onmousedown=3D"this.href=3D'javascript:';return true;" oncl=
ick=3D"this.href=3D'javascript:';return true;">std-proposal...@<wbr>isocpp.=
org</a>.<br>
To post to this group, send email to <a href=3D"javascript:" target=3D"_bla=
nk" gdf-obfuscated-mailto=3D"-vjRbj3rmNIJ" rel=3D"nofollow" onmousedown=3D"=
this.href=3D'javascript:';return true;" onclick=3D"this.href=3D'javascript:=
';return true;">std-pr...@isocpp.org</a>.<br>
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/" target=3D"_blank" rel=3D"nofollow" onmousedown=3D"this.href=
=3D'http://groups.google.com/a/isocpp.org/group/std-proposals/';return true=
;" onclick=3D"this.href=3D'http://groups.google.com/a/isocpp.org/group/std-=
proposals/';return true;">http://groups.google.com/a/<wbr>isocpp.org/group/=
std-<wbr>proposals/</a>.<br>
</blockquote></div></div></div></div><div><div>

<p></p>

-- <br>
<br>
--- <br>
You received this message because you are subscribed to a topic in the Goog=
le Groups "ISO C++ Standard - Future Proposals" group.<br>
To unsubscribe from this topic, visit <a href=3D"https://groups.google.com/=
a/isocpp.org/d/topic/std-proposals/RF7OEseYcHI/unsubscribe" target=3D"_blan=
k" rel=3D"nofollow" onmousedown=3D"this.href=3D'https://groups.google.com/a=
/isocpp.org/d/topic/std-proposals/RF7OEseYcHI/unsubscribe';return true;" on=
click=3D"this.href=3D'https://groups.google.com/a/isocpp.org/d/topic/std-pr=
oposals/RF7OEseYcHI/unsubscribe';return true;">https://groups.google.com/a/=
<wbr>isocpp.org/d/topic/std-<wbr>proposals/RF7OEseYcHI/<wbr>unsubscribe</a>=
..<br>
To unsubscribe from this group and all its topics, send an email to <a href=
=3D"javascript:" target=3D"_blank" gdf-obfuscated-mailto=3D"-vjRbj3rmNIJ" r=
el=3D"nofollow" onmousedown=3D"this.href=3D'javascript:';return true;" oncl=
ick=3D"this.href=3D'javascript:';return true;">std-proposal...@<wbr>isocpp.=
org</a>.<br>
To post to this group, send email to <a href=3D"javascript:" target=3D"_bla=
nk" gdf-obfuscated-mailto=3D"-vjRbj3rmNIJ" rel=3D"nofollow" onmousedown=3D"=
this.href=3D'javascript:';return true;" onclick=3D"this.href=3D'javascript:=
';return true;">std-pr...@isocpp.org</a>.<br>
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/" target=3D"_blank" rel=3D"nofollow" onmousedown=3D"this.href=
=3D'http://groups.google.com/a/isocpp.org/group/std-proposals/';return true=
;" onclick=3D"this.href=3D'http://groups.google.com/a/isocpp.org/group/std-=
proposals/';return true;">http://groups.google.com/a/<wbr>isocpp.org/group/=
std-<wbr>proposals/</a>.<br>
</div></div></blockquote></div><br></div>
</blockquote></div>

<p></p>

-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_198_202388806.1428684646289--
------=_Part_197_1750760000.1428684646289--

.