mirror of
https://github.com/boostorg/fiber.git
synced 2026-02-19 02:12:24 +00:00
Highlight predicate condition_variable::wait() method in condition_variable front matter. Rewrite the explanation of wait()'s Precondition. Add a condition_variables subsection about no spurious condition_variable wakeups. Remove "or spuriously" from wakeup conditions in wait*() methods. First pass through "spurious wakeup" section in Rationale. First pass through migration.qbk. Use lock_t throughout work_sharing.cpp, instead of lock_t, lock_count and explicit std::unique_lock<std::mutex> declarations. Unify treatment of main and dispatcher fibers. Clarify thread-safety requirements on sched_algorithm::notify() and suspend_until(). Clarify disable_interruption when rethrowing fiber_interrupted. Consolidate future<T>::get(): returns T whether T is R, R& or void. Mention nesting of disable_interruption (which matters) versus nesting of restore_interruption (which doesn't). Mention that a disable_interruption constructed within the scope of another disable_interruption is a no-op, both itself and when passed to restore_interruption. When packaged_task::operator()() stores a value or an exception, state "as if" by promise::set_value() or set_exception(): the shared state is set ready. Similarly for ~packaged_task() and ~promise() setting broken_promise. Sprinkle links to the Allocator concept, std::allocator and std::allocator_arg_t where referenced. Similarly for StackAllocator. Add more cross-reference links where Fiber classes and methods are mentioned. Also things like std::unique_lock and std::mutex. Clarify error condition for value_pop() when channel is close()d. Since fiber_specific_ptr::release() does not invoke cleanup, it should not throw an exception raised during cleanup.
186 lines
5.4 KiB
Plaintext
186 lines
5.4 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
|
|
]
|
|
|
|
[#class_packaged_task]
|
|
[section:packaged_task Template `packaged_task<>`]
|
|
|
|
A __packaged_task__ wraps a callable target that returns a value so that the
|
|
return value can be computed asynchronously.
|
|
|
|
Conventional usage of `packaged_task<>` is like this:
|
|
|
|
# Instantiate `packaged_task<>` with template arguments matching the signature
|
|
of the callable. Pass the callable to the [link packaged_task_packaged_task
|
|
constructor].
|
|
# Call [member_link packaged_task..get_future] and capture the returned
|
|
[template_link future] instance.
|
|
# Launch a [class_link fiber] to run the new `packaged_task<>`, passing any
|
|
arguments required by the original callable.
|
|
# Call [member_link fiber..detach] on the newly-launched `fiber`.
|
|
# At some later point, retrieve the result from the `future<>`.
|
|
|
|
This is, in fact, pretty much what [ns_function_link fibers..async]
|
|
encapsulates.
|
|
|
|
template< class R, typename ... Args >
|
|
class packaged_task< R( Args ... ) > {
|
|
public:
|
|
packaged_task() noexcept;
|
|
|
|
template< typename Fn >
|
|
explicit packaged_task( Fn &&);
|
|
|
|
template< typename Fn, typename __Allocator__ >
|
|
packaged_task( __allocator_arg_t__, Allocator const&, Fn &&);
|
|
|
|
packaged_task( packaged_task &&) noexcept;
|
|
|
|
packaged_task & operator=( packaged_task &&) noexcept;
|
|
|
|
packaged_task( packaged_task const&) = delete;
|
|
|
|
packaged_task & operator=( packaged_task const&) = delete;
|
|
|
|
~packaged_task();
|
|
|
|
void swap( packaged_task &) noexcept;
|
|
|
|
bool valid() const noexcept;
|
|
|
|
future< R > get_future();
|
|
|
|
void operator()( Args ...);
|
|
|
|
void reset();
|
|
};
|
|
|
|
template< typename Signature >
|
|
void swap( packaged_task< Signature > &, packaged_task< Signature > &) noexcept;
|
|
|
|
[heading Default constructor `packaged_task()`]
|
|
|
|
packaged_task() noexcept;
|
|
|
|
[variablelist
|
|
[[Effects:] [Constructs an object of class `packaged_task` with no [link
|
|
shared_state shared state].]]
|
|
[[Throws:] [Nothing.]]
|
|
]
|
|
|
|
[#packaged_task_packaged_task]
|
|
[heading Templated constructor `packaged_task()`]
|
|
|
|
template< typename Fn >
|
|
explicit packaged_task( Fn && fn);
|
|
|
|
template< typename Fn, typename __Allocator__ >
|
|
packaged_task( __allocator_arg_t__, Allocator const& alloc, Fn && fn);
|
|
|
|
[variablelist
|
|
[[Effects:] [Constructs an object of class `packaged_task` with a [link
|
|
shared_state shared state] and copies or moves the callable target `fn` to
|
|
internal storage.]]
|
|
[[Throws:] [Exceptions caused by memory allocation.]]
|
|
[[Note:] [The signature of `Fn` should have a return type convertible to `R`.]]
|
|
[[See also:] [__allocator_arg_t__]]
|
|
]
|
|
|
|
[heading Move constructor]
|
|
|
|
packaged_task( packaged_task && other) noexcept;
|
|
|
|
[variablelist
|
|
[[Effects:] [Creates a packaged_task by moving the [link shared_state shared
|
|
state] from `other`.]]
|
|
[[Postcondition:] [`other` contains no valid shared state.]]
|
|
[[Throws:] [Nothing.]]
|
|
]
|
|
|
|
[heading Destructor]
|
|
|
|
~packaged_task();
|
|
|
|
[variablelist
|
|
[[Effects:] [Destroys `*this` and abandons the [link shared_state shared
|
|
state] if shared state is ready; otherwise stores __future_error__ with error
|
|
condition __broken_promise__ as if by [member_link promise..set_exception]:
|
|
the shared state is set ready.]]
|
|
]
|
|
|
|
[operator_heading packaged_task..operator_assign..operator=]
|
|
|
|
packaged_task & operator=( packaged_task && other) noexcept;
|
|
|
|
[variablelist
|
|
[[Effects:] [Transfers the ownership of [link shared_state shared state] to
|
|
`*this`.]]
|
|
[[Postcondition:] [`other` contains no valid shared state.]]
|
|
[[Throws:] [Nothing.]]
|
|
]
|
|
|
|
[member_heading packaged_task..swap]
|
|
|
|
void swap( packaged_task & other) noexcept;
|
|
|
|
[variablelist
|
|
[[Effects:] [Swaps the [link shared_state shared state] between other and
|
|
`*this`.]]
|
|
[[Throws:] [Nothing.]]
|
|
]
|
|
|
|
[member_heading packaged_task..valid]
|
|
|
|
bool valid() const noexcept;
|
|
|
|
[variablelist
|
|
[[Effects:] [Returns `true` if `*this` contains a [link shared_state shared
|
|
state].]]
|
|
[[Throws:] [Nothing.]]
|
|
]
|
|
|
|
[member_heading packaged_task..get_future]
|
|
|
|
future< R > get_future();
|
|
|
|
[variablelist
|
|
[[Returns:] [A __future__ with the same [link shared_state shared state].]]
|
|
[[Throws:] [__future_error__ with __already_retrieved__ or __no_state__.]]
|
|
]
|
|
|
|
[operator_heading packaged_task..operator_apply..operator()]
|
|
|
|
void operator()( Args && ... args);
|
|
|
|
[variablelist
|
|
[[Effects:] [Invokes the stored callable target. Any exception thrown by the
|
|
callable target `fn` is stored in the [link shared_state shared state] as if
|
|
by [member_link promise..set_exception]. Otherwise, the value returned by `fn`
|
|
is stored in the shared state as if by [member_link promise..set_value].]]
|
|
[[Throws:] [__future_error__ with __no_state__.]]
|
|
]
|
|
|
|
[member_heading packaged_task..reset]
|
|
|
|
void reset();
|
|
|
|
[variablelist
|
|
[[Effects:] [Resets the [link shared_state shared state] and abandons the
|
|
result of previous executions. A new shared state is constructed.]]
|
|
[[Throws:] [__future_error__ with __no_state__.]]
|
|
]
|
|
|
|
[function_heading_for swap..packaged_task]
|
|
|
|
template< typename Signature >
|
|
void swap( packaged_task< Signature > & l, packaged_task< Signature > & r) noexcept;
|
|
|
|
[variablelist
|
|
[[Effects:] [Same as `l.swap( r)`.]]
|
|
]
|
|
|
|
[endsect]
|