Topic: std::future::fetch() to provide lock free
Author: Sergey Vidyuk <sir.vestnik@gmail.com>
Date: Mon, 15 May 2017 20:36:44 -0700 (PDT)
Raw View
------=_Part_1947_2075370230.1494905804671
Content-Type: multipart/alternative;
boundary="----=_Part_1948_822286151.1494905804671"
------=_Part_1948_822286151.1494905804671
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
=D0=B2=D1=82=D0=BE=D1=80=D0=BD=D0=B8=D0=BA, 16 =D0=BC=D0=B0=D1=8F 2017 =D0=
=B3., 4:08:51 UTC+7 =D0=BF=D0=BE=D0=BB=D1=8C=D0=B7=D0=BE=D0=B2=D0=B0=D1=82=
=D0=B5=D0=BB=D1=8C rmn...@gmail.com=20
=D0=BD=D0=B0=D0=BF=D0=B8=D1=81=D0=B0=D0=BB:
>
> I recently stumbled upon a post that talked about how futures are slow=20
> because get() blocks (
> https://isocpp.org/blog/2016/07/cppcon-2015-completion-t-improving-the-fu=
ture-t-with-monads-travis-gockel)=20
> even when you don't need to block. For example in a callback attached wi=
th=20
> .then()
>
> auto future =3D async(...);
> future.then([](std::future<int> future) {
> future.get(); // unnecessary locking
> });
>
> A lot of future libraries out there have a different versions of then to=
=20
> avoid this problem (for example Facebook's futures and in the=20
> aforementioned post). Why not have a version of get() that does no=20
> locking or atomic loads? And assume that the user will only call this=20
> within a callback attached with .then()?
>
> auto future =3D async(...);
> future.then([](std::future<int> future) {
> future.fetch(); // no unnecessary locking
> });
>
> I don't think that introducing unsafe function fo access to a potentially=
=20
uninitialized value in a shared state is a good design for safe high level=
=20
synchronization primitive. Right now I'm playing with my own Concurrency TS=
=20
future::then implementation and trying to solve the same performance issue=
=20
you are talking in a quite a different way.
The idea is the following:
* future keeps shared_ptr to shared_state
* shared_state is an interface with two implementations: ready (no=20
thread-synchronization performed in any function) and async (with=20
synchronization inside)
* async shared state has optional<read_shared_state> as a member so when=
=20
shared state is ready then shared_ptr<ready_shared_state> can be=20
constructed from shared_ptr<async_shared_state> with aliasing constructor.
* future passed to continuation holds pointer to ready_shared_state and=20
all of the operations on it are guarantied to perform no=20
threads-synchronization operations.
Sergey Vidyuk=20
--=20
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 e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/84708a30-3822-494e-b49f-49ecacd26707%40isocpp.or=
g.
------=_Part_1948_822286151.1494905804671
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><br>=D0=B2=D1=82=D0=BE=D1=80=D0=BD=D0=B8=D0=BA, 16 =D0=
=BC=D0=B0=D1=8F 2017 =D0=B3., 4:08:51 UTC+7 =D0=BF=D0=BE=D0=BB=D1=8C=D0=B7=
=D0=BE=D0=B2=D0=B0=D1=82=D0=B5=D0=BB=D1=8C rmn...@gmail.com =D0=BD=D0=B0=D0=
=BF=D0=B8=D1=81=D0=B0=D0=BB:<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">I recently stumbled upon a post that talked about how future=
s are slow because <font face=3D"courier new, monospace">get()</font> block=
s (<a href=3D"https://isocpp.org/blog/2016/07/cppcon-2015-completion-t-impr=
oving-the-future-t-with-monads-travis-gockel" target=3D"_blank" rel=3D"nofo=
llow" onmousedown=3D"this.href=3D'https://www.google.com/url?q\x3dhttps=
%3A%2F%2Fisocpp.org%2Fblog%2F2016%2F07%2Fcppcon-2015-completion-t-improving=
-the-future-t-with-monads-travis-gockel\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dA=
FQjCNHo5gnlMU7MCA0XvvOHj_4DiwHsTA';return true;" onclick=3D"this.href=
=3D'https://www.google.com/url?q\x3dhttps%3A%2F%2Fisocpp.org%2Fblog%2F2=
016%2F07%2Fcppcon-2015-completion-t-improving-the-future-t-with-monads-trav=
is-gockel\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHo5gnlMU7MCA0XvvOHj_4DiwH=
sTA';return true;">https://isocpp.org/blog/2016/<wbr>07/cppcon-2015-com=
pletion-t-<wbr>improving-the-future-t-with-<wbr>monads-travis-gockel</a>) e=
ven when you don't need to block. =C2=A0For example in a callback attac=
hed with <font face=3D"courier new, monospace">.then()</font><div><br></div=
><div><font face=3D"courier new, monospace">auto future =3D async(...);</fo=
nt></div><div><font face=3D"courier new, monospace">future.then([](std::fut=
ure<<wbr>int> future) {</font></div><div><font face=3D"courier new, m=
onospace">=C2=A0 =C2=A0 future.get(); //=C2=A0unnecessary=C2=A0locking</fon=
t></div><div><font face=3D"courier new, monospace">});</font></div><div><fo=
nt face=3D"courier new, monospace"><br></font></div><div><font face=3D"aria=
l, sans-serif">A lot of </font><font face=3D"courier new, monospace">future=
</font><font face=3D"arial, sans-serif"> libraries out there have a differe=
nt versions of then to avoid this problem (for example Facebook's futur=
es and in the aforementioned post). =C2=A0Why not have a version of </font>=
<font face=3D"courier new, monospace">get()</font><font face=3D"arial, sans=
-serif">=C2=A0that does no locking or atomic loads? =C2=A0And assume that t=
he user will only call this within a callback attached with </font><font fa=
ce=3D"courier new, monospace">.then()</font><font face=3D"arial, sans-serif=
">?</font></div><div><font face=3D"arial, sans-serif"><br></font></div><div=
><div><font face=3D"courier new, monospace">auto future =3D async(...);</fo=
nt></div><div><font face=3D"courier new, monospace">future.then([](std::fut=
ure<<wbr>int> future) {</font></div><div><font face=3D"courier new, m=
onospace">=C2=A0 =C2=A0 future.fetch(); // no unnecessary=C2=A0locking</fon=
t></div><div><font face=3D"courier new, monospace">});</font></div></div><d=
iv><font face=3D"courier new, monospace"><br></font></div></div></blockquot=
e><div>I don't think that introducing unsafe function fo access to a po=
tentially uninitialized value in a shared state is a good design for safe h=
igh level synchronization primitive. Right now I'm playing with my own =
Concurrency TS future::then implementation and trying to solve the same per=
formance issue you are talking in a quite a different way.<br><br>The idea =
is the following:<br>=C2=A0* future keeps shared_ptr to shared_state<br>=C2=
=A0* shared_state is an interface with two implementations: ready (no threa=
d-synchronization performed in any function) and async (with synchronizatio=
n inside)<br>=C2=A0* async shared state has optional<read_shared_state&g=
t; as a member so when shared state is ready then shared_ptr<ready_share=
d_state> can be constructed from shared_ptr<async_shared_state> wi=
th aliasing constructor.<br>=C2=A0* future passed to continuation holds poi=
nter to ready_shared_state and all of the operations on it are guarantied t=
o perform no threads-synchronization operations.<br><br>Sergey Vidyuk <br><=
/div></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" 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 />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/84708a30-3822-494e-b49f-49ecacd26707%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/84708a30-3822-494e-b49f-49ecacd26707=
%40isocpp.org</a>.<br />
------=_Part_1948_822286151.1494905804671--
------=_Part_1947_2075370230.1494905804671--
.
Author: Giovanni Piero Deretta <gpderetta@gmail.com>
Date: Tue, 16 May 2017 04:40:51 -0700 (PDT)
Raw View
------=_Part_2027_2026615980.1494934851457
Content-Type: multipart/alternative;
boundary="----=_Part_2028_736701160.1494934851457"
------=_Part_2028_736701160.1494934851457
Content-Type: text/plain; charset="UTF-8"
On Monday, May 15, 2017 at 10:08:51 PM UTC+1, rmn...@gmail.com wrote:
>
> I recently stumbled upon a post that talked about how futures are slow
> because get() blocks (
> https://isocpp.org/blog/2016/07/cppcon-2015-completion-t-improving-the-future-t-with-monads-travis-gockel)
> even when you don't need to block. For example in a callback attached with
> .then()
>
> auto future = async(...);
> future.then([](std::future<int> future) {
> future.get(); // unnecessary locking
> });
>
> A lot of future libraries out there have a different versions of then to
> avoid this problem (for example Facebook's futures and in the
> aforementioned post). Why not have a version of get() that does no
> locking or atomic loads? And assume that the user will only call this
> within a callback attached with .then()?
>
There is no reason for get to issue anything more expensive than a load
acquire, (or even consume) + cmp + (very predictable) branch which can be
very cheap. In fact there is no reason for locking to be used at all
(including in setting up and dispatching 'then' callback) in an std future
implementation outside of shared_future. It can be completely lock free as
long as only 'then' is used to wait for values.
--
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.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/ffb37277-c783-4e75-9057-3900ef3fe4f0%40isocpp.org.
------=_Part_2028_736701160.1494934851457
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Monday, May 15, 2017 at 10:08:51 PM UTC+1, rmn...@gmail=
..com 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">I =
recently stumbled upon a post that talked about how futures are slow becaus=
e <font face=3D"courier new, monospace">get()</font> blocks (<a href=3D"htt=
ps://isocpp.org/blog/2016/07/cppcon-2015-completion-t-improving-the-future-=
t-with-monads-travis-gockel" target=3D"_blank" rel=3D"nofollow" onmousedown=
=3D"this.href=3D'https://www.google.com/url?q\x3dhttps%3A%2F%2Fisocpp.o=
rg%2Fblog%2F2016%2F07%2Fcppcon-2015-completion-t-improving-the-future-t-wit=
h-monads-travis-gockel\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHo5gnlMU7MCA=
0XvvOHj_4DiwHsTA';return true;" onclick=3D"this.href=3D'https://www=
..google.com/url?q\x3dhttps%3A%2F%2Fisocpp.org%2Fblog%2F2016%2F07%2Fcppcon-2=
015-completion-t-improving-the-future-t-with-monads-travis-gockel\x26sa\x3d=
D\x26sntz\x3d1\x26usg\x3dAFQjCNHo5gnlMU7MCA0XvvOHj_4DiwHsTA';return tru=
e;">https://isocpp.org/blog/2016/<wbr>07/cppcon-2015-completion-t-<wbr>impr=
oving-the-future-t-with-<wbr>monads-travis-gockel</a>) even when you don=
9;t need to block. =C2=A0For example in a callback attached with <font face=
=3D"courier new, monospace">.then()</font><div><br></div><div><font face=3D=
"courier new, monospace">auto future =3D async(...);</font></div><div><font=
face=3D"courier new, monospace">future.then([](std::future<<wbr>int>=
future) {</font></div><div><font face=3D"courier new, monospace">=C2=A0 =
=C2=A0 future.get(); //=C2=A0unnecessary=C2=A0locking</font></div><div><fon=
t face=3D"courier new, monospace">});</font></div><div><font face=3D"courie=
r new, monospace"><br></font></div><div><font face=3D"arial, sans-serif">A =
lot of </font><font face=3D"courier new, monospace">future</font><font face=
=3D"arial, sans-serif"> libraries out there have a different versions of th=
en to avoid this problem (for example Facebook's futures and in the afo=
rementioned post). =C2=A0Why not have a version of </font><font face=3D"cou=
rier new, monospace">get()</font><font face=3D"arial, sans-serif">=C2=A0tha=
t does no locking or atomic loads? =C2=A0And assume that the user will only=
call this within a callback attached with </font><font face=3D"courier new=
, monospace">.then()</font><font face=3D"arial, sans-serif">?</font></div><=
/div></blockquote><div><br>There is no reason for get to issue anything mor=
e expensive than a load acquire, (or even consume) + cmp + (very predictabl=
e) branch=C2=A0 which can be very cheap. In fact there is no reason for loc=
king to be used at all (including in setting up and dispatching 'then&#=
39; callback) in an std future implementation outside of shared_future. It =
can be completely lock free as long as only 'then' is used to wait =
for values.<br></div><br></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" 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 />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/ffb37277-c783-4e75-9057-3900ef3fe4f0%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/ffb37277-c783-4e75-9057-3900ef3fe4f0=
%40isocpp.org</a>.<br />
------=_Part_2028_736701160.1494934851457--
------=_Part_2027_2026615980.1494934851457--
.
Author: Arthur O'Dwyer <arthur.j.odwyer@gmail.com>
Date: Tue, 16 May 2017 20:39:06 -0700 (PDT)
Raw View
------=_Part_2601_1740695624.1494992347010
Content-Type: multipart/alternative;
boundary="----=_Part_2602_64985465.1494992347010"
------=_Part_2602_64985465.1494992347010
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
On Monday, May 15, 2017 at 3:08:51 PM UTC-6, rmn...@gmail.com wrote:
>
> I recently stumbled upon a post that talked about how futures are slow=20
> because get() blocks (
> https://isocpp.org/blog/2016/07/cppcon-2015-completion-t-improving-the-fu=
ture-t-with-monads-travis-gockel)=20
> even when you don't need to block. For example in a callback attached wi=
th=20
> .then()
>
> auto future =3D async(...);
> future.then([](std::future<int> future) {
> future.get(); // unnecessary locking
> });
>
> A lot of future libraries out there have a different versions of then to=
=20
> avoid this problem (for example Facebook's futures and in the=20
> aforementioned post). Why not have a version of get() that does no=20
> locking or atomic loads? And assume that the user will only call this=20
> within a callback attached with .then()?
>
> auto future =3D async(...);
> future.then([](std::future<int> future) {
> future.fetch(); // no unnecessary locking
> });
>
I believe the type-safe way to design this API has already been designed=20
and used in practice, e.g. in Folly.
auto future =3D async(...);
future.then([](int result) {
use(result);
}).on_error([](std::exception_ptr exc) {
handle(exc);
});
That is, .then() allows "unwrapped" callbacks, and if you need to handle=20
the exceptional case, then you add an .on_error() handler. The above code=
=20
is 100% equivalent in semantics to
auto future =3D async(...);
future.then([](std::future<int> maybe_result) {
try {
int result =3D maybe_result.get();
use(result);
} catch (...) {
std::exception_ptr exc =3D std::current_exception();
handle(exc);
}
});
except that the former version is much much faster, because it doesn't have=
=20
to do any atomic operations and it doesn't have to throw any exceptions on=
=20
the exceptional path. (I'm fairly sure that throwing that exception is=20
going to be much much slower than the couple of atomic exchanges necessary=
=20
to lock and unlock the shared state of the future.)
I've also seen "unwrapped .then()" referred to as ".on_value()", which has=
=20
nice symmetry and also makes the metaprogramming much easier.
The .on_value()/.then() and .on_error() functions don't seem to be part of=
=20
std::experimental::future=20
<http://en.cppreference.com/w/cpp/experimental/future/then>, but of course=
=20
they should be. No actual codebase is going to implement .then() without a=
=20
fast .on_value()/.on_error() equivalent.
=E2=80=93Arthur
--=20
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 e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/08f959c0-27db-4988-8970-95b52a1f4d9c%40isocpp.or=
g.
------=_Part_2602_64985465.1494992347010
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Monday, May 15, 2017 at 3:08:51 PM UTC-6, rmn...@gmail.=
com 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">I r=
ecently stumbled upon a post that talked about how futures are slow because=
<font face=3D"courier new, monospace">get()</font> blocks (<a href=3D"http=
s://isocpp.org/blog/2016/07/cppcon-2015-completion-t-improving-the-future-t=
-with-monads-travis-gockel" target=3D"_blank" rel=3D"nofollow" onmousedown=
=3D"this.href=3D'https://www.google.com/url?q\x3dhttps%3A%2F%2Fisocpp.o=
rg%2Fblog%2F2016%2F07%2Fcppcon-2015-completion-t-improving-the-future-t-wit=
h-monads-travis-gockel\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHo5gnlMU7MCA=
0XvvOHj_4DiwHsTA';return true;" onclick=3D"this.href=3D'https://www=
..google.com/url?q\x3dhttps%3A%2F%2Fisocpp.org%2Fblog%2F2016%2F07%2Fcppcon-2=
015-completion-t-improving-the-future-t-with-monads-travis-gockel\x26sa\x3d=
D\x26sntz\x3d1\x26usg\x3dAFQjCNHo5gnlMU7MCA0XvvOHj_4DiwHsTA';return tru=
e;">https://isocpp.org/blog/2016/<wbr>07/cppcon-2015-completion-t-<wbr>impr=
oving-the-future-t-with-<wbr>monads-travis-gockel</a>) even when you don=
9;t need to block. =C2=A0For example in a callback attached with <font face=
=3D"courier new, monospace">.then()</font><div><br></div><div><font face=3D=
"courier new, monospace">auto future =3D async(...);</font></div><div><font=
face=3D"courier new, monospace">future.then([](std::future<<wbr>int>=
future) {</font></div><div><font face=3D"courier new, monospace">=C2=A0 =
=C2=A0 future.get(); //=C2=A0unnecessary=C2=A0locking</font></div><div><fon=
t face=3D"courier new, monospace">});</font></div><div><font face=3D"courie=
r new, monospace"><br></font></div><div><font face=3D"arial, sans-serif">A =
lot of </font><font face=3D"courier new, monospace">future</font><font face=
=3D"arial, sans-serif"> libraries out there have a different versions of th=
en to avoid this problem (for example Facebook's futures and in the afo=
rementioned post). =C2=A0Why not have a version of </font><font face=3D"cou=
rier new, monospace">get()</font><font face=3D"arial, sans-serif">=C2=A0tha=
t does no locking or atomic loads? =C2=A0And assume that the user will only=
call this within a callback attached with </font><font face=3D"courier new=
, monospace">.then()</font><font face=3D"arial, sans-serif">?</font></div><=
div><font face=3D"arial, sans-serif"><br></font></div><div><div><font face=
=3D"courier new, monospace">auto future =3D async(...);</font></div><div><f=
ont face=3D"courier new, monospace">future.then([](std::future<<wbr>int&=
gt; future) {</font></div><div><font face=3D"courier new, monospace">=C2=A0=
=C2=A0 future.fetch(); // no unnecessary=C2=A0locking</font></div><div><fo=
nt face=3D"courier new, monospace">});</font></div></div></div></blockquote=
><div><br></div><div>I believe the type-safe way to design this API has alr=
eady been designed and used in practice, e.g. in Folly.</div><div><br></div=
><div><font face=3D"courier new, monospace">=C2=A0 =C2=A0 auto future =3D a=
sync(...);</font></div><div><font face=3D"courier new, monospace">=C2=A0 =
=C2=A0 future.then([](int result) {</font></div><div><font face=3D"courier =
new, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 use(result);</font></div><div><=
font face=3D"courier new, monospace">=C2=A0 =C2=A0 }).on_error([](std::exce=
ption_ptr exc) {</font></div><div><font face=3D"courier new, monospace">=C2=
=A0 =C2=A0 =C2=A0 =C2=A0 handle(exc);</font></div><div><font face=3D"courie=
r new, monospace">=C2=A0 =C2=A0 });</font></div><div><br></div><div>That is=
, .then() allows "unwrapped" callbacks, and if you need to handle=
the exceptional case, then you add an .on_error() handler. =C2=A0The above=
code is 100% equivalent in semantics to</div><div><br></div><div><font fac=
e=3D"courier new, monospace">=C2=A0 =C2=A0 auto future =3D async(...);</fon=
t></div><div><font face=3D"courier new, monospace">=C2=A0 =C2=A0 future.the=
n([](std::future<int> maybe_result) {</font></div><div><font face=3D"=
courier new, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 try {</font></div><div>=
<font face=3D"courier new, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 int result =3D maybe_result.get();</font></div><div><font face=3D"co=
urier new, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 use(result)=
;</font></div><div><font face=3D"courier new, monospace">=C2=A0 =C2=A0 =C2=
=A0 =C2=A0 } catch (...) {</font></div><div><font face=3D"courier new, mono=
space">=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 std::exception_ptr exc =3D=
std::current_exception();</font></div><div><font face=3D"courier new, mono=
space">=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 handle(exc);</font></div><=
div><font face=3D"courier new, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 }</fo=
nt></div><div><font face=3D"courier new, monospace">=C2=A0 =C2=A0 });</font=
></div><div><br></div><div>except that the former version is much much fast=
er, because it doesn't have to do any atomic operations and it doesn=
9;t have to throw any exceptions on the exceptional path. =C2=A0(I'm fa=
irly sure that throwing that exception is going to be much much slower than=
the couple of atomic exchanges necessary to lock and unlock the shared sta=
te of the future.)</div><div><br></div><div><div>I've also seen "u=
nwrapped .then()" referred to as ".on_value()", which has ni=
ce symmetry and also makes the metaprogramming much easier.</div></div><div=
><br></div><div>The .on_value()/.then() and .on_error() functions <a href=
=3D"http://en.cppreference.com/w/cpp/experimental/future/then">don't se=
em to be part of std::experimental::future</a>, but of course they should b=
e. No actual codebase is going to implement .then() without a fast .on_valu=
e()/.on_error() equivalent.</div><div><br></div><div>=E2=80=93Arthur<br></d=
iv></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" 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 />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/08f959c0-27db-4988-8970-95b52a1f4d9c%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/08f959c0-27db-4988-8970-95b52a1f4d9c=
%40isocpp.org</a>.<br />
------=_Part_2602_64985465.1494992347010--
------=_Part_2601_1740695624.1494992347010--
.