<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
   "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=US-ASCII">
<title>A Simple Asynchronous Call</title>
</head>
<body>
<h1>A Simple Asynchronous Call</h1>

<p>
ISO/IEC JTC1 SC22 WG21 N2996 = 09-0186 - 2009-10-23
</p>

<p>
Lawrence Crowl, crowl@google.com, Lawrence@Crowl.org
<br>
Herb Sutter, hsutter@microsoft.com
</p>

<p>
This paper is a consensus of
"A simple async() (revision 1)" N2970 = 09-0160 - 2009-09-26
and
"An Asynchronous Call for C++" N2973 = 09-0163 - 2009-09-27.
</p>

<p>

<a href="#Introduction">Introduction</a><br>
<a href="#Acknowledgements">Acknowledgements</a><br>
<a href="#Wording">Proposed Wording</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#futures.overview">30.6.1 Overview [futures.overview]</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#futures.unique_future">30.6.5 Class template <code>unique_future</code> [futures.unique_future]</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#futures.shared_future">30.6.6 Class template <code>shared_future</code> [futures.shared_future]</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#futures.async">30.6.? Function template <code>async</code> [futures.async]</a><br>

</p>


<h2><a name="Introduction">Introduction</a></h2>

<p>
This paper represents a consensus proposal
on an asynchronous execution facility.
For rationale see papers
<a href="http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2009/n2970.pdf">
N2970</a>
and
<a href="http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2009/n2973.html">
N2973</a>.
For further background see paper
<a href="http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2009/n2974.html">
N2974</a>.
</p>

<p>
The following changes have been made
with respect to N2970 and N2973.
</p>
<ul>
<li>
A restoration of the variadic thread and async functions.
This restoration is a consequence of analysis and request
of the British Standards Institute.
</li>
<li>
A convergence on the "as if a new thread"
in the launching of asynchronous work.
This change avoids undefined behavior arising from
any delay in destroying thread-local variables,
but requires careful implementation to avoid excessive overhead.
</li>
<li>
Removal of the <code>is_ready</code>, <code>has_exception</code>,
and <code>has_value</code> query functions.
The presence of these function requires still other functions
in the synchronous case.
Evolution Working Group direction is that
the complexity in interface is as yet unjustified,
and prudence dictates a smaller initial interface.
</li>
<li>
Unspecified behavior for the use of timed wait functions
when the <code>unique_future</code>
was created from a deferred <code>async</code>.
</li>
<li>
The conversion from <code>unique_future</code> to <code>shared_future</code>
will execute any deferred work.
</li>
<li>
The use of an <code>enum class</code>
to better clarify the launching policy.
</li>
</ul>


<h2><a name="Acknowledgements">Acknowledgements</a></h2>

<p>
This solution derives from an extensive discussion
on the <cite>C++ threads standardisation</cite>
&lt;cpp-threads@decadentplace.org.uk&gt;
mailing list.
Thanks to the following contributors to the discussion on this topic:
Hans Boehm,
Beman Dawes,
Peter Dimov,
Pablo Halpern,
Howard Hinnant,
Oliver Kowalke,
Doug Lea,
Arch Robison,
Bjarne Stroustrup,
Alexander Terekhov,
and Anthony Williams.
Further discussion at the October 2009 meeting
include contributors beyond our ability to recount.
We gratefully acknowledge their contribution.
</p>


<h2><a name="Wording">Proposed Wording</a></h2>

<p>
The proposed wording is as follows.
It consists primarily of two new subsections.
</p>


<h3><a name="futures.overview">30.6.1 Overview [futures.overview]</a></h3>

<p>
Add to the synopsis the appropriate entries from the following sections.
</p>


<h3><a name="futures.unique_future">30.6.5 Class template <code>unique_future</code> [futures.unique_future]</a></h3>

<p>
Edit the synopsis as follows.
The edit removes query functions on <code>unique_future</code>.
</p>

<blockquote><pre><code>
namespace std {
  template &lt;class R&gt;
  class unique_future {
  public:
    unique_future(unique_future &amp;&amp;);
    unique_future(const unique_future&amp; rhs) = delete;
    ~unique_future();
    unique_future&amp; operator=(const unique_future&amp; rhs) = delete;
    // retrieving the value
    see below get();
    // functions to check state and wait for ready
<del>    bool is_ready() const;
    bool has_exception() const;
    bool has_value() const;</del>
    void wait() const;
    template &lt;class Rep, class Period&gt;
      bool wait_for(
        const chrono::duration&lt;Rep, Period&gt;&amp; rel_time) const;
    template &lt;class Clock, class Duration&gt;
      bool wait_until(
        const chrono::time_point&lt;Clock, Duration&gt;&amp; abs_time) const;
  };
}
</code></pre></blockquote>

<p>
After paragraph 4, add a new paragraph as follows.
This paragraph is a requirement on the destructor.
</p>

<blockquote><p>
<ins>
<i>Synchronization:</i>
If no other future refers to the associated state,
and that state is associated with a thread
created by an <code>async</code> call ([futures.async]),
as if <var>associated-thread</var><code>.join()</code>.
</ins>
</p></blockquote>

<p>
After paragraph 5, add a new paragraph as follows.
This paragraph is a requirement on <code>get()</code>.
</p>

<blockquote><p>
<ins>
<i>Effects:</i>
As if <code>wait()</code>.
</ins>
</p></blockquote>

<p>
Delete paragraph 6.
This synchronization now happens as a consequence
of "as if" <code>wait()</code>.
</p>

<blockquote><p>
<del>
<i>Synchronization:</i>
if <code>*this</code> is associated with a <code>promise</code> object,
the completion of <code>set_value()</code> or <code>set_exception()</code>
to that <code>promise</code> happens before (1.10) <code>get()</code> returns.
</del>
</p></blockquote>

<p>
Delete member functions <code>is_ready</code>, <code>has_exception</code>,
and <code>has_value</code>.
</p>

<blockquote>
<dl>
<dt><del><code>bool is_ready() const;</code></del></dt>
<dd><p><del><i>Returns:</i>
<code>true</code> only if the associated state
holds a value or an exception ready for retrieval.
</del></p>
<p><del><i>Remark:</i>
the return value is unspecified after a call to <code>get()</code>.
</del></p>
</dd>
<dt><del><code>bool has_exception() const;</code></del></dt>
<dd><del><i>Returns:</i>
<code>true</code> only if <code>is_ready() == true</code>
and the associated state contains an exception.
</del></dd>
<dt><del><code>bool has_value() const;</code></del></dt>
<dd><del><i>Returns:</i>
<code>true</code> only if <code>is_ready() == true</code>
and the associated state contains a value.
</del>
</dd>
</dl>
</blockquote>

<p>
Edit paragraph 13 as follows.
</p>

<blockquote><p>
<i>Effects:</i>
<ins>if the associated state contains a deferred function,
then execute the deferred function.
Otherwise,
</ins>
blocks until <code>*this</code> is ready.
</p></blockquote>

<p>
Edit paragraph 14 as follows.
</p>

<blockquote><p>
<i>Synchronization:</i>
if <code>*this</code> is associated with a <code>promise</code> object,
the completion of <code>set_value()</code> or <code>set_exception()</code>
to that <code>promise</code> happens before (1.10) <code>wait()</code> returns.
<ins>If the future is associated with a thread
created by an <code>async</code> call ([futures.async]),
as if <var>associated-thread</var><code>.join()</code></ins>.
</p></blockquote>

<p>
Edit the <code>wait_for()</code> prototype as follows.
</p>

<blockquote><pre><code>
template &lt;class Rep, class <del>period</del> <ins>Period</ins>&gt;
void wait_for(const chrono::duration&lt;Rep, Period&gt;&amp; rel_time) const;
</code></pre></blockquote>

<p>
Edit paragraph 16 as follows.
</p>

<blockquote><p>
<i>Effects:</i>
<ins>if the associated state contains a deferred function,
then the behavior is unspecified.
Otherwise,</ins>
blocks until <code>*this</code> is ready
or until <code>rel_time</code> has elapsed.
<ins>If <code>*this</code> is ready,
as if <code>wait()</code>.</ins>
</p></blockquote>


<h3><a name="futures.shared_future">30.6.6 Class template <code>shared_future</code> [futures.shared_future]</a></h3>

<p>
Edit the synopsis as follows.
</p>

<blockquote><pre><code>
namespace std {
  template &lt;class R&gt;
  class shared_future {
  public:
    shared_future(const shared_future&amp; rhs);
    shared_future(unique_future&lt;R&gt;&amp;&amp;);
    ~shared_future();
    shared_future &amp; operator=(const shared_future&amp; rhs) = delete;
    // retrieving the value
    see below get() const;
    // functions to check state and wait for ready
<del>    bool is_ready() const;
    bool has_exception() const;
    bool has_value() const;</del>
    void wait() const;
    template &lt;class Rep, class Period&gt;
    bool wait_for(const chrono::duration&lt;Rep, Period&gt;&amp; rel_time) const;
    template &lt;class Clock, class Duration&gt;
    bool wait_until(const chrono::time_point&lt;Clock, Duration&gt;&amp; abs_time) const;
  };
}
</code></pre></blockquote>

<p>
After paragraph 5, add a new paragraph as follows.
This paragraph is a note on the destructor.
</p>

<blockquote><p>
<ins>
<i>Synchronization:</i>
If no other future refers to the associated state,
and that state is associated with a thread
created by an <code>async</code> call ([futures.async]),
as if <var>associated-thread</var><code>.join()</code>.
</ins>
</p></blockquote>

<p>
After paragraph 6, add a new paragraph as follows.
This paragraph is a requirement on <code>get()</code>.
</p>

<blockquote><p>
<ins>
<i>Effects:</i>
As if <code>wait()</code>.
</ins>
</p></blockquote>

<p>
Remove the member functions <code>is_ready</code>,
<code>has_exception</code>, <code>has_value</code>.
</p>

<blockquote>
<dl>
<dt><del>bool is_ready() const;</del></dt>
<dd><del><i>Returns:</i>
<code>true</code> only if the associated state
holds a value or an exception ready for retrieval.
</del></dd>
<dt><del>bool has_exception() const;</del></dt>
<dd><del><i>Returns:</i>
<code>true</code> only if <code>is_ready() == true</code>
and the associated state contains an exception.
</del></dd>
<dt><del>bool has_value() const;</del></dt>
<dd><del><i>Returns:</i>
<code>true</code> only if <code>is_ready() == true</code>
and the associated state contains a value.
</del></dd>
</dl>
</blockquote>

<p>
Edit paragraph 13 as follows.
This paragraph describes <code>wait()</code>.
</p>

<blockquote><p>
<i>Effects:</i>
<ins>
if the associated state contains a deferred function,
then execute the deferred function.
Otherwise, 
</ins>
blocks until <code>*this</code> is ready.
</p></blockquote>

<p>
Edit paragraph 14 as follows.
</p>

<blockquote><p>
<i>Synchronization:</i>
if <code>*this</code> is associated with a <code>promise</code> object,
the completion of <code>set_value()</code> or <code>set_exception()</code>
to that <code>promise</code> happens before (1.10) <code>get()</code> returns.
<ins>If the future is associated with a thread
created by an <code>async</code> call ([futures.async]),
as if <i>associated-thread</i><code>.join()</code>.</ins>
</p></blockquote>

<p>
Edit the <code>wait_for()</code> prototype as follows.
</p>

<blockquote><pre><code>
template &lt;class Rep, class <del>period</del> <ins>Period</ins>&gt;
void wait_for(const chrono::duration&lt;Rep, Period&gt;&amp; rel_time) const;
</code></pre></blockquote>

<p>
Edit paragraph 16 as follows.
This paragraph describes <code>wait_for()</code>.
</p>

<blockquote><p>
<i>Effects:</i>
<ins>if the associated state contains a deferred function,
then the behavior is unspecified.
Otherwise,</ins>
blocks until <code>*this</code> is ready
or until <code>rel_time</code> has elapsed.
</p></blockquote>


<h3><a name="futures.async">30.6.? Function template <code>async</code> [futures.async]</a></h3>

<p>
Add the following section.
</p>

<blockquote>

<pre><code>
enum class launch { any, async, sync };
</code></pre>

<pre><code>
template&lt;class F, class ...Args&gt;
&nbsp;&nbsp;&nbsp;&nbsp;unique_future&lt;typename F::result_type&gt;
&nbsp;&nbsp;&nbsp;&nbsp;async( F&amp;&amp; f, Args&amp;&amp;... args );
</code></pre>
<pre><code>
template&lt;class F, class ...Args&gt;
&nbsp;&nbsp;&nbsp;&nbsp;unique_future&lt;typename F::result_type&gt;
&nbsp;&nbsp;&nbsp;&nbsp;async( launch policy, F&amp;&amp; f, Args&amp;&amp;... args );
</code></pre>

<p>
<i>Requires:</i>
<code>F</code> and each type <code>Ti</code> in <code>Args</code>
shall be <code>CopyConstructible</code> if an lvalue
and otherwise <code>MoveConstructible</code>.
<code>INVOKE (f, w1, w2, ..., wN)</code> (20.7.2)
shall be a valid expression
for some values <code>w1</code>, <code>w2</code>, ..., <code>wN</code>,
where <code>N == sizeof...(Args)</code>.
</p>
<p>
<i>Effects:</i>
Constructs an object of type
<code>unique_future&lt;typename F::result_type&gt;</code>
([futures.unique_future]).
If the <code>policy</code> parameter is not present,
then as if the policy parameter were <code>launch::any</code>.
If <code>policy</code> is <code>launch::async</code>,
executes <code>INVOKE (f, w1, w2, ..., wN)</code>
as if in a new <code>thread</code> of execution.
Any return value is captured by the <code>unique_future</code>.
Any exception not caught by <code>f</code>
is captured by the <code>unique_future</code>.
The <code>thread</code> is <dfn>associated</dfn>
with the <code>unique_future</code>,
and affects the behavior of the <code>unique_future</code>.
If <code>policy</code> is <code>launch::sync</code>,
then <code>INVOKE (f, w1, w2, ..., wN)</code>
is associated with the returned <code>unique_future</code>.
The invocation is said to be <dfn>deferred</dfn>.
If <code>policy</code> is <code>launch::any</code>,
the implementation may choose either policy above
at any call to <code>async</code>.
[<i>Note:</i>
Implementations should defer invocations
when no more concurrency can be effectively exploited.
&mdash;<i>end note</i>]
</p>
<p>
<i>Synchronization:</i>
The invocation of the <code>async</code>
happens before (1.10 [intro.multithread]) the invocation of <code>f</code>.
[<i>Note:</i>
This statement applies even when
the corresponding <code>unique_future</code> is moved to another thread.
&mdash;<i>end note</i>]
</p>
<p>
<i>Throws:</i>
<code>std::system_error</code>
if <code>policy</code> is <code>launch::async</code>
and the implementation is unable to start a new thread.
</p>
<p>
<i>Error conditions:</i>
&mdash; <code>resource_unavailable_try_again</code> &mdash;
if <code>policy</code> is <code>launch::async</code>
and either the system lacked the necessary resources to create another thread,
or the system-imposed limit on the number of threads in a process
would be exceeded.
</p>

<p>
[<i>Example:</i>
Two items of <code>work</code> below <em>may</em> be executed concurrently.
</p>
<blockquote><pre><code>
extern int work1(int value);
extern int work2(int value);
int work(int value) {
  auto handle = std::async( [=]{ return work2(value); } );
  int tmp = work1(value);
  return tmp + handle.get();
}
</code></pre></blockquote>
<p>
&mdash;<i>end example:</i>]
[<i>Note:</i>
The statement
</p>
<blockquote><pre><code>
return work1(value) + handle.get();
</code></pre></blockquote>
<p>
might not result in concurrency
because <code>get()</code> may be evaluated before <code>work1()</code>,
thus forcing <code>work2</code> to be evaluated before <code>work1()</code>.
&mdash;<i>end note:</i>]
</p>

</blockquote>

</body>
</html>
