ISO/IEC JTC1 SC22 WG21 N3129 = 10-0119 - 2010-08-20
Lawrence Crowl, crowl@google.com, Lawrence@Crowl.org
Problem
Solution
Wording
30.6.4 Associated asynchronous state [futures.state]
30.6.5 Class template promise [futures.promise]
30.6.6 Class template future [futures.unique_future]
30.6.7 Class template shared_future [futures.shared_future]
30.6.8 Class template atomic_future [futures.atomic_future]
30.6.10.1 packaged_task member functions [futures.task.members]
Within the Final Committee Draft, the specification for managing associated asynchronous state [futures.state] is confusing, sometimes omitted, and redundantly specified.
Define terms-of-art for releasing, making ready, and abandoning an associated asynchronous state. Define a term-of-art for waiting functions on an associated asynchronous state. Use those terms where appropriate.
This solution implements the intent of the existing wording. That is, there is no new functionality.
The wording is relative to the FCD.
Edit paragraph 3 as follows.
An asynchronous return object is an object that reads results from an associated asynchronous state. A waiting function of an asynchronous return object is one that potentially blocks to wait for the associated asynchronous state to be made ready.
Edit paragraph 5 as follows.
When the last reference to an associated asynchronous state is given up, any resources held by that associated asynchronous state are released.An asynchronous return object or an asynchronous provider release their associated asynchronous state as follows.
- If the return object or provider contains the last reference to that state, destroys that state.
- The return object or provider destroys the reference to that state.
An asynchronous provider makes ready an associated asynchronous state as follows.
- The provider marks that state as ready.
- The provider unblocks any concurrent agent waiting for the associated state to become ready.
An asynchronous provider abandons an associated asynchronous state as follows.
If that state is not ready,
- the provider stores an exception object of type
future_error
with an error condition ofbroken_promise
within that state, and then- the provider makes ready that state.
- The provider releases that state.
Edit paragraph 7, regarding the destructor, as follows.
Effects:
if the associated asynchronous state ofabandons any associated asynchronous state ([futures.state]).*this
is not ready, stores an exception object of typefuture_error
with an error condition ofbroken_promise
Any threads blocked in a function waiting for the asynchronous state associated with*this
to become ready are unblocked. Destroys*this
and releases its reference to its associated asynchronous state if any. If this is the last reference to that associated asynchronous state, destroys that state.
Edit paragraph 8, regarding the move assignment operator, as follows.
Effects: abandons any associated asynchronous state ([futures.state]) and then as if
promise<R>(std::move(rhs)).swap(*this)
.
Remove paragraph 9, as it is now redundant with the effects.
Postcondition:rhs
has no associated asynchronous state.*this
has the associated asynchronous state ofrhs
prior to the assignment.
Edit paragraph 18, regarding set_value
, as follows.
Effects: atomically stores
r
in the associated asynchronous state andsets that state to ready. Any threads blocked in a call of a blocking function of any future that refers to the same associated asynchronous state asmakes ready that state ([futures.state]).*this
are unblocked.
Edit paragraph 22, regarding set_exception
, as follows.
Effects: atomically stores
p
in the associated asynchronous state andsets that state to ready. Any threads blocked in a call of a blocking function of any future that refers to the same associated asynchronous state asmakes ready that state ([futures.state]).*this
are unblocked.
Edit paragraph 26, regarding set_value_at_thread_exit
, as follows.
Effects: Stores
r
in the associated asynchronous state without making readythe associated asynchronousthat statereadyimmediately. Schedulesthe associated asynchronousthat state to be made ready when the current thread exits, after all objects of thread storage duration associated with the current thread have been destroyed.
Edit paragraph 29, regarding set_exception_at_thread_exit
,
as follows.
Effects: Stores
p
in the associated asynchronous state without making readythe associated asynchronousthat statereadyimmediately. Schedulesthe associated asynchronousthat state to be made ready when the current thread exits, after all objects of thread storage duration associated with the current thread have been destroyed.
Edit paragraph 10, regarding the destructor, as follows.
Effects:
gives up the reference to itsreleases any associated asynchronous state ([futures.state]).- destroys
*this
.
Edit paragraph 11, regarding the move assignment operator, as follows.
Effects:
ifreleases any associated asynchronous state ([futures.state]).*this
referred to an associated asynchronous state prior to the assignment it gives up this reference.move assigns the contents of
rhs
to*this
.
Edit paragraph 13, regarding the destructor, as follows.
Effects:
gives up the reference to itsreleases any associated asynchronous state ([futures.state]).- destroys
*this
.
Edit paragraph 14, regarding the move assignment operator, as follows.
Effects:
ifreleases any associated asynchronous state ([futures.state]).*this
refers to an associated asynchronous state it gives up this reference.- assigns the contents of
rhs
to*this
.
Edit paragraph 16, regarding the copy assignment operator, as follows.
Effects:
ifreleases any associated asynchronous state ([futures.state]).*this
refers to an associated asynchronous state it gives up this reference.- assigns the contents of
rhs
to*this
. [Note: as a result,*this
refers to the same associated asynchronous state asrhs
(if any). —end note]
Edit paragraph 9, regarding the destructor, as follows.
Effects:
gives up the reference to itsreleases any associated asynchronous state ([futures.state]).- destroys
*this
.
Edit paragraph 10, regarding the copy assignment operator, as follows.
Effects:
- releases any associated asynchronous state.
- assigns the contents of
rhs
to*this
. [Note: as a result,*this
refers to the same associated asynchronous state asrhs
(if any). —end note]
Edit paragraph 9, regarding the move assignment operator, as follows.
Effects:
- releases any associated asynchronous state ([futures.state]).
packaged_task<R, ArgTypes...>(other).swap(*this)
.
Edit paragraph 10, regarding the destructor, as follows.
Effects:
if the associated asynchronous state ofabandons any associated asynchronous state ([futures.state]).*this
is not ready, stores an exception object of typefuture_error
with an error code ofbroken_promise
. Any threads blocked in a function waiting for the associated asynchronous state of*this
to become ready are unblocked. Destroys*this
and releases its reference to its associated asynchronous state (if any). If this is the last reference to that associated asynchronous state, destroys that state.
Edit within paragraph 24, regarding make_ready_at_thread_exit
,
as follows.
.... this shall be done without
making the state readymaking ready that state ([futures.state]) immediately. ....
Edit paragraph 27, regarding reset
, as follows.
Effects:
returns the object to a stateas ifa newly-constructed instance had just been assigned to*this
by*this = packaged_task(std::move(f))
, wheref
is the task stored in*this
. [Note: this constructs a new associated asynchronous state for*this
. The old state isdiscarded,abandoned ([futures.state]).as described in the destructor for—end note]packaged_task
.get_future
may now be called again for*this
.