2
0
mirror of https://github.com/boostorg/fiber.git synced 2026-02-12 12:02:54 +00:00
Files
fiber/doc/future.qbk

365 lines
11 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.]]
]
[heading `deferred`]
[variablelist
[[Effects:] [The function is deferred, e.g. result will be computed only when explictly requested.]]
[[Note:] [Not implemented yet.]]
]
[warning Launch policy `deferred`, which indicates you simply want to defer the function call until a later time (lazy evaluation), is not supported yet.]
[template_heading future]
A __future__ contains a [link shared_state shared state] which is not shared with any other future.
template< typename R >
class future {
public:
future() noexcept;
future( future && other) noexcept;
future( future const& other) = delete;
~future();
future & operator=( future && other) noexcept;
future & operator=( future const& other) = delete;
bool valid() const noexcept;
shared_future< R > share();
R get();
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();
[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] == other.valid()]]]
[[Throws:] [Nothing.]]
]
]
[future_move_copy_ctor_variablelist future..false]
[heading Destructor]
~future();
[template future_dtor_variablelist[xfuture end]
[variablelist
[[Effects:] [Destroys the [xfuture]; ownership is abandoned[end]]]
[[Throws:] [Nothing.]]
[[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__.]]
[[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();
[template future_get_variablelist[]
[variablelist
[[Precondition:] [`true == valid()`]]
[[Returns:] [[future_method_wait .] If `set_value()` is called, returns the
value. If `set_exception()` is called, throws the indicated exception.]]
[[Postcondition:] [`false == valid()`]]
[[Throws:] [__future_error__ with error condition __no_state__, or
__fiber_interrupted__. 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__ or __fiber_interrupted__.]]
]
]
[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__ or __fiber_interrupted__.]]
]
[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 __fiber_interrupted__.]]
]
[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 __fiber_interrupted__.]]
]
]
[future_wait_etc future]
[template_heading shared_future]
A __shared_future__ contains a [link shared_state shared state] which might be shared with other futures.
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 && 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 && other) noexcept;
shared_future( shared_future && other) noexcept;
[future_move_copy_ctor_variablelist shared_future..false]
[heading Copy constructor]
shared_future( shared_future const& other) noexcept;
[future_move_copy_ctor_variablelist shared_future..true]
[heading Destructor]
~shared_future();
[future_dtor_variablelist shared_future.. if not shared.]
[operator_heading shared_future..operator_assign..operator=]
shared_future & operator=( future && 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: `true` 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>
template< typename Fn, typename ... Args >
future< typename result_of< Fn&&( Args && ... ) >::type >
async( Fn && fn, Args && ... args);
template< typename StackAllocator, typename Fn, typename ... Args >
future< typename result_of< Fn&&( Args && ... ) >::type >
async( std::allocator_arg_t, StackAllocator salloc, Fn && fn, Args && ... args);
[variablelist
[[Effects:] [Executes `fn` in a [class_link fiber] and returns an associated
[template_link future].]]
[[Result:] [`future< typename result_of< Fn >::type >` representing the [link
shared_state shared state] associated with the asynchronous execution of
`fn`.]]
[[Throws:] [__fiber_exception__ or __future_error__ if an error occurs.]]
[[Notes:] [The overload accepting `std::allocator_arg_t` uses the passed
`StackAllocator` when constructing the launched `fiber`.]]
]
[endsect]