fiber/doc/future.qbk
oliver Kowalke 20ca3705e7 pass stack-allocator to fiber in async()
- stack-allocator was mistakenly passed as argument to packaged_task<>
- additional overload for async() taking stack-allocator for fiber and
  allocator for packaged_task<>
2017-01-12 09:11:25 +01:00

429 lines
13 KiB
Plaintext

[/
Copyright Oliver Kowalke 2013.
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt
]
[section:future Future]
A future provides a mechanism to access the result of an asynchronous operation.
[#shared_state]
[heading shared state]
Behind a [template_link promise] and its [template_link future] lies an
unspecified object called their ['shared state]. The shared state is what will
actually hold the async result (or the exception).
The shared state is instantiated along with the [template_link promise].
Aside from its originating `promise<>`, a [template_link future] holds a
unique reference to a particular shared state. However, multiple
[template_link shared_future] instances can reference the same underlying
shared state.
As [template_link packaged_task] and [ns_function_link fibers..async] are
implemented using [template_link promise], discussions of shared state apply
to them as well.
[#class_future_status]
[heading Enumeration `future_status`]
Timed wait-operations (__wait_for__ and __wait_until__) return the state of the future.
enum class future_status {
ready,
timeout,
deferred // not supported yet
};
[heading `ready`]
[variablelist
[[Effects:] [The [link shared_state shared state] is ready.]]
]
[heading `timeout`]
[variablelist
[[Effects:] [The [link shared_state shared state] did not become ready before timeout has passed.]]
]
[note Deferred futures are not supported.]
[template_heading future]
A __future__ contains a [link shared_state shared state] which is not shared with any other future.
#include <boost/fiber/future/future.hpp>
namespace boost {
namespace fibers {
template< typename R >
class future {
public:
future() noexcept;
future( future const& other) = delete;
future & operator=( future const& other) = delete;
future( future && other) noexcept;
future & operator=( future && other) noexcept;
~future();
bool valid() const noexcept;
shared_future< R > share();
R get(); // member only of generic future template
R & get(); // member only of future< R & > template specialization
void get(); // member only of future< void > template specialization
std::exception_ptr get_exception_ptr();
void wait() const;
template< class Rep, class Period >
future_status wait_for(
std::chrono::duration< Rep, Period > const& timeout_duration) const;
template< typename Clock, typename Duration >
future_status wait_until(
std::chrono::time_point< Clock, Duration > const& timeout_time) const;
};
}}
[heading Default constructor]
future() noexcept;
[template future_ctor_variablelist[xfuture]
[variablelist
[[Effects:] [Creates a [xfuture] with no [link shared_state shared state].
After construction `false == valid()`.]]
[[Throws:] [Nothing.]]
]
]
[future_ctor_variablelist future]
[heading Move constructor]
future( future && other) noexcept;
[template future_move_copy_ctor_variablelist[xfuture post_valid]
[variablelist
[[Effects:] [Constructs a [xfuture] with the [link shared_state shared state] of other.
After construction [post_valid].]]
[[Throws:] [Nothing.]]
]
]
[future_move_copy_ctor_variablelist future..`false == other.valid()`]
[heading Destructor]
~future();
[template future_dtor_variablelist[xfuture end]
[variablelist
[[Effects:] [Destroys the [xfuture]; ownership is abandoned[end]]]
[[Note:] [[`~[xfuture]()] does ['not] block the calling fiber.]]
]
]
[future_dtor_variablelist future .]
Consider a sequence such as:
# instantiate [template_link promise]
# obtain its `future<>` via [member_link promise..get_future]
# launch [class_link fiber], capturing `promise<>`
# destroy `future<>`
# call [member_link promise..set_value]
The final `set_value()` call succeeds, but the value is silently discarded: no
additional `future<>` can be obtained from that `promise<>`.
[operator_heading future..operator_assign..operator=]
future & operator=( future && other) noexcept;
[variablelist
[[Effects:] [Moves the [link shared_state shared state] of other to `this`.
After the assignment, `false == other.valid()`.]]
[[Throws:] [Nothing.]]
]
[template future_valid[xfuture]
[member_heading [xfuture]..valid]
bool valid() const noexcept;
[variablelist
[[Effects:] [Returns `true` if [xfuture] contains a [link shared_state shared state].]]
[[Throws:] [Nothing.]]
]
]
[future_valid future]
[member_heading future..share]
shared_future< R > share();
[variablelist
[[Effects:] [Move the state to a __shared_future__.]]
[[Returns:] [a __shared_future__ containing the [link shared_state shared
state] formerly belonging to `*this`.]]
[[Postcondition:] [`false == valid()`]]
[[Throws:] [__future_error__ with error condition __no_state__.]]
]
[template future_method_wait[end] Waits until [member_link promise..set_value] or
[member_link promise..set_exception] is called[end]]
[member_heading future..get]
R get(); // member only of generic future template
R & get(); // member only of future< R & > template specialization
void get(); // member only of future< void > template specialization
[template future_get_variablelist[]
[variablelist
[[Precondition:] [`true == valid()`]]
[[Returns:] [[future_method_wait .] If [member_link promise..set_value] is
called, returns the value. If [member_link promise..set_exception] is called,
throws the indicated exception.]]
[[Postcondition:] [`false == valid()`]]
[[Throws:] [__future_error__ with error condition __no_state__,
__broken_promise__. Any exception passed to
`promise::set_exception()`.]]
]
]
[future_get_variablelist]
[template future_get_exception_ptr[xfuture]
[member_heading [xfuture]..get_exception_ptr]
std::exception_ptr get_exception_ptr();
[variablelist
[[Precondition:] [`true == valid()`]]
[[Returns:] [[future_method_wait .] If `set_value()` is called, returns a
default-constructed `std::exception_ptr`. If `set_exception()` is called,
returns the passed `std::exception_ptr`.]]
[[Throws:] [__future_error__ with error condition __no_state__.]]
[[Note:] [ `get_exception_ptr()` does ['not] invalidate the [`[xfuture]].
After calling `get_exception_ptr()`, you may still call [member_link
[xfuture]..get].]]
]
]
[future_get_exception_ptr future]
[template future_wait_etc[xfuture]
[member_heading [xfuture]..wait]
void wait();
[variablelist
[[Effects:] [[future_method_wait .]]]
[[Throws:] [__future_error__ with error condition __no_state__.]]
]
[template_member_heading [xfuture]..wait_for]
template< class Rep, class Period >
future_status wait_for( std::chrono::duration< Rep, Period > const& timeout_duration) const;
[variablelist
[[Effects:] [[future_method_wait , or `timeout_duration` has passed.]]]
[[Result:] [A `future_status` is returned indicating the reason for returning.]]
[[Throws:] [__future_error__ with error condition __no_state__ or
timeout-related exceptions.]]
]
[template_member_heading [xfuture]..wait_until]
template< typename Clock, typename Duration >
future_status wait_until( std::chrono::time_point< Clock, Duration > const& timeout_time) const;
[variablelist
[[Effects:] [[future_method_wait , or `timeout_time` has passed.]]]
[[Result:] [A `future_status` is returned indicating the reason for returning.]]
[[Throws:] [__future_error__ with error condition __no_state__ or
timeout-related exceptions.]]
]
]
[future_wait_etc future]
[template_heading shared_future]
A __shared_future__ contains a [link shared_state shared state] which might be
shared with other __shared_future__ instances.
#include <boost/fiber/future/future.hpp>
namespace boost {
namespace fibers {
template< typename R >
class shared_future {
public:
shared_future() noexcept;
~shared_future();
shared_future( shared_future const& other);
shared_future( future< R > && other) noexcept;
shared_future( shared_future && other) noexcept;
shared_future & operator=( shared_future && other) noexcept;
shared_future & operator=( future< R > && other) noexcept;
shared_future & operator=( shared_future const& other) noexcept;
bool valid() const noexcept;
R const& get(); // member only of generic shared_future template
R & get(); // member only of shared_future< R & > template specialization
void get(); // member only of shared_future< void > template specialization
std::exception_ptr get_exception_ptr();
void wait() const;
template< class Rep, class Period >
future_status wait_for(
std::chrono::duration< Rep, Period > const& timeout_duration) const;
template< typename Clock, typename Duration >
future_status wait_until(
std::chrono::time_point< Clock, Duration > const& timeout_time) const;
};
}}
[heading Default constructor]
shared_future();
[future_ctor_variablelist shared_future]
[heading Move constructor]
shared_future( future< R > && other) noexcept;
shared_future( shared_future && other) noexcept;
[future_move_copy_ctor_variablelist shared_future..`false == other.valid()`]
[heading Copy constructor]
shared_future( shared_future const& other) noexcept;
[future_move_copy_ctor_variablelist shared_future..`other.valid()` is unchanged]
[heading Destructor]
~shared_future();
[future_dtor_variablelist shared_future.. if not shared.]
[operator_heading shared_future..operator_assign..operator=]
shared_future & operator=( future< R > && other) noexcept;
shared_future & operator=( shared_future && other) noexcept;
shared_future & operator=( shared_future const& other) noexcept;
[variablelist
[[Effects:] [Moves or copies the [link shared_state shared state] of other to
`this`. After the assignment, the state of `other.valid()` depends on which
overload was invoked: unchanged for the overload accepting `shared_future
const&`, otherwise `false`.]]
[[Throws:] [Nothing.]]
]
[future_valid shared_future]
[member_heading shared_future..get]
R const& get(); // member only of generic shared_future template
R & get(); // member only of shared_future< R & > template specialization
void get(); // member only of shared_future< void > template specialization
[future_get_variablelist]
[future_get_exception_ptr shared_future]
[future_wait_etc shared_future]
[ns_function_heading fibers..async]
#include <boost/fiber/future/async.hpp>
namespace boost {
namespace fibers {
template< class Function, class ... Args >
future<
std::result_of_t<
std::decay_t< Function >( std::decay_t< Args > ... )
>
>
async( Function && fn, Args && ... args);
template< class Function, class ... Args >
future<
std::result_of_t<
std::decay_t< Function >( std::decay_t< Args > ... )
>
>
async( ``[link class_launch `launch`]`` policy, Function && fn, Args && ... args);
template< typename __StackAllocator__, class Function, class ... Args >
future<
std::result_of_t<
std::decay_t< Function >( std::decay_t< Args > ... )
>
>
async( ``[link class_launch `launch`]`` policy, __allocator_arg_t__, __StackAllocator__ salloc,
Function && fn, Args && ... args);
template< typename __StackAllocator__, typename Allocator, class Function, class ... Args >
future<
std::result_of_t<
std::decay_t< Function >( std::decay_t< Args > ... )
>
>
async( ``[link class_launch `launch`]`` policy, __allocator_arg_t__, __StackAllocator__ salloc,
Allocator alloc, Function && fn, Args && ... args);
}}
[variablelist
[[Effects:] [Executes `fn` in a [class_link fiber] and returns an associated
[template_link future].]]
[[Result:] [``future<
std::result_of_t<
std::decay_t< Function >( std::decay_t< Args > ... )
>
>`` representing the [link
shared_state shared state] associated with the asynchronous execution of
`fn`.]]
[[Throws:] [__fiber_error__ or __future_error__ if an error occurs.]]
[[Notes:] [The overloads accepting __allocator_arg_t__ use the passed
__StackAllocator__ when constructing the launched `fiber`. The overloads
accepting [class_link launch] use the passed `launch` when
constructing the launched `fiber`. The default `launch` is `post`, as
for the `fiber` constructor.]]
]
[note Deferred futures are not supported.]
[endsect]