Document Number: N3058=10-0048
Date: 2010-03-11
Project: Programming Language C++

Detlef Vollmann <dv@vollmann.ch>

N3058: Futures and Async Cleanup (Rev.)

Introduction

The adoption of N2996 and N2997 at the same meeting caused some editorial trouble, as the papers both were based on the previous working paper and were not properly aligned. [Big apologies to the editor!]

This paper tries to clean up the whole [futures] sub-clause.

Acknowledgements

Thanks to Anthony Williams, Jonathan Wakely, Daniel Krügler, Alisdair Meredith, José Daniel García Sánchez, Hans Boehm, Pete Becker, Alberto Ganesh Barbati and the Concurrency subgroup for their comments and contributions to this paper.

Resolved Issues

Apart from a number of editor's notes, this proposal resolves the following LWG issues:

1090 (Ready, added swap to header, otherwise copied verbatim)
1226 (Ready, copied verbatim)
1244 (New, agreed on enum return)
1266 (New, taken proposed semantics, but different wording, ok'ed by Anthony)
1269 (New, different wording, same semantics, ok'ed by Anthony)
1272 (New, proposed resolution copied verbatim)
1273 (Ready, proposed resolution copied verbatim)
1274 (Ready, proposed resolution copied verbatim)
1275 (New, suggestions from issue taken and created wording
1291 (New, proposed resolution copied with editorial change
1300 (Ready, proposed resolution copied verbatim)
1304 (Ready, proposed resolution copied verbatim)
1305 (New, proposed resolution partly taken)
1315 (Ready, proposed resolution copied verbatim)

Proposed Changes

The changes applied here assume that the proposed change of LWG issue 929 (decay_copy()) was already applied to the working paper.

LWG issue 1244 (New)

Add a new enumeration future_status to 30.6.1 [futures.overview] following the definition of the launch enumeration:

  enum class future_status {
      ready,
      timeout,
      deferred
  };

LWG issue 1226 (Tentatively Ready)

In 30.6.1 [futures.overview], header <future> synopsis:
Change:

    constexpr error_code make_error_code(future_errc e);
    constexpr error_condition make_error_condition(future_errc e);

    extern const error_category*& const future_category();

LWG issue 1090 (Ready)

In 30.6.1 [futures.overview], header <future> synopsis, after declaration of class template packaged_task:
Add:

    template <class R>
      void swap(packaged_task<R(ArgTypes...)>&, packaged_task<R(ArgTypes...)>&)

LWG issue 1315 (Tentatively Ready)

In 30.6.1 [futures.overview], header <future> synopsis:
Change:

    template <class F, class... Args>
      future<typename F::result_typeresult_of<F(Args...)>::type>
      async(F&& f, Args&&... args);
    template <class F, class... Args>
      future<typename F::result_typeresult_of<F(Args...)>::type>
      async(launch policy, F&& f, Args&&... args);

LWG issue 1226 (Tentatively Ready)

In 30.6.2 [futures.errors] near paragraph 1:
Change:

extern const error_category&* const future_category();

future_category shall point to a statically initialized object of a type derived from class error_category.
Returns: A reference to an object of a type derived from class error_category.
Near paragraph 3, change:
constexpr error_code make_error_code(future_errc e);
Returns: error_code(static_cast<int>(e), *future_category()).
Near paragraph 4, change:
constexpr error_codecondition make_error_condition(future_errc e);
Returns: error_condition(static_cast<int>(e), *future_category()).

LWG issue 1269 (New)

In 30.6.4 [futures.state], title:
Change:

Associated asynchronous state

In 30.6.4 [futures.state], paragraph 1ff:
Change:

If fully initialized, objects of type future ([future.future]), shared_future ([future.shared_future]), atomic_future ([future.atomic_future]), promise ([future.promise) and packaged_task ([future.task]) reference some state that is potentially shared between several such objects.

Many of the classes introduced in this sub-clause use some state to communicate results. This associated asynchronous state consists of some state information and some (possibly not yet evaluated) result, which can be a (possibly void) value or an exception. [Note: Futures, promises and tasks defined in this clause reference such associated asynchronous state. --end note]

[Note: The result can be any kind of object including a function to compute that result, as used by async for policy = launch::sync. --end note]

Objects that read results from associated asynchronous state are called asynchronous return objects.

Objects that provide such a result, are called asynchronous providers. The result of such an associated asynchronous state can be is set by

respective functions on the asynchronous provider. [Note: Such as promises or tasks. --end note] The means of setting the result of an associated asynchronous state is specified in the description of those classes and functions that create such a state object.

When the last reference to an associated asynchronous state is given up, any resources held by this associated asynchronous state are released.

An associated asynchronous state is ready only if it holds a value or an exception ready for retrieval. Waiting for an associated asynchronous state to become ready may invoke code to compute the result on the waiting thread, if so specified in the description of the class or function that creates such a state object.

TheCalls to functions that successfully set the stored result of an associated asynchronous state synchronize with ([intro.multithread]) calls to member functions of other objects referring to successfully detecting the ready status resulting from that setting the same associated asynchronous state and such calls are serialized. The storage of the result (whether normal or exceptional) into the associated asynchronous state happens-before ([intro.multithread]) that state is set to ready.

Accesses to the same associated asynchronous state through member functions of future, shared_future, atomic_future, promise or packaged_task objects conflict ([intro.multithread]).

LWG issue 1272 (New)

In 30.6.5 [futures.promise], synopsis:
Remove:

      void set_value(const R& r);

Clean-up

In 30.6.5 [futures.promise], paragraph 3, promise():
Change:

Effects: constructs a promise object and an associated asynchronous state. The second constructor uses the allocator a to allocate memory for the associated asynchronous state.

In 30.6.5 [futures.promise], paragraph 4f, promise(promise &&):
Change:

Effects: Constructs a new promise object and transfers ownership of the associated asynchronous state of rhs (if any) to the newly-constructed object.
Postcondition: rhs has no associated asynchronous state.

In 30.6.5 [futures.promise], paragraph 7, ~promise():
Change:

Effects: If the asynchronous state associated with *this is not ready, stores an exception of type future_error with an error codecondition of broken_promise as-if by >this->set_exception(copy_exception(future_error(future_errc::broken_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.

In 30.6.5 [futures.promise], paragraph 9, operator=():
Change:

Postcondition: rhs has no associated asynchronousstate. *this has the associated asynchronous state of rhs prior to the assignment.

LWG issue 1300 (Tentatively Ready)

In 30.6.5 [futures.promise], paragraph 12ff, swap():
Change:

Effects: swap(*this, other) Exchanges the associated asynchronous states of *this and other.
Postcondition: *this has the same associated asynchronous state (if any) as other prior to the call to swap. other has the same associated asynchronous state (if any) as *this prior to the call to swap.
Throws: Nothing.

Clean-up

In 30.6.5 [futures.promise], paragraph 14ff, get_future():
Change:

Returns: a future<R> object with the same associated asynchronous state as *this.
Throws: future_error if *this has no associated asynchronous state, or if get_future() has already been called on a promise with the associated asynchronous state of *this.
Error conditions:

LWG issue 1272 (New)

In 30.6.5 [futures.promise], before paragraph 17, set_value():
Change:

void promise::set_value(const R& r);

LWG issue 1291 (New)

In 30.6.5 [futures.promise], paragraph 17ff, set_value():
Change:

Effects: Atomically stores r in the associated asynchronous state and sets 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 as *this are unblocked.
Throws:
Error conditions:
Synchronization: Calls to set_value and set_exception on a single promise object are serialized.
[Note: And they synchronize and serialize with other functions through the referred associated asynchronous state. --end note]

Clean-up

In 30.6.5 [futures.promise], paragraph 21ff, set_exception():
Change:

Effects: Atomically stores p in the associated asynchronous state and sets 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 as *this are unblocked.
Throws: future_error if its associated asynchronous state is already ready.
Error conditions:
Synchronization: Calls to set_value and set_exception on a single promise object are serialized.
[Note: And they synchronize and serialize with other functions through the referred associated asynchronous state. --end note]

LWG issue 1275 (New)

In 30.6.6 [futures.unique_future], paragraph 1:
Change:

The class template future defines a type for asynchronous return objects which do not share their associated asynchronous state with other asynchronous return objects. A default-constructed future has no associated asynchronous state. future objects with associated asynchronous state can only be created by use of promise ([future.promise]) or packaged_task ([future.task]) objects, functions on asynchronous providers ([futures.state] or by the move constructor and share their associated asynchronous state with that promise or packaged_task. Their the original asynchronous provider. The result (values or exceptions) of future objects can be set by use of the promise ([future.promise]) or packaged_task ([future.task]) calling a respective function on an object that shares the same associated asynchronous state.

LWG issue 1273 (Tentatively Ready)

In 30.6.6 [futures.unique_future], paragraph 3, introduction:
Change:

The effect of calling any member function other than the destructor or the move-assignment operator or valid() on a future for which valid() == false is undefined.

LWG issue 1244 (New)

In 30.6.6 [futures.unique_future], after paragraph 3, synopsis:
Change:

  template <class Rep, class Period>
  boolfuture_status wait_for(const chrono::duration<Rep, Period>& rel_time) const;
  template <class Clock, class Duration>
  boolfuture_status wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;

Clean-up

In 30.6.6 [futures.unique_future], paragraph 5, future():

Change:

Effects: constructs an empty future that not does not refer to an associated asynchronous state.

In 30.6.6 [futures.unique_future], paragraph 7, future(future&&):
Change:

Effects: move constructs a future object that refers to the associated asynchronous state that was originally referred to by rhs (if any).

In 30.6.6 [futures.unique_future], paragraph 10, ~future():
Change:

Effects:
Synchronization: if the object's associated state is associated with a thread object created by a call to async (30.6.9) and no other future object refers to that associated state, calls the member function join on the thread object.

In 30.6.6 [futures.unique_future], paragraph 12, operator=():
Change:

Effects:

In 30.6.6 [futures.unique_future], paragraph 15ff, get():
Change:

Effects:
Returns:
Throws: the stored exception, if an exception was stored in the associated asynchronous state.

In 30.6.6 [futures.unique_future], paragraph 19, valid():
Change:

Returns: true only if *this refers to an associated asynchronous state.

In 30.6.6 [futures.unique_future], paragraph 21, wait():
Change:

Effects: if the associated state contains a deferred function, executes the deferred function. Otherwise, blocks until the associated asynchronous state is ready.

LWG issue 1244 (New)

In 30.6.6 [futures.unique_future], before paragraph 22, wait_for:
Change:

  template <class Rep, class Period>
  boolfuture_status wait_for(const chrono::duration<Rep, Period>& rel_time) const;

In 30.6.6 [futures.unique_future], paragraph 23f, wait_for:
Change:

Effects: if the associated state contains a deferred function, the behavior is unspecified. Otherwise, blocks until the associated asynchronous state is ready or until rel_time has elapsed.
Returns: true only if the associated state is ready.
  • future_status::deferred if the associated asynchronous state contains a deferred function that is not running.
  • future_status::ready if the associated asynchronous state is ready.
  • future_status::timeout if the function is returning because the time period specified by rel_time has elapsed.

In 30.6.6 [futures.unique_future], before paragraph 25, wait_until:
Change:

  template <class Clock, class Duration>
  boolfuture_status wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;

In 30.6.6 [futures.unique_future], paragraph 26f, wait_until:
Change:

Effects: blocks until the associated asynchronous state is ready or until the current time exceeds abs_time.
Returns: true only if the associated state is ready.
  • future_status::deferred if the associated asynchronous state contains a deferred function that is not running.
  • future_status::ready if the associated asynchronous state is ready.
  • future_status::timeout if the function is returning because the time point specified by abs_time has been reached.

LWG issue 1275 (New)

In 30.6.7 [future.shared_future], paragraph 1f, introduction:
Change:

The class template shared_future defines a type for asynchronous return objects which may share their associated asynchronous state with other asynchronous return objects. A default-constructed shared_future has no associated asynchronous state. A shared_future object with associated asynchronous state can only be created from another shared_future with associated state or a future object with associated state by conversion from a future object and share their associated asynchronous state with the original asynchronous provider of the associated state. TheirThe result (values or exceptions) of shared_future objects can be set by use of a promise ([future.promise]) or packaged_task ([future.task]) calling a respective function on an object that shares the same associated asynchronous state.

[Note:shared_future member functions do not synchronize with themselves, but they synchronize on the shared associated asynchronous state. --end note]

The effect of calling any member function other than the destructor or the move-assignment operator or valid() on a shared_future for which valid() == false is undefined.

LWG issue 1244 (New)

In 30.6.7 [future.shared_future], after paragraph 2, synopsis:
Change:

  template <class Rep, class Period>
  boolfuture_status wait_for(const chrono::duration<Rep, Period>& rel_time) const;
  template <class Clock, class Duration>
  boolfuture_status wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;

LWG issue 1304 (Tentatively Ready)

In 30.6.7 [future.shared_future], paragraph 4, shared_future():
Change:

Effects: constructs an empty shared_future that doesn't refer to an associated asynchronous state.
Postcondition: valid() == false
Throws: nothing.

Clean-up

In 30.6.7 [future.shared_future], paragraph 5, shared_future(const shared_future&):
Change:

Effects: constructs a shared_future object that refers to the same associated asynchronous state as rhs (if any).

In 30.6.7 [future.shared_future], paragraph 7, move-ctor shared_future:
Change:

Effects: move constructs a shared_future object that refers to the associated associated state that was originally referred to by rhs (if any).

In 30.6.7 [future.shared_future], paragraph 10f, ~shared_future():
Change:

Effects:
Synchronization: if the object's associated state is associated with a thread object created by a call to async (30.6.9) and no other future object refers to that associated state, calls the member function join on the thread object.

In 30.6.7 [future.shared_future], paragraph 12, move-assignment:
Change:

Effects:

In 30.6.7 [future.shared_future], paragraph 14, copy-assignment:
Change:

Effects:

In 30.6.7 [future.shared_future], paragraph 18ff, get():
Change:

Effects:
Returns:
Throws: the stored exception, if an exception was stored in the associated asynchronous state.

In 30.6.7 [future.shared_future], paragraph 21, valid():
Change:

Returns: true only if *this refers to an associated asynchronous state.

LWG issue 1304 (Tentatively Ready), clean-up

In 30.6.7 [future.shared_future], paragraph 22, wait():
Change:

Requires: valid() == true
Effects: if the associated state contains a deferred function, executes the deferred function. Otherwise, blocks until the associated asynchronous state is ready.

LWG issue 1304 (Tentatively Ready), LWG issue 1244 (New)

In 30.6.7 [future.shared_future], paragraph 23ff, wait_for()/wait_until():
Change:

  template <class Rep, class Period>
  boolfuture_status wait_for(const chrono::duration<Rep, Period>& rel_time) const;
Requires: valid() == true
Effects: if the associated state contains a deferred function, the behavior is unspecified. Otherwise, blocks until the associated asynchronous state is ready or until rel_time has elapsed.
Returns: true only if the associated state is ready.
  • future_status::deferred if the associated asynchronous state contains a deferred function that is not running.
  • future_status::ready if the associated asynchronous state is ready.
  • future_status::timeout if the function is returning because the time period specified by rel_time has elapsed.
  template <class Clock, class Duration>
  boolfuture_status wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
Requires: valid() == true
Effects: blocks until the associated asynchronous state is ready or until the current time exceeds abs_time.
Returns: true only if the associated state is ready.
  • future_status::deferred if the associated asynchronous state contains a deferred function that is not running.
  • future_status::ready if the associated asynchronous state is ready.
  • future_status::timeout if the function is returning because the time point specified by abs_time has been reached.

LWG issue 1275 (New)

In 30.6.8 [futures.atomic_future], paragraph 1:
Change:

The class template atomic_future defines a type for asynchronous return objects which may share their associated asynchronous state with other asynchronous return objects. A single atomic_future object may be shared between different threads. These objects can only be created by use of promise ([future.promise]) or packaged_task ([future.task]) objects. A default-constructed atomic_future has no associated asynchronous state. atomic_future objects with associated asynchronous state can be created by conversion from a future object and share their associated asynchronous state with the original asynchronous provider of the associated state. Their values or exceptions can be set by use of promise ([future.promise]) objects. The result (values or exceptions) of atomic_future objects can be set by calling a respective function on an object that shares the same associated asynchronous state.

LWG issue 1244 (New)

In 30.6.8 [futures.atomic_future], after paragraph 2, synopsis:
Change:

  template <class Rep, class Period>
  boolfuture_status wait_for(const chrono::duration<Rep, Period>& rel_time) const;
  template <class Clock, class Duration>
  boolfuture_status wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;

Clean-up

In 30.6.8 [futures.atomic_future], paragraph 3, atomic_future():
Change:

Effects: constructs an empty atomic_future that doesn't refer to an associated asynchronous state.

In 30.6.8 [futures.atomic_future], before paragraph 5, atomic_future(const atomic_future&):
Change:

Effects: constructs an atomic_future object that refers to the same associated asynchronous state as rhs (if any).

LWG issue 1274 (Tentatively Ready)

In 30.6.8 [futures.atomic_future], before paragraph 6, atomic_future(atomic_future<R>&& rhs):
Change:

atomic_future(atomic_future<R>&& rhs);
Effects: move constructs an atomic_future object that refers to the associated asynchronous state that was originally referred to by rhs (if any).

Clean-up

In 30.6.8 [futures.atomic_future], after paragraph 6, ~atomic_future():
Change:

Effects:

In 30.6.8 [futures.atomic_future], paragraph 7ff, operator=():
Change:

Requires: valid() == false
Effects: assigns the contents of rhs to *this. [Note: So *this refers to the same associated asynchronous state as rhs (if any). --end note]
Synchronization: This assignment performs an acquire operation on rhs and a release operation on the left-hand side *this.

In 30.6.8 [futures.atomic_future], paragraph 13ff, get():
Change:

Requires: valid() == true
Effects:
Returns:
Throws:
Error condition: with an error condition of no_state if the precondition is not met valid() == false.
[Note:: Contrary to future, calling get() more than once on the same object is well defined and just produces the result again. --end note]

Clean-up

In 30.6.8 [futures.atomic_future], paragraph 17, is_ready()ff:
Remove:

bool is_ready() const;
Requires: valid() == true
Returns: true only if the associated state is ready.
bool has_exception() const;
Returns: true only if the associated state is ready and the associated state contains an exception.
bool has_value() const;
Returns: true only if the associated state is ready and the associated state contains a value.

LWG issue 1305 (New), clean-up

In 30.6.8 [futures.atomic_future], paragraph 22, wait():
Change:

Effects: blocks until the associated asynchronous state is ready.
Throws: future_error if an error condition occurs.
Error conditions:
  • no_state — if *this has no associated asynchronous state.

LWG issue 1244 (New) and 1305 (New), clean-up

In 30.6.8 [futures.atomic_future], paragraph 23ff, wait_for()/wait_until():
Change:

  template <class Rep, class Period>
  boolfuture_status wait_for(const chrono::duration<Rep, Period>& rel_time) const;
Effects: blocks until the associated asynchronous state is ready or until rel_time has elapsed.
Returns: true only if the associated state is ready.
  • future_status::deferred if the associated asynchronous state contains a deferred function that is not running.
  • future_status::ready if the associated asynchronous state is ready.
  • future_status::timeout if the function is returning because the time period specified by rel_time has elapsed.
Throws: future_error if an error condition occurs.
Error condition: no_state if *this has no associated asynchronous state.
  template <class Clock, class Duration>
  boolfuture_status wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
Effects: blocks until the associated asynchronous state is ready or until the current time exceeds abs_time.
Returns: true only if the associated state is ready.
  • future_status::deferred if the associated asynchronous state contains a deferred function that is not running.
  • future_status::ready if the associated asynchronous state is ready.
  • future_status::timeout if the function is returning because the time point specified by abs_time has been reached.
Throws: future_error if an error condition occurs.
Error condition: no_state if *this has no associated asynchronous state.

Clean-up

In 30.6.9 [futures.async], just after the title:
Add:

async provides a mechanism to launch a function potentially in a new thread and provides the result of the function in a future object, with which it shares an associated asynchronous state.

LWG issue 1315 (Tentatively Ready)

In 30.6.9 [futures.async] synopsis:
Change:

    template <class F, class... Args>
      future<typename F::result_typeresult_of<F(Args...)>::type>
      async(F&& f, Args&&... args);
    template <class F, class... Args>
      future<typename F::result_typeresult_of<F(Args...)>::type>
      async(launch policy, F&& f, Args&&... args);

Clean-Up

In 30.6.9 [futures.async], paragraph 1, async():
Change:

Requires: F and each Ti in Args shall be CopyConstructible if an lvalue and otherwise satisfy the MoveConstructible requirements. INVOKE(f, w1, w2, ..., wN) (20.7.2 [func.require]) shall be a valid expression for some values w1, w2, ... , wN, where N == sizeof...(Args). INVOKE(decay_copy(std::forward<F>(f)), decay_copy(std::forward<Args>(args))...) (20.7.2 [func.require], 30.3.1.2 [thread.thread.constr]) shall be a valid expression."
 
Effects: Returns: an object of type future<typename F::result_type>.
The first function behaves the same as a call to the second function with a policy argument of launch::any and the same arguments for F and Args. The second function creates an associated asynchronous state that is associated with the returned future object. The further behavior of the second function depends on the policy argument as follows:
 
Returns: an object of type future<typename result_of<F(Args...)>::type> that refers to the associated asynchronous state created by this call to async.
 
Synchronization: the invocation of the async happens-before ([intro.multithread]) the invocation of f. [Note: this statement applies even when the corresponding future object is moved to another thread. --end note ]
If the invocation is not deferred, a call to a waiting function on asynchronous return objects that share the associated asynchronous state created by this async() call shall block until the associated thread has completed.
If the invocation is not deferred, the join() on the created thread happens-before [intro.multithread] the first function that successfully detects the ready status of the associated asynchronous state returns or before the function that gives up the last reference to the associated asynchronous state returns, whichever happens first.
If the invocation is deferred, the completion of the invocation of the deferred function happens-before the calls to the waiting functions return.

In 30.6.9 [futures.async], paragraph 5:
Change:

Error conditions:

LWG issue 1315 (Tentatively Ready)

In 30.6.9 [futures.async], after paragraph 5:
Add:

Remarks: The first signature shall not participate in overload resolution if decay<F>::type is std::launch.

Clean-up

In 30.6.10 [futures.futures_task], paragraph 1, introduction:
Change:

A packaged_task provides a means of wrapping a function or callable object so that the return value of the function or callable object is stored in a future when it is invoked. The associated state of a packaged_task object includes storage for a copy of this associated task.

When the packaged_task is invoked, its associated stored task is invoked, and the result (whether normal or exceptional) stored in the associated asynchronous state. Any futures that shares the associated asynchronous state will then be able to access the stored result.

LWG issue 1090 (Ready)

In 30.6.10 [futures.futures_task], synopsis, after definition of class template packaged_task:
Add:

    template <class R, class... Argtypes>
      void swap(packaged_task<R(ArgTypes...)>&, packaged_task<R(ArgTypes...)>&)

Clean-up

In 30.6.10 [futures.futures_task], paragraph 4, packaged_task():
Change:

Effects: constructs a packaged_task object with no associated asynchronous state nor stored task.

In 30.6.10 [futures.futures_task], paragraph 6f, ctor:
Change:

Requires: INVOKE (f, t1, t2, ..., tN, R) where t1, t2, ..., tN are values of the corresponding types in ArgTypes.... shall be a valid expression. Invoking a copy of f shall behave the same as invoking f.
Effects: constructs a new packaged_task object and stores with a copy of f stored in the associated state as the object's associatedstored task. And constructs an associated asynchronous state. The constructors that take an Allocator argument use it to allocate memory needed to store the internal data structures.

In 30.6.10 [futures.futures_task], paragraph 9f, move-ctor:
Change:

Effects: constructs a new packaged_task object and transfers other's stored task and ownership of other's associated asynchronous state to *this, leaving other with no associated asynchronous state.
Postcondition: other has no associated asynchronous state.
Throws: nothing.

In 30.6.10 [futures.futures_task], paragraph 13, ~packaged_task():
Change:

Effects: If the asynchronous state associated with *this is not ready, stores an exception of type future_error with an error codecondition of broken_promise. Any threads blocked in a member function of future, shared_future or atomic_future waiting for the asynchronous state associated with *this to become ready are unblocked.
Destroys *this and the stored task, if any, 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.

In 30.6.10 [futures.futures_task], paragraph 15f, swap():
Change:

Effects: exchanges the associated asynchronous states and stored tasks of *this and other.
Postcondition: *this has the same associated asynchronous state and stored task (if any) as other prior to the call to swap. other has the same associated asynchronous state and stored task (if any) as *this prior to the call to swap.

In 30.6.10 [futures.futures_task], paragraph 18, operator bool():
Change:

Returns: true if and only if *this has an associated asynchronous state.

In 30.6.10 [futures.futures_task], paragraph 20ff, get_future():
Change:

Returns: a future object that shares the same associated asynchronous state as *this.
Throws: std::future_error if an error occurs.
Error conditions:

In 30.6.10 [futures.futures_task], paragraph 20ff, operator()():
Change:

Effects: INVOKE (f, t1, t2, ..., tN, R), where f is the stored task in associated state of *this and t1, t2, ..., tN are the values in args.... If the task returns normally, the return value is stored as the asynchronous result in the asynchronous state associated with *this, otherwise the exception thrown by the task is stored. The asynchronous state associated with *this is made ready, and any threads blocked in a member function of future, shared_future or atomic_future waiting for the asynchronous state associated with *this to become ready are unblocked.
Throws: std::future_error if there is no associated asynchrounous state or the stored task has already been invoked.
Error conditions:
Synchronization: A successful call to operator() synchronizes with ([intro.multithread]) a call to any member function of a future object, shared_future object or atomic_future object that shares the same associated asynchronous state. The completion of the invocation of the associatedstored task and the storage of the result (whether normal or exceptional) into the associated asynchronous state happens-before ([intro.multithread]) that state is set to ready.
[Note: operator() synchronizes and serializes with other functions through the referred associated asynchronous state. --end note]

In 30.6.10 [futures.futures_task], paragraph 27f, reset():
Change:

Effects: returns the object to a state as if a newly-constructed instance had just been assigned to *this by *this = packaged_task(std::move(f)), where f is the task stored in the associated state of *this.
[Note: This constructs a new associated asynchronous state for *this. The old state is discarded, as described in the destructor for packaged_task. get_future() may now be called again for *this. -- end note]
Throws:

LWG issue 1090 (Ready)

In 30.6.10 [futures.futures_task], after paragraph 28 (at the end):
Add:

    template <class R, class... Argtypes>
      void swap(packaged_task<R(ArgTypes...)>& x, packaged_task<R(ArgTypes...)>& y)
Effects: x.swap(y)
Throws: nothing.