mirror of
https://github.com/boostorg/thread.git
synced 2026-02-09 11:32:12 +00:00
Compare commits
170 Commits
boost-1.41
...
sandbox-br
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
01e071233c | ||
|
|
8d22c3869b | ||
|
|
235ed4afe0 | ||
|
|
627cb7f774 | ||
|
|
09021af350 | ||
|
|
31c280d1fa | ||
|
|
629f344f34 | ||
|
|
db5f924e24 | ||
|
|
9be3eb282a | ||
|
|
effd891a16 | ||
|
|
13db35cbf5 | ||
|
|
0f2d480e3c | ||
|
|
9edc61e37b | ||
|
|
f4dab6aac5 | ||
|
|
9e0550d140 | ||
|
|
0d1701c509 | ||
|
|
f2f62f93ea | ||
|
|
8a329f66fb | ||
|
|
05d4c52918 | ||
|
|
8fd0dd0cc0 | ||
|
|
8eea5811ba | ||
|
|
a154c2adab | ||
|
|
10bf4ed576 | ||
|
|
60d12dd395 | ||
|
|
b4e9be3c52 | ||
|
|
dcebae6d4a | ||
|
|
0d776bcd26 | ||
|
|
2d6ed47cf2 | ||
|
|
ea06434425 | ||
|
|
6508eff95e | ||
|
|
69930684a9 | ||
|
|
b1931a3eda | ||
|
|
63b44d4e32 | ||
|
|
f7cb8d8141 | ||
|
|
48c857e02c | ||
|
|
442dc58e0f | ||
|
|
25460c652c | ||
|
|
31a98f0a1e | ||
|
|
36c44b6f45 | ||
|
|
27426b18d1 | ||
|
|
3ea9ce1c8c | ||
|
|
4dfc636c84 | ||
|
|
5fe4312c6c | ||
|
|
63e675a6bb | ||
|
|
e92aeac7d7 | ||
|
|
f1f7eac1f2 | ||
|
|
eff0c84553 | ||
|
|
58c8ce61c7 | ||
|
|
6ac5e6953a | ||
|
|
5d9ad59af2 | ||
|
|
3c48a05437 | ||
|
|
4462124ff2 | ||
|
|
373f557ef7 | ||
|
|
495e561398 | ||
|
|
d24a579033 | ||
|
|
77130424b4 | ||
|
|
eb30688937 | ||
|
|
880bac0633 | ||
|
|
851d6a987f | ||
|
|
9bebd7b35f | ||
|
|
309acb9597 | ||
|
|
a56887167e | ||
|
|
e984dff4e4 | ||
|
|
685e4d446b | ||
|
|
8af680f307 | ||
|
|
6c60cce60d | ||
|
|
5882a675bb | ||
|
|
a5e95845b3 | ||
|
|
5b83d81e40 | ||
|
|
c8e5ad564d | ||
|
|
5edfa273ff | ||
|
|
4db57bcb10 | ||
|
|
3f13340903 | ||
|
|
6abb53c9d3 | ||
|
|
fdd20a519e | ||
|
|
67cc49f333 | ||
|
|
31a34cd0b5 | ||
|
|
ef8c08ba99 | ||
|
|
2991ca6c6f | ||
|
|
52bace18b2 | ||
|
|
767d14ae4f | ||
|
|
1a5c911e36 | ||
|
|
6e42a04e43 | ||
|
|
28be2cfeef | ||
|
|
8be168fd87 | ||
|
|
eee95fef57 | ||
|
|
9ea179b052 | ||
|
|
6868280409 | ||
|
|
e00b764454 | ||
|
|
999613c686 | ||
|
|
c2661d7eb5 | ||
|
|
4d21dd1f47 | ||
|
|
a0a0e57527 | ||
|
|
d8af0d0b4e | ||
|
|
113288e3b0 | ||
|
|
afecfd7c2d | ||
|
|
94d89aac5f | ||
|
|
8831b13efc | ||
|
|
01f99da03a | ||
|
|
080654e3ef | ||
|
|
2ac2eb2a61 | ||
|
|
61b940b705 | ||
|
|
4a4f87e017 | ||
|
|
6d5e7f63a7 | ||
|
|
f77285f375 | ||
|
|
dc5d03a6dc | ||
|
|
ea0961b7f6 | ||
|
|
33d9f9774c | ||
|
|
86097fa038 | ||
|
|
70d9dbc45a | ||
|
|
3926fd3a20 | ||
|
|
7861cf1146 | ||
|
|
0516b86a6e | ||
|
|
ec735d3e9b | ||
|
|
1c5c070983 | ||
|
|
a5c02b73dc | ||
|
|
918b920670 | ||
|
|
de67d2e27e | ||
|
|
bc89df04cb | ||
|
|
c26a4cf082 | ||
|
|
6e1a866b13 | ||
|
|
f91986ad0d | ||
|
|
795cc23f3e | ||
|
|
a3695bd4a0 | ||
|
|
08dc521daf | ||
|
|
8b916d21b1 | ||
|
|
c40f47a78a | ||
|
|
e9fb470b06 | ||
|
|
343d049772 | ||
|
|
86f9480da4 | ||
|
|
8696b610ca | ||
|
|
6f13227eda | ||
|
|
58d5110e61 | ||
|
|
76e53c7bc5 | ||
|
|
cfb08be1a8 | ||
|
|
b5bbb7fb1c | ||
|
|
a76c33f8cc | ||
|
|
810306b8f3 | ||
|
|
6c22bdb3bd | ||
|
|
6a0d3e98bc | ||
|
|
3809321037 | ||
|
|
eef695bdf0 | ||
|
|
ab01ab1e4d | ||
|
|
c8d8a108a7 | ||
|
|
7afd9efcc5 | ||
|
|
56ded87ad2 | ||
|
|
82e503339b | ||
|
|
713d0c7ace | ||
|
|
25ad6e3f8f | ||
|
|
df0197b617 | ||
|
|
a89c4f01ad | ||
|
|
ae67099633 | ||
|
|
57542d3a5c | ||
|
|
9a1da14116 | ||
|
|
ed050d753d | ||
|
|
8bec363710 | ||
|
|
7c68e190a9 | ||
|
|
7ebf5ea3d1 | ||
|
|
11e0435a4b | ||
|
|
d15ee57cd1 | ||
|
|
56d660b7fd | ||
|
|
792958e693 | ||
|
|
914e67dc04 | ||
|
|
b50a7ccb61 | ||
|
|
f827709d42 | ||
|
|
36abb42175 | ||
|
|
40f3b1b4c8 | ||
|
|
4f35e25688 | ||
|
|
270e88edd7 | ||
|
|
5ded171247 |
28
CMakeLists.txt
Normal file
28
CMakeLists.txt
Normal file
@@ -0,0 +1,28 @@
|
||||
#
|
||||
# Copyright Troy D. Straszheim
|
||||
#
|
||||
# Distributed under the Boost Software License, Version 1.0.
|
||||
# See http://www.boost.org/LICENSE_1_0.txt
|
||||
#
|
||||
#----------------------------------------------------------------------------
|
||||
# This file was automatically generated from the original CMakeLists.txt file
|
||||
# Add a variable to hold the headers for the library
|
||||
set (lib_headers
|
||||
thread.hpp
|
||||
thread
|
||||
)
|
||||
|
||||
# Add a library target to the build system
|
||||
boost_library_project(
|
||||
thread
|
||||
SRCDIRS src
|
||||
TESTDIRS test
|
||||
HEADERS ${lib_headers}
|
||||
# DOCDIRS
|
||||
# DESCRIPTION
|
||||
MODULARIZED
|
||||
# AUTHORS
|
||||
# MAINTAINERS
|
||||
)
|
||||
|
||||
|
||||
@@ -180,6 +180,7 @@ rule requirements ( properties * )
|
||||
alias thread_sources
|
||||
: ## win32 sources ##
|
||||
win32/thread.cpp
|
||||
win32/exceptions.cpp
|
||||
win32/tss_dll.cpp
|
||||
win32/tss_pe.cpp
|
||||
: ## requirements ##
|
||||
@@ -189,6 +190,7 @@ alias thread_sources
|
||||
alias thread_sources
|
||||
: ## pthread sources ##
|
||||
pthread/thread.cpp
|
||||
pthread/exceptions.cpp
|
||||
pthread/once.cpp
|
||||
: ## requirements ##
|
||||
<threadapi>pthread
|
||||
|
||||
@@ -5,11 +5,7 @@
|
||||
http://www.boost.org/LICENSE_1_0.txt).
|
||||
]
|
||||
|
||||
[section:changes Changes since boost 1.40]
|
||||
|
||||
The 1.41.0 release of Boost adds futures to the thread library. There are also a few minor changes.
|
||||
|
||||
[heading Changes since boost 1.35]
|
||||
[section:changes Changes since boost 1.35]
|
||||
|
||||
The 1.36.0 release of Boost includes a few new features in the thread library:
|
||||
|
||||
|
||||
@@ -1,968 +0,0 @@
|
||||
[/
|
||||
(C) Copyright 2008-9 Anthony Williams.
|
||||
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:reference Futures Reference]
|
||||
|
||||
[section:future_state `state` enum]
|
||||
|
||||
namespace future_state
|
||||
{
|
||||
enum state {uninitialized, waiting, ready};
|
||||
}
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:unique_future `unique_future` class template]
|
||||
|
||||
template <typename R>
|
||||
class unique_future
|
||||
{
|
||||
unique_future(unique_future & rhs);// = delete;
|
||||
unique_future& operator=(unique_future& rhs);// = delete;
|
||||
|
||||
public:
|
||||
typedef future_state::state state;
|
||||
|
||||
unique_future();
|
||||
~unique_future();
|
||||
|
||||
// move support
|
||||
unique_future(unique_future && other);
|
||||
unique_future& operator=(unique_future && other);
|
||||
|
||||
void swap(unique_future& other);
|
||||
|
||||
// retrieving the value
|
||||
R&& get();
|
||||
|
||||
// functions to check state
|
||||
state get_state() const;
|
||||
bool is_ready() const;
|
||||
bool has_exception() const;
|
||||
bool has_value() const;
|
||||
|
||||
// waiting for the result to be ready
|
||||
void wait() const;
|
||||
template<typename Duration>
|
||||
bool timed_wait(Duration const& rel_time) const;
|
||||
bool timed_wait_until(boost::system_time const& abs_time) const;
|
||||
};
|
||||
|
||||
[section:default_constructor Default Constructor]
|
||||
|
||||
unique_future();
|
||||
|
||||
[variablelist
|
||||
|
||||
[[Effects:] [Constructs an uninitialized future.]]
|
||||
|
||||
[[Postconditions:] [[unique_future_is_ready_link `this->is_ready`] returns `false`. [unique_future_get_state_link
|
||||
`this->get_state()`] returns __uninitialized__.]]
|
||||
|
||||
[[Throws:] [Nothing.]]
|
||||
|
||||
]
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:destructor Destructor]
|
||||
|
||||
~unique_future();
|
||||
|
||||
[variablelist
|
||||
|
||||
[[Effects:] [Destroys `*this`.]]
|
||||
|
||||
[[Throws:] [Nothing.]]
|
||||
|
||||
]
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:move_constructor Move Constructor]
|
||||
|
||||
unique_future(unique_future && other);
|
||||
|
||||
[variablelist
|
||||
|
||||
[[Effects:] [Constructs a new future, and transfers ownership of the asynchronous result associated with `other` to `*this`.]]
|
||||
|
||||
[[Postconditions:] [[unique_future_get_state_link `this->get_state()`] returns the value of `other->get_state()` prior to the
|
||||
call. `other->get_state()` returns __uninitialized__. If `other` was associated with an asynchronous result, that result is now
|
||||
associated with `*this`. `other` is not associated with any asynchronous result.]]
|
||||
|
||||
[[Throws:] [Nothing.]]
|
||||
|
||||
[[Notes:] [If the compiler does not support rvalue-references, this is implemented using the boost.thread move emulation.]]
|
||||
|
||||
]
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:move_assignment Move Assignment Operator]
|
||||
|
||||
unique_future& operator=(unique_future && other);
|
||||
|
||||
[variablelist
|
||||
|
||||
[[Effects:] [Transfers ownership of the asynchronous result associated with `other` to `*this`.]]
|
||||
|
||||
[[Postconditions:] [[unique_future_get_state_link `this->get_state()`] returns the value of `other->get_state()` prior to the
|
||||
call. `other->get_state()` returns __uninitialized__. If `other` was associated with an asynchronous result, that result is now
|
||||
associated with `*this`. `other` is not associated with any asynchronous result. If `*this` was associated with an asynchronous
|
||||
result prior to the call, that result no longer has an associated __unique_future__ instance.]]
|
||||
|
||||
[[Throws:] [Nothing.]]
|
||||
|
||||
[[Notes:] [If the compiler does not support rvalue-references, this is implemented using the boost.thread move emulation.]]
|
||||
|
||||
]
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:swap Member function `swap()`]
|
||||
|
||||
void swap(unique_future & other);
|
||||
|
||||
[variablelist
|
||||
|
||||
[[Effects:] [Swaps ownership of the asynchronous results associated with `other` and `*this`.]]
|
||||
|
||||
[[Postconditions:] [[unique_future_get_state_link `this->get_state()`] returns the value of `other->get_state()` prior to the
|
||||
call. `other->get_state()` returns the value of `this->get_state()` prior to the call. If `other` was associated with an
|
||||
asynchronous result, that result is now associated with `*this`, otherwise `*this` has no associated result. If `*this` was
|
||||
associated with an asynchronous result, that result is now associated with `other`, otherwise `other` has no associated result.]]
|
||||
|
||||
[[Throws:] [Nothing.]]
|
||||
|
||||
]
|
||||
|
||||
[endsect]
|
||||
|
||||
|
||||
[section:get Member function `get()`]
|
||||
|
||||
R&& get();
|
||||
R& unique_future<R&>::get();
|
||||
void unique_future<void>::get();
|
||||
|
||||
[variablelist
|
||||
|
||||
[[Effects:] [If `*this` is associated with an asynchronous result, waits until the result is ready as-if by a call to
|
||||
__unique_future_wait__, and retrieves the result (whether that is a value or an exception).]]
|
||||
|
||||
[[Returns:] [If the result type `R` is a reference, returns the stored reference. If `R` is `void`, there is no return
|
||||
value. Otherwise, returns an rvalue-reference to the value stored in the asynchronous result.]]
|
||||
|
||||
[[Postconditions:] [[unique_future_is_ready_link `this->is_ready()`] returns `true`. [unique_future_get_state_link
|
||||
`this->get_state()`] returns __ready__.]]
|
||||
|
||||
[[Throws:] [__future_uninitialized__ if `*this` is not associated with an asynchronous result. __thread_interrupted__ if the result
|
||||
associated with `*this` is not ready at the point of the call, and the current thread is interrupted. Any exception stored in the
|
||||
asynchronous result in place of a value.]]
|
||||
|
||||
[[Notes:] [`get()` is an ['interruption point].]]
|
||||
|
||||
]
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:wait Member function `wait()`]
|
||||
|
||||
void wait();
|
||||
|
||||
[variablelist
|
||||
|
||||
[[Effects:] [If `*this` is associated with an asynchronous result, waits until the result is ready. If the result is not ready on
|
||||
entry, and the result has a ['wait callback] set, that callback is invoked prior to waiting.]]
|
||||
|
||||
[[Throws:] [__future_uninitialized__ if `*this` is not associated with an asynchronous result. __thread_interrupted__ if the result
|
||||
associated with `*this` is not ready at the point of the call, and the current thread is interrupted. Any exception thrown by the
|
||||
['wait callback] if such a callback is called.]]
|
||||
|
||||
[[Postconditions:] [[unique_future_is_ready_link `this->is_ready()`] returns `true`. [unique_future_get_state_link
|
||||
`this->get_state()`] returns __ready__.]]
|
||||
|
||||
[[Notes:] [`wait()` is an ['interruption point].]]
|
||||
|
||||
]
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:timed_wait_duration Member function `timed_wait()`]
|
||||
|
||||
template<typename Duration>
|
||||
bool timed_wait(Duration const& wait_duration);
|
||||
|
||||
[variablelist
|
||||
|
||||
[[Effects:] [If `*this` is associated with an asynchronous result, waits until the result is ready, or the time specified by
|
||||
`wait_duration` has elapsed. If the result is not ready on entry, and the result has a ['wait callback] set, that callback is
|
||||
invoked prior to waiting.]]
|
||||
|
||||
[[Returns:] [`true` if `*this` is associated with an asynchronous result, and that result is ready before the specified time has
|
||||
elapsed, `false` otherwise.]]
|
||||
|
||||
[[Throws:] [__future_uninitialized__ if `*this` is not associated with an asynchronous result. __thread_interrupted__ if the result
|
||||
associated with `*this` is not ready at the point of the call, and the current thread is interrupted. Any exception thrown by the
|
||||
['wait callback] if such a callback is called.]]
|
||||
|
||||
[[Postconditions:] [If this call returned `true`, then [unique_future_is_ready_link `this->is_ready()`] returns `true` and
|
||||
[unique_future_get_state_link `this->get_state()`] returns __ready__.]]
|
||||
|
||||
[[Notes:] [`timed_wait()` is an ['interruption point]. `Duration` must be a type that meets the Boost.DateTime time duration requirements.]]
|
||||
|
||||
]
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:timed_wait_absolute Member function `timed_wait()`]
|
||||
|
||||
bool timed_wait(boost::system_time const& wait_timeout);
|
||||
|
||||
[variablelist
|
||||
|
||||
[[Effects:] [If `*this` is associated with an asynchronous result, waits until the result is ready, or the time point specified by
|
||||
`wait_timeout` has passed. If the result is not ready on entry, and the result has a ['wait callback] set, that callback is invoked
|
||||
prior to waiting.]]
|
||||
|
||||
[[Returns:] [`true` if `*this` is associated with an asynchronous result, and that result is ready before the specified time has
|
||||
passed, `false` otherwise.]]
|
||||
|
||||
[[Throws:] [__future_uninitialized__ if `*this` is not associated with an asynchronous result. __thread_interrupted__ if the result
|
||||
associated with `*this` is not ready at the point of the call, and the current thread is interrupted. Any exception thrown by the
|
||||
['wait callback] if such a callback is called.]]
|
||||
|
||||
[[Postconditions:] [If this call returned `true`, then [unique_future_is_ready_link `this->is_ready()`] returns `true` and
|
||||
[unique_future_get_state_link `this->get_state()`] returns __ready__.]]
|
||||
|
||||
[[Notes:] [`timed_wait()` is an ['interruption point].]]
|
||||
|
||||
]
|
||||
|
||||
[endsect]
|
||||
|
||||
|
||||
[section:is_ready Member function `is_ready()`]
|
||||
|
||||
bool is_ready();
|
||||
|
||||
[variablelist
|
||||
|
||||
[[Effects:] [Checks to see if the asynchronous result associated with `*this` is set.]]
|
||||
|
||||
[[Returns:] [`true` if `*this` is associated with an asynchronous result, and that result is ready for retrieval, `false`
|
||||
otherwise.]]
|
||||
|
||||
[[Throws:] [Nothing.]]
|
||||
|
||||
]
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:has_value Member function `has_value()`]
|
||||
|
||||
bool has_value();
|
||||
|
||||
[variablelist
|
||||
|
||||
[[Effects:] [Checks to see if the asynchronous result associated with `*this` is set with a value rather than an exception.]]
|
||||
|
||||
[[Returns:] [`true` if `*this` is associated with an asynchronous result, that result is ready for retrieval, and the result is a
|
||||
stored value, `false` otherwise.]]
|
||||
|
||||
[[Throws:] [Nothing.]]
|
||||
|
||||
]
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:has_exception Member function `has_exception()`]
|
||||
|
||||
bool has_exception();
|
||||
|
||||
[variablelist
|
||||
|
||||
[[Effects:] [Checks to see if the asynchronous result associated with `*this` is set with an exception rather than a value.]]
|
||||
|
||||
[[Returns:] [`true` if `*this` is associated with an asynchronous result, that result is ready for retrieval, and the result is a
|
||||
stored exception, `false` otherwise.]]
|
||||
|
||||
[[Throws:] [Nothing.]]
|
||||
|
||||
]
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:get_state Member function `get_state()`]
|
||||
|
||||
future_state::state get_state();
|
||||
|
||||
[variablelist
|
||||
|
||||
[[Effects:] [Determine the state of the asynchronous result associated with `*this`, if any.]]
|
||||
|
||||
[[Returns:] [__uninitialized__ if `*this` is not associated with an asynchronous result. __ready__ if the asynchronous result
|
||||
associated with `*this` is ready for retrieval, __waiting__ otherwise.]]
|
||||
|
||||
[[Throws:] [Nothing.]]
|
||||
|
||||
]
|
||||
|
||||
[endsect]
|
||||
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:shared_future `shared_future` class template]
|
||||
|
||||
template <typename R>
|
||||
class shared_future
|
||||
{
|
||||
public:
|
||||
typedef future_state::state state;
|
||||
|
||||
shared_future();
|
||||
~shared_future();
|
||||
|
||||
// copy support
|
||||
shared_future(shared_future const& other);
|
||||
shared_future& operator=(shared_future const& other);
|
||||
|
||||
// move support
|
||||
shared_future(shared_future && other);
|
||||
shared_future(unique_future<R> && other);
|
||||
shared_future& operator=(shared_future && other);
|
||||
shared_future& operator=(unique_future<R> && other);
|
||||
|
||||
void swap(shared_future& other);
|
||||
|
||||
// retrieving the value
|
||||
R get();
|
||||
|
||||
// functions to check state, and wait for ready
|
||||
state get_state() const;
|
||||
bool is_ready() const;
|
||||
bool has_exception() const;
|
||||
bool has_value() const;
|
||||
|
||||
// waiting for the result to be ready
|
||||
void wait() const;
|
||||
template<typename Duration>
|
||||
bool timed_wait(Duration const& rel_time) const;
|
||||
bool timed_wait_until(boost::system_time const& abs_time) const;
|
||||
};
|
||||
|
||||
[section:default_constructor Default Constructor]
|
||||
|
||||
shared_future();
|
||||
|
||||
[variablelist
|
||||
|
||||
[[Effects:] [Constructs an uninitialized future.]]
|
||||
|
||||
[[Postconditions:] [[shared_future_is_ready_link `this->is_ready`] returns `false`. [shared_future_get_state_link
|
||||
`this->get_state()`] returns __uninitialized__.]]
|
||||
|
||||
[[Throws:] [Nothing.]]
|
||||
|
||||
]
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:get Member function `get()`]
|
||||
|
||||
const R& get();
|
||||
|
||||
[variablelist
|
||||
|
||||
[[Effects:] [If `*this` is associated with an asynchronous result, waits until the result is ready as-if by a call to
|
||||
__shared_future_wait__, and returns a `const` reference to the result.]]
|
||||
|
||||
[[Returns:] [If the result type `R` is a reference, returns the stored reference. If `R` is `void`, there is no return
|
||||
value. Otherwise, returns a `const` reference to the value stored in the asynchronous result.]]
|
||||
|
||||
[[Throws:] [__future_uninitialized__ if `*this` is not associated with an asynchronous result. __thread_interrupted__ if the
|
||||
result associated with `*this` is not ready at the point of the call, and the current thread is interrupted.]]
|
||||
|
||||
[[Notes:] [`get()` is an ['interruption point].]]
|
||||
|
||||
]
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:wait Member function `wait()`]
|
||||
|
||||
void wait();
|
||||
|
||||
[variablelist
|
||||
|
||||
[[Effects:] [If `*this` is associated with an asynchronous result, waits until the result is ready. If the result is not ready on
|
||||
entry, and the result has a ['wait callback] set, that callback is invoked prior to waiting.]]
|
||||
|
||||
[[Throws:] [__future_uninitialized__ if `*this` is not associated with an asynchronous result. __thread_interrupted__ if the result
|
||||
associated with `*this` is not ready at the point of the call, and the current thread is interrupted. Any exception thrown by the
|
||||
['wait callback] if such a callback is called.]]
|
||||
|
||||
[[Postconditions:] [[shared_future_is_ready_link `this->is_ready()`] returns `true`. [shared_future_get_state_link
|
||||
`this->get_state()`] returns __ready__.]]
|
||||
|
||||
[[Notes:] [`wait()` is an ['interruption point].]]
|
||||
|
||||
]
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:timed_wait_duration Member function `timed_wait()`]
|
||||
|
||||
template<typename Duration>
|
||||
bool timed_wait(Duration const& wait_duration);
|
||||
|
||||
[variablelist
|
||||
|
||||
[[Effects:] [If `*this` is associated with an asynchronous result, waits until the result is ready, or the time specified by
|
||||
`wait_duration` has elapsed. If the result is not ready on entry, and the result has a ['wait callback] set, that callback is
|
||||
invoked prior to waiting.]]
|
||||
|
||||
[[Returns:] [`true` if `*this` is associated with an asynchronous result, and that result is ready before the specified time has
|
||||
elapsed, `false` otherwise.]]
|
||||
|
||||
[[Throws:] [__future_uninitialized__ if `*this` is not associated with an asynchronous result. __thread_interrupted__ if the result
|
||||
associated with `*this` is not ready at the point of the call, and the current thread is interrupted. Any exception thrown by the
|
||||
['wait callback] if such a callback is called.]]
|
||||
|
||||
[[Postconditions:] [If this call returned `true`, then [shared_future_is_ready_link `this->is_ready()`] returns `true` and
|
||||
[shared_future_get_state_link `this->get_state()`] returns __ready__.]]
|
||||
|
||||
[[Notes:] [`timed_wait()` is an ['interruption point]. `Duration` must be a type that meets the Boost.DateTime time duration requirements.]]
|
||||
|
||||
]
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:timed_wait_absolute Member function `timed_wait()`]
|
||||
|
||||
bool timed_wait(boost::system_time const& wait_timeout);
|
||||
|
||||
[variablelist
|
||||
|
||||
[[Effects:] [If `*this` is associated with an asynchronous result, waits until the result is ready, or the time point specified by
|
||||
`wait_timeout` has passed. If the result is not ready on entry, and the result has a ['wait callback] set, that callback is invoked
|
||||
prior to waiting.]]
|
||||
|
||||
[[Returns:] [`true` if `*this` is associated with an asynchronous result, and that result is ready before the specified time has
|
||||
passed, `false` otherwise.]]
|
||||
|
||||
[[Throws:] [__future_uninitialized__ if `*this` is not associated with an asynchronous result. __thread_interrupted__ if the result
|
||||
associated with `*this` is not ready at the point of the call, and the current thread is interrupted. Any exception thrown by the
|
||||
['wait callback] if such a callback is called.]]
|
||||
|
||||
[[Postconditions:] [If this call returned `true`, then [shared_future_is_ready_link `this->is_ready()`] returns `true` and
|
||||
[shared_future_get_state_link `this->get_state()`] returns __ready__.]]
|
||||
|
||||
[[Notes:] [`timed_wait()` is an ['interruption point].]]
|
||||
|
||||
]
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:is_ready Member function `is_ready()`]
|
||||
|
||||
bool is_ready();
|
||||
|
||||
[variablelist
|
||||
|
||||
[[Effects:] [Checks to see if the asynchronous result associated with `*this` is set.]]
|
||||
|
||||
[[Returns:] [`true` if `*this` is associated with an asynchronous result, and that result is ready for retrieval, `false`
|
||||
otherwise.]]
|
||||
|
||||
[[Throws:] [Nothing.]]
|
||||
|
||||
]
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:has_value Member function `has_value()`]
|
||||
|
||||
bool has_value();
|
||||
|
||||
[variablelist
|
||||
|
||||
[[Effects:] [Checks to see if the asynchronous result associated with `*this` is set with a value rather than an exception.]]
|
||||
|
||||
[[Returns:] [`true` if `*this` is associated with an asynchronous result, that result is ready for retrieval, and the result is a
|
||||
stored value, `false` otherwise.]]
|
||||
|
||||
[[Throws:] [Nothing.]]
|
||||
|
||||
]
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:has_exception Member function `has_exception()`]
|
||||
|
||||
bool has_exception();
|
||||
|
||||
[variablelist
|
||||
|
||||
[[Effects:] [Checks to see if the asynchronous result associated with `*this` is set with an exception rather than a value.]]
|
||||
|
||||
[[Returns:] [`true` if `*this` is associated with an asynchronous result, that result is ready for retrieval, and the result is a
|
||||
stored exception, `false` otherwise.]]
|
||||
|
||||
[[Throws:] [Nothing.]]
|
||||
|
||||
]
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:get_state Member function `get_state()`]
|
||||
|
||||
future_state::state get_state();
|
||||
|
||||
[variablelist
|
||||
|
||||
[[Effects:] [Determine the state of the asynchronous result associated with `*this`, if any.]]
|
||||
|
||||
[[Returns:] [__uninitialized__ if `*this` is not associated with an asynchronous result. __ready__ if the asynchronous result
|
||||
associated with `*this` is ready for retrieval, __waiting__ otherwise.]]
|
||||
|
||||
[[Throws:] [Nothing.]]
|
||||
|
||||
]
|
||||
|
||||
[endsect]
|
||||
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:promise `promise` class template]
|
||||
|
||||
template <typename R>
|
||||
class promise
|
||||
{
|
||||
promise(promise & rhs);// = delete;
|
||||
promise & operator=(promise & rhs);// = delete;
|
||||
public:
|
||||
// template <class Allocator> explicit promise(Allocator a);
|
||||
|
||||
promise();
|
||||
~promise();
|
||||
|
||||
// Move support
|
||||
promise(promise && rhs);
|
||||
promise & operator=(promise&& rhs);
|
||||
|
||||
void swap(promise& other);
|
||||
// Result retrieval
|
||||
unique_future<R> get_future();
|
||||
|
||||
// Set the value
|
||||
void set_value(R& r);
|
||||
void set_value(R&& r);
|
||||
void set_exception(boost::exception_ptr e);
|
||||
|
||||
template<typename F>
|
||||
void set_wait_callback(F f);
|
||||
};
|
||||
|
||||
[section:default_constructor Default Constructor]
|
||||
|
||||
promise();
|
||||
|
||||
[variablelist
|
||||
|
||||
[[Effects:] [Constructs a new __promise__ with no associated result.]]
|
||||
|
||||
[[Throws:] [Nothing.]]
|
||||
|
||||
]
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:move_constructor Move Constructor]
|
||||
|
||||
promise(promise && other);
|
||||
|
||||
[variablelist
|
||||
|
||||
[[Effects:] [Constructs a new __promise__, and transfers ownership of the result associated with `other` to `*this`, leaving `other`
|
||||
with no associated result.]]
|
||||
|
||||
[[Throws:] [Nothing.]]
|
||||
|
||||
[[Notes:] [If the compiler does not support rvalue-references, this is implemented using the boost.thread move emulation.]]
|
||||
|
||||
]
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:move_assignment Move Assignment Operator]
|
||||
|
||||
promise& operator=(promise && other);
|
||||
|
||||
[variablelist
|
||||
|
||||
[[Effects:] [Transfers ownership of the result associated with `other` to `*this`, leaving `other` with no associated result. If there
|
||||
was already a result associated with `*this`, and that result was not ['ready], sets any futures associated with that result to
|
||||
['ready] with a __broken_promise__ exception as the result. ]]
|
||||
|
||||
[[Throws:] [Nothing.]]
|
||||
|
||||
[[Notes:] [If the compiler does not support rvalue-references, this is implemented using the boost.thread move emulation.]]
|
||||
|
||||
]
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:destructor Destructor]
|
||||
|
||||
~promise();
|
||||
|
||||
[variablelist
|
||||
|
||||
[[Effects:] [Destroys `*this`. If there was a result associated with `*this`, and that result is not ['ready], sets any futures
|
||||
associated with that task to ['ready] with a __broken_promise__ exception as the result.]]
|
||||
|
||||
[[Throws:] [Nothing.]]
|
||||
|
||||
]
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:get_future Member Function `get_future()`]
|
||||
|
||||
unique_future<R> get_future();
|
||||
|
||||
[variablelist
|
||||
|
||||
[[Effects:] [If `*this` was not associated with a result, allocate storage for a new asynchronous result and associate it with
|
||||
`*this`. Returns a __unique_future__ associated with the result associated with `*this`. ]]
|
||||
|
||||
[[Throws:] [__future_already_retrieved__ if the future associated with the task has already been retrieved. `std::bad_alloc` if any
|
||||
memory necessary could not be allocated.]]
|
||||
|
||||
]
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:set_value Member Function `set_value()`]
|
||||
|
||||
void set_value(R&& r);
|
||||
void set_value(const R& r);
|
||||
void promise<R&>::set_value(R& r);
|
||||
void promise<void>::set_value();
|
||||
|
||||
[variablelist
|
||||
|
||||
[[Effects:] [If `*this` was not associated with a result, allocate storage for a new asynchronous result and associate it with
|
||||
`*this`. Store the value `r` in the asynchronous result associated with `*this`. Any threads blocked waiting for the asynchronous
|
||||
result are woken.]]
|
||||
|
||||
[[Postconditions:] [All futures waiting on the asynchronous result are ['ready] and __unique_future_has_value__ or
|
||||
__shared_future_has_value__ for those futures shall return `true`.]]
|
||||
|
||||
[[Throws:] [__promise_already_satisfied__ if the result associated with `*this` is already ['ready]. `std::bad_alloc` if the memory
|
||||
required for storage of the result cannot be allocated. Any exception thrown by the copy or move-constructor of `R`.]]
|
||||
|
||||
]
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:set_exception Member Function `set_exception()`]
|
||||
|
||||
void set_exception(boost::exception_ptr e);
|
||||
|
||||
[variablelist
|
||||
|
||||
[[Effects:] [If `*this` was not associated with a result, allocate storage for a new asynchronous result and associate it with
|
||||
`*this`. Store the exception `e` in the asynchronous result associated with `*this`. Any threads blocked waiting for the asynchronous
|
||||
result are woken.]]
|
||||
|
||||
[[Postconditions:] [All futures waiting on the asynchronous result are ['ready] and __unique_future_has_exception__ or
|
||||
__shared_future_has_exception__ for those futures shall return `true`.]]
|
||||
|
||||
[[Throws:] [__promise_already_satisfied__ if the result associated with `*this` is already ['ready]. `std::bad_alloc` if the memory
|
||||
required for storage of the result cannot be allocated.]]
|
||||
|
||||
]
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:set_wait_callback Member Function `set_wait_callback()`]
|
||||
|
||||
template<typename F>
|
||||
void set_wait_callback(F f);
|
||||
|
||||
[variablelist
|
||||
|
||||
[[Preconditions:] [The expression `f(t)` where `t` is a lvalue of type __packaged_task__ shall be well-formed. Invoking a copy of
|
||||
`f` shall have the same effect as invoking `f`]]
|
||||
|
||||
[[Effects:] [Store a copy of `f` with the asynchronous result associated with `*this` as a ['wait callback]. This will replace any
|
||||
existing wait callback store alongside that result. If a thread subsequently calls one of the wait functions on a __unique_future__
|
||||
or __shared_future__ associated with this result, and the result is not ['ready], `f(*this)` shall be invoked.]]
|
||||
|
||||
[[Throws:] [`std::bad_alloc` if memory cannot be allocated for the required storage.]]
|
||||
|
||||
]
|
||||
|
||||
[endsect]
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:packaged_task `packaged_task` class template]
|
||||
|
||||
template<typename R>
|
||||
class packaged_task
|
||||
{
|
||||
packaged_task(packaged_task&);// = delete;
|
||||
packaged_task& operator=(packaged_task&);// = delete;
|
||||
|
||||
public:
|
||||
// construction and destruction
|
||||
template <class F>
|
||||
explicit packaged_task(F const& f);
|
||||
|
||||
explicit packaged_task(R(*f)());
|
||||
|
||||
template <class F>
|
||||
explicit packaged_task(F&& f);
|
||||
|
||||
// template <class F, class Allocator>
|
||||
// explicit packaged_task(F const& f, Allocator a);
|
||||
// template <class F, class Allocator>
|
||||
// explicit packaged_task(F&& f, Allocator a);
|
||||
|
||||
~packaged_task()
|
||||
{}
|
||||
|
||||
// move support
|
||||
packaged_task(packaged_task&& other);
|
||||
packaged_task& operator=(packaged_task&& other);
|
||||
|
||||
void swap(packaged_task& other);
|
||||
// result retrieval
|
||||
unique_future<R> get_future();
|
||||
|
||||
// execution
|
||||
void operator()();
|
||||
|
||||
template<typename F>
|
||||
void set_wait_callback(F f);
|
||||
};
|
||||
|
||||
[section:task_constructor Task Constructor]
|
||||
|
||||
template<typename F>
|
||||
packaged_task(F const &f);
|
||||
|
||||
packaged_task(R(*f)());
|
||||
|
||||
template<typename F>
|
||||
packaged_task(F&&f);
|
||||
|
||||
[variablelist
|
||||
|
||||
[[Preconditions:] [`f()` is a valid expression with a return type convertible to `R`. Invoking a copy of `f` shall behave the same
|
||||
as invoking `f`.]]
|
||||
|
||||
[[Effects:] [Constructs a new __packaged_task__ with a copy of `f` stored as the associated task.]]
|
||||
|
||||
[[Throws:] [Any exceptions thrown by the copy (or move) constructor of `f`. `std::bad_alloc` if memory for the internal data
|
||||
structures could not be allocated.]]
|
||||
|
||||
]
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:move_constructor Move Constructor]
|
||||
|
||||
packaged_task(packaged_task && other);
|
||||
|
||||
[variablelist
|
||||
|
||||
[[Effects:] [Constructs a new __packaged_task__, and transfers ownership of the task associated with `other` to `*this`, leaving `other`
|
||||
with no associated task.]]
|
||||
|
||||
[[Throws:] [Nothing.]]
|
||||
|
||||
[[Notes:] [If the compiler does not support rvalue-references, this is implemented using the boost.thread move emulation.]]
|
||||
|
||||
]
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:move_assignment Move Assignment Operator]
|
||||
|
||||
packaged_task& operator=(packaged_task && other);
|
||||
|
||||
[variablelist
|
||||
|
||||
[[Effects:] [Transfers ownership of the task associated with `other` to `*this`, leaving `other` with no associated task. If there
|
||||
was already a task associated with `*this`, and that task has not been invoked, sets any futures associated with that task to
|
||||
['ready] with a __broken_promise__ exception as the result. ]]
|
||||
|
||||
[[Throws:] [Nothing.]]
|
||||
|
||||
[[Notes:] [If the compiler does not support rvalue-references, this is implemented using the boost.thread move emulation.]]
|
||||
|
||||
]
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:destructor Destructor]
|
||||
|
||||
~packaged_task();
|
||||
|
||||
[variablelist
|
||||
|
||||
[[Effects:] [Destroys `*this`. If there was a task associated with `*this`, and that task has not been invoked, sets any futures
|
||||
associated with that task to ['ready] with a __broken_promise__ exception as the result.]]
|
||||
|
||||
[[Throws:] [Nothing.]]
|
||||
|
||||
]
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:get_future Member Function `get_future()`]
|
||||
|
||||
unique_future<R> get_future();
|
||||
|
||||
[variablelist
|
||||
|
||||
[[Effects:] [Returns a __unique_future__ associated with the result of the task associated with `*this`. ]]
|
||||
|
||||
[[Throws:] [__task_moved__ if ownership of the task associated with `*this` has been moved to another instance of
|
||||
__packaged_task__. __future_already_retrieved__ if the future associated with the task has already been retrieved.]]
|
||||
|
||||
]
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:call_operator Member Function `operator()()`]
|
||||
|
||||
void operator()();
|
||||
|
||||
[variablelist
|
||||
|
||||
[[Effects:] [Invoke the task associated with `*this` and store the result in the corresponding future. If the task returns normally,
|
||||
the return value is stored as the asynchronous result, otherwise the exception thrown is stored. Any threads blocked waiting for the
|
||||
asynchronous result associated with this task are woken.]]
|
||||
|
||||
[[Postconditions:] [All futures waiting on the asynchronous result are ['ready]]]
|
||||
|
||||
[[Throws:] [__task_moved__ if ownership of the task associated with `*this` has been moved to another instance of
|
||||
__packaged_task__. __task_already_started__ if the task has already been invoked.]]
|
||||
|
||||
]
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:set_wait_callback Member Function `set_wait_callback()`]
|
||||
|
||||
template<typename F>
|
||||
void set_wait_callback(F f);
|
||||
|
||||
[variablelist
|
||||
|
||||
[[Preconditions:] [The expression `f(t)` where `t` is a lvalue of type __packaged_task__ shall be well-formed. Invoking a copy of
|
||||
`f` shall have the same effect as invoking `f`]]
|
||||
|
||||
[[Effects:] [Store a copy of `f` with the task associated with `*this` as a ['wait callback]. This will replace any existing wait
|
||||
callback store alongside that task. If a thread subsequently calls one of the wait functions on a __unique_future__ or
|
||||
__shared_future__ associated with this task, and the result of the task is not ['ready], `f(*this)` shall be invoked.]]
|
||||
|
||||
[[Throws:] [__task_moved__ if ownership of the task associated with `*this` has been moved to another instance of
|
||||
__packaged_task__.]]
|
||||
|
||||
]
|
||||
|
||||
[endsect]
|
||||
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:wait_for_any Non-member function `wait_for_any()`]
|
||||
|
||||
template<typename Iterator>
|
||||
Iterator wait_for_any(Iterator begin,Iterator end);
|
||||
|
||||
template<typename F1,typename F2>
|
||||
unsigned wait_for_any(F1& f1,F2& f2);
|
||||
|
||||
template<typename F1,typename F2,typename F3>
|
||||
unsigned wait_for_any(F1& f1,F2& f2,F3& f3);
|
||||
|
||||
template<typename F1,typename F2,typename F3,typename F4>
|
||||
unsigned wait_for_any(F1& f1,F2& f2,F3& f3,F4& f4);
|
||||
|
||||
template<typename F1,typename F2,typename F3,typename F4,typename F5>
|
||||
unsigned wait_for_any(F1& f1,F2& f2,F3& f3,F4& f4,F5& f5);
|
||||
|
||||
[variablelist
|
||||
|
||||
[[Preconditions:] [The types `Fn` shall be specializations of
|
||||
__unique_future__ or __shared_future__, and `Iterator` shall be a
|
||||
forward iterator with a `value_type` which is a specialization of
|
||||
__unique_future__ or __shared_future__.]]
|
||||
|
||||
[[Effects:] [Waits until at least one of the specified futures is ['ready].]]
|
||||
|
||||
[[Returns:] [The range-based overload returns an `Iterator` identifying the first future in the range that was detected as
|
||||
['ready]. The remaining overloads return the zero-based index of the first future that was detected as ['ready] (first parameter =>
|
||||
0, second parameter => 1, etc.).]]
|
||||
|
||||
[[Throws:] [__thread_interrupted__ if the current thread is interrupted. Any exception thrown by the ['wait callback] associated
|
||||
with any of the futures being waited for. `std::bad_alloc` if memory could not be allocated for the internal wait structures.]]
|
||||
|
||||
[[Notes:] [`wait_for_any()` is an ['interruption point].]]
|
||||
|
||||
]
|
||||
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:wait_for_all Non-member function `wait_for_all()`]
|
||||
|
||||
template<typename Iterator>
|
||||
void wait_for_all(Iterator begin,Iterator end);
|
||||
|
||||
template<typename F1,typename F2>
|
||||
void wait_for_all(F1& f1,F2& f2);
|
||||
|
||||
template<typename F1,typename F2,typename F3>
|
||||
void wait_for_all(F1& f1,F2& f2,F3& f3);
|
||||
|
||||
template<typename F1,typename F2,typename F3,typename F4>
|
||||
void wait_for_all(F1& f1,F2& f2,F3& f3,F4& f4);
|
||||
|
||||
template<typename F1,typename F2,typename F3,typename F4,typename F5>
|
||||
void wait_for_all(F1& f1,F2& f2,F3& f3,F4& f4,F5& f5);
|
||||
|
||||
[variablelist
|
||||
|
||||
[[Preconditions:] [The types `Fn` shall be specializations of
|
||||
__unique_future__ or __shared_future__, and `Iterator` shall be a
|
||||
forward iterator with a `value_type` which is a specialization of
|
||||
__unique_future__ or __shared_future__.]]
|
||||
|
||||
[[Effects:] [Waits until all of the specified futures are ['ready].]]
|
||||
|
||||
[[Throws:] [Any exceptions thrown by a call to `wait()` on the specified futures.]]
|
||||
|
||||
[[Notes:] [`wait_for_all()` is an ['interruption point].]]
|
||||
|
||||
]
|
||||
|
||||
|
||||
[endsect]
|
||||
|
||||
|
||||
[endsect]
|
||||
187
doc/futures.qbk
187
doc/futures.qbk
@@ -1,187 +0,0 @@
|
||||
[/
|
||||
(C) Copyright 2008-9 Anthony Williams.
|
||||
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:futures Futures]
|
||||
|
||||
[template future_state_link[link_text] [link thread.synchronization.futures.reference.future_state [link_text]]]
|
||||
[def __uninitialized__ [future_state_link `boost::future_state::uninitialized`]]
|
||||
[def __ready__ [future_state_link `boost::future_state::ready`]]
|
||||
[def __waiting__ [future_state_link `boost::future_state::waiting`]]
|
||||
|
||||
[def __future_uninitialized__ `boost::future_uninitialized`]
|
||||
[def __broken_promise__ `boost::broken_promise`]
|
||||
[def __future_already_retrieved__ `boost::future_already_retrieved`]
|
||||
[def __task_moved__ `boost::task_moved`]
|
||||
[def __task_already_started__ `boost::task_already_started`]
|
||||
[def __promise_already_satisfied__ `boost::promise_already_satisfied`]
|
||||
|
||||
[def __thread_interrupted__ `boost::thread_interrupted`]
|
||||
|
||||
|
||||
[template unique_future_link[link_text] [link thread.synchronization.futures.reference.unique_future [link_text]]]
|
||||
[def __unique_future__ [unique_future_link `boost::unique_future`]]
|
||||
|
||||
[template unique_future_get_link[link_text] [link thread.synchronization.futures.reference.unique_future.get [link_text]]]
|
||||
[def __unique_future_get__ [unique_future_get_link `boost::unique_future<R>::get()`]]
|
||||
|
||||
[template unique_future_wait_link[link_text] [link thread.synchronization.futures.reference.unique_future.wait [link_text]]]
|
||||
[def __unique_future_wait__ [unique_future_wait_link `boost::unique_future<R>::wait()`]]
|
||||
|
||||
[template unique_future_is_ready_link[link_text] [link thread.synchronization.futures.reference.unique_future.is_ready [link_text]]]
|
||||
[def __unique_future_is_ready__ [unique_future_is_ready_link `boost::unique_future<R>::is_ready()`]]
|
||||
|
||||
[template unique_future_has_value_link[link_text] [link thread.synchronization.futures.reference.unique_future.has_value [link_text]]]
|
||||
[def __unique_future_has_value__ [unique_future_has_value_link `boost::unique_future<R>::has_value()`]]
|
||||
|
||||
[template unique_future_has_exception_link[link_text] [link thread.synchronization.futures.reference.unique_future.has_exception [link_text]]]
|
||||
[def __unique_future_has_exception__ [unique_future_has_exception_link `boost::unique_future<R>::has_exception()`]]
|
||||
|
||||
[template unique_future_get_state_link[link_text] [link thread.synchronization.futures.reference.unique_future.get_state [link_text]]]
|
||||
[def __unique_future_get_state__ [unique_future_get_state_link `boost::unique_future<R>::get_state()`]]
|
||||
|
||||
[template shared_future_link[link_text] [link thread.synchronization.futures.reference.shared_future [link_text]]]
|
||||
[def __shared_future__ [shared_future_link `boost::shared_future`]]
|
||||
|
||||
[template shared_future_get_link[link_text] [link thread.synchronization.futures.reference.shared_future.get [link_text]]]
|
||||
[def __shared_future_get__ [shared_future_get_link `boost::shared_future<R>::get()`]]
|
||||
|
||||
[template shared_future_wait_link[link_text] [link thread.synchronization.futures.reference.shared_future.wait [link_text]]]
|
||||
[def __shared_future_wait__ [shared_future_wait_link `boost::shared_future<R>::wait()`]]
|
||||
|
||||
[template shared_future_is_ready_link[link_text] [link thread.synchronization.futures.reference.shared_future.is_ready [link_text]]]
|
||||
[def __shared_future_is_ready__ [shared_future_is_ready_link `boost::shared_future<R>::is_ready()`]]
|
||||
|
||||
[template shared_future_has_value_link[link_text] [link thread.synchronization.futures.reference.shared_future.has_value [link_text]]]
|
||||
[def __shared_future_has_value__ [shared_future_has_value_link `boost::shared_future<R>::has_value()`]]
|
||||
|
||||
[template shared_future_has_exception_link[link_text] [link thread.synchronization.futures.reference.shared_future.has_exception [link_text]]]
|
||||
[def __shared_future_has_exception__ [shared_future_has_exception_link `boost::shared_future<R>::has_exception()`]]
|
||||
|
||||
[template shared_future_get_state_link[link_text] [link thread.synchronization.futures.reference.shared_future.get_state [link_text]]]
|
||||
[def __shared_future_get_state__ [shared_future_get_state_link `boost::shared_future<R>::get_state()`]]
|
||||
|
||||
[template promise_link[link_text] [link thread.synchronization.futures.reference.promise [link_text]]]
|
||||
[def __promise__ [promise_link `boost::promise`]]
|
||||
|
||||
[template packaged_task_link[link_text] [link thread.synchronization.futures.reference.packaged_task [link_text]]]
|
||||
[def __packaged_task__ [packaged_task_link `boost::packaged_task`]]
|
||||
|
||||
[template wait_for_any_link[link_text] [link thread.synchronization.futures.reference.wait_for_any [link_text]]]
|
||||
[def __wait_for_any__ [wait_for_any_link `boost::wait_for_any()`]]
|
||||
|
||||
[template wait_for_all_link[link_text] [link thread.synchronization.futures.reference.wait_for_all [link_text]]]
|
||||
[def __wait_for_all__ [wait_for_all_link `boost::wait_for_all()`]]
|
||||
|
||||
|
||||
[section:overview Overview]
|
||||
|
||||
The futures library provides a means of handling synchronous future values, whether those values are generated by another thread, or
|
||||
on a single thread in response to external stimuli, or on-demand.
|
||||
|
||||
This is done through the provision of four class templates: __unique_future__ and __shared_future__ which are used to retrieve the
|
||||
asynchronous results, and __promise__ and __packaged_task__ which are used to generate the asynchronous results.
|
||||
|
||||
An instance of __unique_future__ holds the one and only reference to a result. Ownership can be transferred between instances using
|
||||
the move constructor or move-assignment operator, but at most one instance holds a reference to a given asynchronous result. When
|
||||
the result is ready, it is returned from __unique_future_get__ by rvalue-reference to allow the result to be moved or copied as
|
||||
appropriate for the type.
|
||||
|
||||
On the other hand, many instances of __shared_future__ may reference the same result. Instances can be freely copied and assigned,
|
||||
and __shared_future_get__ returns a `const` reference so that multiple calls to __shared_future_get__ are safe. You can move an
|
||||
instance of __unique_future__ into an instance of __shared_future__, thus transferring ownership of the associated asynchronous
|
||||
result, but not vice-versa.
|
||||
|
||||
You can wait for futures either individually or with one of the __wait_for_any__ and __wait_for_all__ functions.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:creating Creating asynchronous values]
|
||||
|
||||
You can set the value in a future with either a __promise__ or a __packaged_task__. A __packaged_task__ is a callable object that
|
||||
wraps a function or callable object. When the packaged task is invoked, it invokes the contained function in turn, and populates a
|
||||
future with the return value. This is an answer to the perennial question: "how do I return a value from a thread?": package the
|
||||
function you wish to run as a __packaged_task__ and pass the packaged task to the thread constructor. The future retrieved from the
|
||||
packaged task can then be used to obtain the return value. If the function throws an exception, that is stored in the future in
|
||||
place of the return value.
|
||||
|
||||
int calculate_the_answer_to_life_the_universe_and_everything()
|
||||
{
|
||||
return 42;
|
||||
}
|
||||
|
||||
boost::packaged_task<int> pt(calculate_the_answer_to_life_the_universe_and_everything);
|
||||
boost::unique_future<int> fi=pt.get_future();
|
||||
|
||||
boost::thread task(boost::move(pt)); // launch task on a thread
|
||||
|
||||
fi.wait(); // wait for it to finish
|
||||
|
||||
assert(fi.is_ready());
|
||||
assert(fi.has_value());
|
||||
assert(!fi.has_exception());
|
||||
assert(fi.get_state()==boost::future_state::ready);
|
||||
assert(fi.get()==42);
|
||||
|
||||
|
||||
A __promise__ is a bit more low level: it just provides explicit functions to store a value or an exception in the associated
|
||||
future. A promise can therefore be used where the value may come from more than one possible source, or where a single operation may
|
||||
produce multiple values.
|
||||
|
||||
boost::promise<int> pi;
|
||||
boost::unique_future<int> fi;
|
||||
fi=pi.get_future();
|
||||
|
||||
pi.set_value(42);
|
||||
|
||||
assert(fi.is_ready());
|
||||
assert(fi.has_value());
|
||||
assert(!fi.has_exception());
|
||||
assert(fi.get_state()==boost::future_state::ready);
|
||||
assert(fi.get()==42);
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:lazy_futures Wait Callbacks and Lazy Futures]
|
||||
|
||||
Both __promise__ and __packaged_task__ support ['wait callbacks] that are invoked when a thread blocks in a call to `wait()` or
|
||||
`timed_wait()` on a future that is waiting for the result from the __promise__ or __packaged_task__, in the thread that is doing the
|
||||
waiting. These can be set using the `set_wait_callback()` member function on the __promise__ or __packaged_task__ in question.
|
||||
|
||||
This allows ['lazy futures] where the result is not actually computed until it is needed by some thread. In the example below, the
|
||||
call to `f.get()` invokes the callback `invoke_lazy_task`, which runs the task to set the value. If you remove the call to
|
||||
`f.get()`, the task is not ever run.
|
||||
|
||||
int calculate_the_answer_to_life_the_universe_and_everything()
|
||||
{
|
||||
return 42;
|
||||
}
|
||||
|
||||
void invoke_lazy_task(boost::packaged_task<int>& task)
|
||||
{
|
||||
try
|
||||
{
|
||||
task();
|
||||
}
|
||||
catch(boost::task_already_started&)
|
||||
{}
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
boost::packaged_task<int> task(calculate_the_answer_to_life_the_universe_and_everything);
|
||||
task.set_wait_callback(invoke_lazy_task);
|
||||
boost::unique_future<int> f(task.get_future());
|
||||
|
||||
assert(f.get()==42);
|
||||
}
|
||||
|
||||
|
||||
[endsect]
|
||||
|
||||
[include future_ref.qbk]
|
||||
|
||||
[endsect]
|
||||
@@ -158,7 +158,6 @@
|
||||
[include condition_variables.qbk]
|
||||
[include once.qbk]
|
||||
[include barrier.qbk]
|
||||
[include futures.qbk]
|
||||
[endsect]
|
||||
|
||||
[include tss.qbk]
|
||||
|
||||
@@ -916,13 +916,6 @@ exits (even if the thread has been interrupted).]]
|
||||
[[Throws:] [`std::bad_alloc` if memory cannot be allocated for the copy of the function, __thread_resource_error__ if any other
|
||||
error occurs within the thread library. Any exception thrown whilst copying `func` into internal storage.]]
|
||||
|
||||
[[Note:] [This function is *not* called if the thread was terminated
|
||||
forcefully using platform-specific APIs, or if the thread is
|
||||
terminated due to a call to `exit()`, `abort()` or
|
||||
`std::terminate()`. In particular, returning from `main()` is
|
||||
equivalent to call to `exit()`, so will not call any functions
|
||||
registered with `at_thread_exit()`]]
|
||||
|
||||
]
|
||||
|
||||
[endsect]
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// Copyright (C) 2001-2003
|
||||
// William E. Kempf
|
||||
// (C) Copyright 2008-9 Anthony Williams
|
||||
// (C) Copyright 2008 Anthony Williams
|
||||
//
|
||||
// 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)
|
||||
@@ -21,6 +21,5 @@
|
||||
#include <boost/thread/locks.hpp>
|
||||
#include <boost/thread/shared_mutex.hpp>
|
||||
#include <boost/thread/barrier.hpp>
|
||||
#include <boost/thread/future.hpp>
|
||||
|
||||
#endif
|
||||
|
||||
@@ -357,6 +357,27 @@ namespace boost
|
||||
|
||||
namespace this_thread
|
||||
{
|
||||
class BOOST_THREAD_DECL disable_interruption
|
||||
{
|
||||
disable_interruption(const disable_interruption&);
|
||||
disable_interruption& operator=(const disable_interruption&);
|
||||
|
||||
bool interruption_was_enabled;
|
||||
friend class restore_interruption;
|
||||
public:
|
||||
disable_interruption();
|
||||
~disable_interruption();
|
||||
};
|
||||
|
||||
class BOOST_THREAD_DECL restore_interruption
|
||||
{
|
||||
restore_interruption(const restore_interruption&);
|
||||
restore_interruption& operator=(const restore_interruption&);
|
||||
public:
|
||||
explicit restore_interruption(disable_interruption& d);
|
||||
~restore_interruption();
|
||||
};
|
||||
|
||||
thread::id BOOST_THREAD_DECL get_id();
|
||||
|
||||
void BOOST_THREAD_DECL interruption_point();
|
||||
@@ -476,6 +497,83 @@ namespace boost
|
||||
detail::add_thread_exit_function(thread_exit_func);
|
||||
}
|
||||
}
|
||||
|
||||
class thread_group:
|
||||
private noncopyable
|
||||
{
|
||||
public:
|
||||
~thread_group()
|
||||
{
|
||||
for(std::list<thread*>::iterator it=threads.begin(),end=threads.end();
|
||||
it!=end;
|
||||
++it)
|
||||
{
|
||||
delete *it;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename F>
|
||||
thread* create_thread(F threadfunc)
|
||||
{
|
||||
boost::lock_guard<mutex> guard(m);
|
||||
std::auto_ptr<thread> new_thread(new thread(threadfunc));
|
||||
threads.push_back(new_thread.get());
|
||||
return new_thread.release();
|
||||
}
|
||||
|
||||
void add_thread(thread* thrd)
|
||||
{
|
||||
if(thrd)
|
||||
{
|
||||
boost::lock_guard<mutex> guard(m);
|
||||
threads.push_back(thrd);
|
||||
}
|
||||
}
|
||||
|
||||
void remove_thread(thread* thrd)
|
||||
{
|
||||
boost::lock_guard<mutex> guard(m);
|
||||
std::list<thread*>::iterator const it=std::find(threads.begin(),threads.end(),thrd);
|
||||
if(it!=threads.end())
|
||||
{
|
||||
threads.erase(it);
|
||||
}
|
||||
}
|
||||
|
||||
void join_all()
|
||||
{
|
||||
boost::lock_guard<mutex> guard(m);
|
||||
|
||||
for(std::list<thread*>::iterator it=threads.begin(),end=threads.end();
|
||||
it!=end;
|
||||
++it)
|
||||
{
|
||||
(*it)->join();
|
||||
}
|
||||
}
|
||||
|
||||
void interrupt_all()
|
||||
{
|
||||
boost::lock_guard<mutex> guard(m);
|
||||
|
||||
for(std::list<thread*>::iterator it=threads.begin(),end=threads.end();
|
||||
it!=end;
|
||||
++it)
|
||||
{
|
||||
(*it)->interrupt();
|
||||
}
|
||||
}
|
||||
|
||||
size_t size() const
|
||||
{
|
||||
boost::lock_guard<mutex> guard(m);
|
||||
return threads.size();
|
||||
}
|
||||
|
||||
private:
|
||||
std::list<thread*> threads;
|
||||
mutable mutex m;
|
||||
};
|
||||
}
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
|
||||
@@ -1,105 +0,0 @@
|
||||
#ifndef BOOST_THREAD_DETAIL_THREAD_GROUP_HPP
|
||||
#define BOOST_THREAD_DETAIL_THREAD_GROUP_HPP
|
||||
// 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)
|
||||
// (C) Copyright 2007-9 Anthony Williams
|
||||
|
||||
#include <list>
|
||||
#include <boost/thread/shared_mutex.hpp>
|
||||
#include <boost/thread/mutex.hpp>
|
||||
|
||||
#include <boost/config/abi_prefix.hpp>
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4251)
|
||||
#endif
|
||||
|
||||
namespace boost
|
||||
{
|
||||
class thread_group:
|
||||
private noncopyable
|
||||
{
|
||||
public:
|
||||
~thread_group()
|
||||
{
|
||||
for(std::list<thread*>::iterator it=threads.begin(),end=threads.end();
|
||||
it!=end;
|
||||
++it)
|
||||
{
|
||||
delete *it;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename F>
|
||||
thread* create_thread(F threadfunc)
|
||||
{
|
||||
boost::lock_guard<shared_mutex> guard(m);
|
||||
std::auto_ptr<thread> new_thread(new thread(threadfunc));
|
||||
threads.push_back(new_thread.get());
|
||||
return new_thread.release();
|
||||
}
|
||||
|
||||
void add_thread(thread* thrd)
|
||||
{
|
||||
if(thrd)
|
||||
{
|
||||
boost::lock_guard<shared_mutex> guard(m);
|
||||
threads.push_back(thrd);
|
||||
}
|
||||
}
|
||||
|
||||
void remove_thread(thread* thrd)
|
||||
{
|
||||
boost::lock_guard<shared_mutex> guard(m);
|
||||
std::list<thread*>::iterator const it=std::find(threads.begin(),threads.end(),thrd);
|
||||
if(it!=threads.end())
|
||||
{
|
||||
threads.erase(it);
|
||||
}
|
||||
}
|
||||
|
||||
void join_all()
|
||||
{
|
||||
boost::shared_lock<shared_mutex> guard(m);
|
||||
|
||||
for(std::list<thread*>::iterator it=threads.begin(),end=threads.end();
|
||||
it!=end;
|
||||
++it)
|
||||
{
|
||||
(*it)->join();
|
||||
}
|
||||
}
|
||||
|
||||
void interrupt_all()
|
||||
{
|
||||
boost::shared_lock<shared_mutex> guard(m);
|
||||
|
||||
for(std::list<thread*>::iterator it=threads.begin(),end=threads.end();
|
||||
it!=end;
|
||||
++it)
|
||||
{
|
||||
(*it)->interrupt();
|
||||
}
|
||||
}
|
||||
|
||||
size_t size() const
|
||||
{
|
||||
boost::shared_lock<shared_mutex> guard(m);
|
||||
return threads.size();
|
||||
}
|
||||
|
||||
private:
|
||||
std::list<thread*> threads;
|
||||
mutable shared_mutex m;
|
||||
};
|
||||
}
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#include <boost/config/abi_suffix.hpp>
|
||||
|
||||
#endif
|
||||
@@ -1,35 +0,0 @@
|
||||
#ifndef BOOST_THREAD_DETAIL_THREAD_INTERRUPTION_HPP
|
||||
#define BOOST_THREAD_DETAIL_THREAD_INTERRUPTION_HPP
|
||||
// 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)
|
||||
// (C) Copyright 2007-9 Anthony Williams
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace this_thread
|
||||
{
|
||||
class BOOST_THREAD_DECL disable_interruption
|
||||
{
|
||||
disable_interruption(const disable_interruption&);
|
||||
disable_interruption& operator=(const disable_interruption&);
|
||||
|
||||
bool interruption_was_enabled;
|
||||
friend class restore_interruption;
|
||||
public:
|
||||
disable_interruption();
|
||||
~disable_interruption();
|
||||
};
|
||||
|
||||
class BOOST_THREAD_DECL restore_interruption
|
||||
{
|
||||
restore_interruption(const restore_interruption&);
|
||||
restore_interruption& operator=(const restore_interruption&);
|
||||
public:
|
||||
explicit restore_interruption(disable_interruption& d);
|
||||
~restore_interruption();
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,6 +1,6 @@
|
||||
// Copyright (C) 2001-2003
|
||||
// William E. Kempf
|
||||
// Copyright (C) 2007-9 Anthony Williams
|
||||
// Copyright (C) 2007-8 Anthony Williams
|
||||
//
|
||||
// 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)
|
||||
@@ -24,36 +24,23 @@
|
||||
namespace boost
|
||||
{
|
||||
|
||||
class thread_interrupted
|
||||
class BOOST_THREAD_DECL thread_interrupted
|
||||
{};
|
||||
|
||||
class thread_exception:
|
||||
public std::exception
|
||||
{
|
||||
protected:
|
||||
thread_exception():
|
||||
m_sys_err(0)
|
||||
{}
|
||||
|
||||
thread_exception(int sys_err_code):
|
||||
m_sys_err(sys_err_code)
|
||||
{}
|
||||
|
||||
class BOOST_THREAD_DECL thread_exception : public std::exception
|
||||
{
|
||||
protected:
|
||||
thread_exception();
|
||||
thread_exception(int sys_err_code);
|
||||
|
||||
public:
|
||||
~thread_exception() throw()
|
||||
{}
|
||||
|
||||
public:
|
||||
~thread_exception() throw();
|
||||
|
||||
int native_error() const
|
||||
{
|
||||
return m_sys_err;
|
||||
}
|
||||
|
||||
int native_error() const;
|
||||
|
||||
private:
|
||||
int m_sys_err;
|
||||
};
|
||||
private:
|
||||
int m_sys_err;
|
||||
};
|
||||
|
||||
class condition_error:
|
||||
public std::exception
|
||||
@@ -66,117 +53,62 @@ namespace boost
|
||||
};
|
||||
|
||||
|
||||
class lock_error:
|
||||
public thread_exception
|
||||
{
|
||||
public:
|
||||
lock_error()
|
||||
{}
|
||||
|
||||
lock_error(int sys_err_code):
|
||||
thread_exception(sys_err_code)
|
||||
{}
|
||||
|
||||
~lock_error() throw()
|
||||
{}
|
||||
|
||||
class BOOST_THREAD_DECL lock_error : public thread_exception
|
||||
{
|
||||
public:
|
||||
lock_error();
|
||||
lock_error(int sys_err_code);
|
||||
~lock_error() throw();
|
||||
|
||||
virtual const char* what() const throw()
|
||||
{
|
||||
return "boost::lock_error";
|
||||
}
|
||||
};
|
||||
virtual const char* what() const throw();
|
||||
};
|
||||
|
||||
class thread_resource_error:
|
||||
public thread_exception
|
||||
{
|
||||
public:
|
||||
thread_resource_error()
|
||||
{}
|
||||
|
||||
thread_resource_error(int sys_err_code):
|
||||
thread_exception(sys_err_code)
|
||||
{}
|
||||
|
||||
~thread_resource_error() throw()
|
||||
{}
|
||||
|
||||
class BOOST_THREAD_DECL thread_resource_error : public thread_exception
|
||||
{
|
||||
public:
|
||||
thread_resource_error();
|
||||
thread_resource_error(int sys_err_code);
|
||||
~thread_resource_error() throw();
|
||||
|
||||
virtual const char* what() const throw()
|
||||
{
|
||||
return "boost::thread_resource_error";
|
||||
}
|
||||
|
||||
};
|
||||
virtual const char* what() const throw();
|
||||
};
|
||||
|
||||
class unsupported_thread_option:
|
||||
public thread_exception
|
||||
{
|
||||
public:
|
||||
unsupported_thread_option()
|
||||
{}
|
||||
|
||||
unsupported_thread_option(int sys_err_code):
|
||||
thread_exception(sys_err_code)
|
||||
{}
|
||||
|
||||
~unsupported_thread_option() throw()
|
||||
{}
|
||||
|
||||
class BOOST_THREAD_DECL unsupported_thread_option : public thread_exception
|
||||
{
|
||||
public:
|
||||
unsupported_thread_option();
|
||||
unsupported_thread_option(int sys_err_code);
|
||||
~unsupported_thread_option() throw();
|
||||
|
||||
virtual const char* what() const throw()
|
||||
{
|
||||
return "boost::unsupported_thread_option";
|
||||
}
|
||||
|
||||
};
|
||||
virtual const char* what() const throw();
|
||||
};
|
||||
|
||||
class invalid_thread_argument:
|
||||
public thread_exception
|
||||
{
|
||||
public:
|
||||
invalid_thread_argument()
|
||||
{}
|
||||
|
||||
invalid_thread_argument(int sys_err_code):
|
||||
thread_exception(sys_err_code)
|
||||
{}
|
||||
|
||||
~invalid_thread_argument() throw()
|
||||
{}
|
||||
|
||||
class BOOST_THREAD_DECL invalid_thread_argument : public thread_exception
|
||||
{
|
||||
public:
|
||||
invalid_thread_argument();
|
||||
invalid_thread_argument(int sys_err_code);
|
||||
~invalid_thread_argument() throw();
|
||||
|
||||
virtual const char* what() const throw()
|
||||
{
|
||||
return "boost::invalid_thread_argument";
|
||||
}
|
||||
|
||||
};
|
||||
virtual const char* what() const throw();
|
||||
};
|
||||
|
||||
class thread_permission_error:
|
||||
public thread_exception
|
||||
{
|
||||
public:
|
||||
thread_permission_error()
|
||||
{}
|
||||
|
||||
thread_permission_error(int sys_err_code):
|
||||
thread_exception(sys_err_code)
|
||||
{}
|
||||
|
||||
~thread_permission_error() throw()
|
||||
{}
|
||||
|
||||
class BOOST_THREAD_DECL thread_permission_error : public thread_exception
|
||||
{
|
||||
public:
|
||||
thread_permission_error();
|
||||
thread_permission_error(int sys_err_code);
|
||||
~thread_permission_error() throw();
|
||||
|
||||
virtual const char* what() const throw()
|
||||
{
|
||||
return "boost::thread_permission_error";
|
||||
}
|
||||
|
||||
};
|
||||
virtual const char* what() const throw();
|
||||
};
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/config/abi_suffix.hpp>
|
||||
|
||||
#endif
|
||||
#endif // BOOST_THREAD_CONFIG_PDM070801_H
|
||||
|
||||
// Change log:
|
||||
// 3 Jan 03 WEKEMPF Modified for DLL implementation.
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -263,16 +263,16 @@ namespace boost
|
||||
}
|
||||
|
||||
|
||||
unique_lock& operator=(unique_lock&& other)
|
||||
unique_lock& operator=(unique_lock<Mutex>&& other)
|
||||
{
|
||||
unique_lock temp(other.move());
|
||||
unique_lock temp(other);
|
||||
swap(temp);
|
||||
return *this;
|
||||
}
|
||||
|
||||
unique_lock& operator=(upgrade_lock<Mutex>&& other)
|
||||
{
|
||||
unique_lock temp(other.move());
|
||||
unique_lock temp(other);
|
||||
swap(temp);
|
||||
return *this;
|
||||
}
|
||||
@@ -783,7 +783,7 @@ namespace boost
|
||||
other.is_locked=false;
|
||||
if(is_locked)
|
||||
{
|
||||
m->unlock_upgrade_and_lock();
|
||||
m.unlock_upgrade_and_lock();
|
||||
}
|
||||
}
|
||||
#else
|
||||
@@ -875,28 +875,6 @@ namespace boost
|
||||
try_lock_wrapper(Mutex& m_,try_to_lock_t):
|
||||
base(m_,try_to_lock)
|
||||
{}
|
||||
#ifdef BOOST_HAS_RVALUE_REFS
|
||||
try_lock_wrapper(try_lock_wrapper&& other):
|
||||
base(other.move())
|
||||
{}
|
||||
|
||||
try_lock_wrapper&& move()
|
||||
{
|
||||
return static_cast<try_lock_wrapper&&>(*this);
|
||||
}
|
||||
|
||||
try_lock_wrapper& operator=(try_lock_wrapper<Mutex>&& other)
|
||||
{
|
||||
try_lock_wrapper temp(other.move());
|
||||
swap(temp);
|
||||
return *this;
|
||||
}
|
||||
|
||||
void swap(try_lock_wrapper&& other)
|
||||
{
|
||||
base::swap(other);
|
||||
}
|
||||
#else
|
||||
try_lock_wrapper(detail::thread_move_t<try_lock_wrapper<Mutex> > other):
|
||||
base(detail::thread_move_t<base>(*other))
|
||||
{}
|
||||
@@ -918,6 +896,12 @@ namespace boost
|
||||
return *this;
|
||||
}
|
||||
|
||||
#ifdef BOOST_HAS_RVALUE_REFS
|
||||
void swap(try_lock_wrapper&& other)
|
||||
{
|
||||
base::swap(other);
|
||||
}
|
||||
#else
|
||||
void swap(try_lock_wrapper& other)
|
||||
{
|
||||
base::swap(other);
|
||||
@@ -927,6 +911,7 @@ namespace boost
|
||||
base::swap(*other);
|
||||
}
|
||||
#endif
|
||||
|
||||
void lock()
|
||||
{
|
||||
base::lock();
|
||||
|
||||
@@ -10,8 +10,8 @@
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/thread/mutex.hpp>
|
||||
#include <boost/thread/thread.hpp>
|
||||
#include <boost/thread/condition_variable.hpp>
|
||||
#include <boost/thread/detail/thread_interruption.hpp>
|
||||
|
||||
#include <boost/config/abi_prefix.hpp>
|
||||
|
||||
|
||||
@@ -20,8 +20,6 @@
|
||||
#endif
|
||||
|
||||
#include <boost/thread/detail/thread.hpp>
|
||||
#include <boost/thread/detail/thread_interruption.hpp>
|
||||
#include <boost/thread/detail/thread_group.hpp>
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
1
module.cmake
Normal file
1
module.cmake
Normal file
@@ -0,0 +1 @@
|
||||
boost_module(thread DEPENDS date_time bind optional range)
|
||||
21
src/CMakeLists.txt
Normal file
21
src/CMakeLists.txt
Normal file
@@ -0,0 +1,21 @@
|
||||
#
|
||||
# Copyright Troy D. Straszheim
|
||||
#
|
||||
# Distributed under the Boost Software License, Version 1.0.
|
||||
# See http://www.boost.org/LICENSE_1_0.txt
|
||||
#
|
||||
if (WIN32)
|
||||
set(THREAD_SOURCES win32/thread.cpp win32/exceptions.cpp win32/tss_dll.cpp
|
||||
win32/tss_pe.cpp)
|
||||
else (WIN32)
|
||||
set(THREAD_SOURCES pthread/thread.cpp pthread/exceptions.cpp pthread/once.cpp)
|
||||
endif (WIN32)
|
||||
|
||||
boost_add_library(
|
||||
boost_thread
|
||||
${THREAD_SOURCES}
|
||||
SHARED_COMPILE_FLAGS "-DBOOST_THREAD_BUILD_DLL=1"
|
||||
STATIC_COMPILE_FLAGS "-DBOOST_THREAD_BUILD_LIB=1"
|
||||
NO_SINGLE_THREADED
|
||||
)
|
||||
|
||||
124
src/pthread/exceptions.cpp
Normal file
124
src/pthread/exceptions.cpp
Normal file
@@ -0,0 +1,124 @@
|
||||
// Copyright (C) 2001-2003
|
||||
// William E. Kempf
|
||||
//
|
||||
// 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)
|
||||
|
||||
#include <boost/thread/detail/config.hpp>
|
||||
|
||||
#include <boost/thread/exceptions.hpp>
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
|
||||
namespace boost {
|
||||
|
||||
thread_exception::thread_exception()
|
||||
: m_sys_err(0)
|
||||
{
|
||||
}
|
||||
|
||||
thread_exception::thread_exception(int sys_err_code)
|
||||
: m_sys_err(sys_err_code)
|
||||
{
|
||||
}
|
||||
|
||||
thread_exception::~thread_exception() throw()
|
||||
{
|
||||
}
|
||||
|
||||
int thread_exception::native_error() const
|
||||
{
|
||||
return m_sys_err;
|
||||
}
|
||||
|
||||
lock_error::lock_error()
|
||||
{
|
||||
}
|
||||
|
||||
lock_error::lock_error(int sys_err_code)
|
||||
: thread_exception(sys_err_code)
|
||||
{
|
||||
}
|
||||
|
||||
lock_error::~lock_error() throw()
|
||||
{
|
||||
}
|
||||
|
||||
const char* lock_error::what() const throw()
|
||||
{
|
||||
return "boost::lock_error";
|
||||
}
|
||||
|
||||
thread_resource_error::thread_resource_error()
|
||||
{
|
||||
}
|
||||
|
||||
thread_resource_error::thread_resource_error(int sys_err_code)
|
||||
: thread_exception(sys_err_code)
|
||||
{
|
||||
}
|
||||
|
||||
thread_resource_error::~thread_resource_error() throw()
|
||||
{
|
||||
}
|
||||
|
||||
const char* thread_resource_error::what() const throw()
|
||||
{
|
||||
return "boost::thread_resource_error";
|
||||
}
|
||||
|
||||
unsupported_thread_option::unsupported_thread_option()
|
||||
{
|
||||
}
|
||||
|
||||
unsupported_thread_option::unsupported_thread_option(int sys_err_code)
|
||||
: thread_exception(sys_err_code)
|
||||
{
|
||||
}
|
||||
|
||||
unsupported_thread_option::~unsupported_thread_option() throw()
|
||||
{
|
||||
}
|
||||
|
||||
const char* unsupported_thread_option::what() const throw()
|
||||
{
|
||||
return "boost::unsupported_thread_option";
|
||||
}
|
||||
|
||||
invalid_thread_argument::invalid_thread_argument()
|
||||
{
|
||||
}
|
||||
|
||||
invalid_thread_argument::invalid_thread_argument(int sys_err_code)
|
||||
: thread_exception(sys_err_code)
|
||||
{
|
||||
}
|
||||
|
||||
invalid_thread_argument::~invalid_thread_argument() throw()
|
||||
{
|
||||
}
|
||||
|
||||
const char* invalid_thread_argument::what() const throw()
|
||||
{
|
||||
return "boost::invalid_thread_argument";
|
||||
}
|
||||
|
||||
thread_permission_error::thread_permission_error()
|
||||
{
|
||||
}
|
||||
|
||||
thread_permission_error::thread_permission_error(int sys_err_code)
|
||||
: thread_exception(sys_err_code)
|
||||
{
|
||||
}
|
||||
|
||||
thread_permission_error::~thread_permission_error() throw()
|
||||
{
|
||||
}
|
||||
|
||||
const char* thread_permission_error::what() const throw()
|
||||
{
|
||||
return "boost::thread_permission_error";
|
||||
}
|
||||
|
||||
} // namespace boost
|
||||
124
src/win32/exceptions.cpp
Normal file
124
src/win32/exceptions.cpp
Normal file
@@ -0,0 +1,124 @@
|
||||
// Copyright (C) 2001-2003
|
||||
// William E. Kempf
|
||||
//
|
||||
// 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)
|
||||
|
||||
#include <boost/thread/detail/config.hpp>
|
||||
|
||||
#include <boost/thread/exceptions.hpp>
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
|
||||
namespace boost {
|
||||
|
||||
thread_exception::thread_exception()
|
||||
: m_sys_err(0)
|
||||
{
|
||||
}
|
||||
|
||||
thread_exception::thread_exception(int sys_err_code)
|
||||
: m_sys_err(sys_err_code)
|
||||
{
|
||||
}
|
||||
|
||||
thread_exception::~thread_exception() throw()
|
||||
{
|
||||
}
|
||||
|
||||
int thread_exception::native_error() const
|
||||
{
|
||||
return m_sys_err;
|
||||
}
|
||||
|
||||
lock_error::lock_error()
|
||||
{
|
||||
}
|
||||
|
||||
lock_error::lock_error(int sys_err_code)
|
||||
: thread_exception(sys_err_code)
|
||||
{
|
||||
}
|
||||
|
||||
lock_error::~lock_error() throw()
|
||||
{
|
||||
}
|
||||
|
||||
const char* lock_error::what() const throw()
|
||||
{
|
||||
return "boost::lock_error";
|
||||
}
|
||||
|
||||
thread_resource_error::thread_resource_error()
|
||||
{
|
||||
}
|
||||
|
||||
thread_resource_error::thread_resource_error(int sys_err_code)
|
||||
: thread_exception(sys_err_code)
|
||||
{
|
||||
}
|
||||
|
||||
thread_resource_error::~thread_resource_error() throw()
|
||||
{
|
||||
}
|
||||
|
||||
const char* thread_resource_error::what() const throw()
|
||||
{
|
||||
return "boost::thread_resource_error";
|
||||
}
|
||||
|
||||
unsupported_thread_option::unsupported_thread_option()
|
||||
{
|
||||
}
|
||||
|
||||
unsupported_thread_option::unsupported_thread_option(int sys_err_code)
|
||||
: thread_exception(sys_err_code)
|
||||
{
|
||||
}
|
||||
|
||||
unsupported_thread_option::~unsupported_thread_option() throw()
|
||||
{
|
||||
}
|
||||
|
||||
const char* unsupported_thread_option::what() const throw()
|
||||
{
|
||||
return "boost::unsupported_thread_option";
|
||||
}
|
||||
|
||||
invalid_thread_argument::invalid_thread_argument()
|
||||
{
|
||||
}
|
||||
|
||||
invalid_thread_argument::invalid_thread_argument(int sys_err_code)
|
||||
: thread_exception(sys_err_code)
|
||||
{
|
||||
}
|
||||
|
||||
invalid_thread_argument::~invalid_thread_argument() throw()
|
||||
{
|
||||
}
|
||||
|
||||
const char* invalid_thread_argument::what() const throw()
|
||||
{
|
||||
return "boost::invalid_thread_argument";
|
||||
}
|
||||
|
||||
thread_permission_error::thread_permission_error()
|
||||
{
|
||||
}
|
||||
|
||||
thread_permission_error::thread_permission_error(int sys_err_code)
|
||||
: thread_exception(sys_err_code)
|
||||
{
|
||||
}
|
||||
|
||||
thread_permission_error::~thread_permission_error() throw()
|
||||
{
|
||||
}
|
||||
|
||||
const char* thread_permission_error::what() const throw()
|
||||
{
|
||||
return "boost::thread_permission_error";
|
||||
}
|
||||
|
||||
} // namespace boost
|
||||
39
test/CMakeLists.txt
Normal file
39
test/CMakeLists.txt
Normal file
@@ -0,0 +1,39 @@
|
||||
#
|
||||
# Copyright Troy D. Straszheim
|
||||
#
|
||||
# Distributed under the Boost Software License, Version 1.0.
|
||||
# See http://www.boost.org/LICENSE_1_0.txt
|
||||
#
|
||||
boost_additional_test_dependencies(thread BOOST_DEPENDS test )
|
||||
|
||||
|
||||
|
||||
set(TESTS
|
||||
test_thread
|
||||
test_thread_id
|
||||
test_hardware_concurrency
|
||||
test_thread_move
|
||||
test_thread_launching
|
||||
test_thread_mf
|
||||
test_move_function
|
||||
test_mutex
|
||||
test_condition_notify_one
|
||||
test_condition_timed_wait_times_out
|
||||
test_condition_notify_all
|
||||
test_condition
|
||||
test_tss
|
||||
test_once
|
||||
test_xtime
|
||||
test_barrier
|
||||
test_shared_mutex
|
||||
test_shared_mutex_part_2
|
||||
test_shared_mutex_timed_locks
|
||||
test_lock_concept
|
||||
test_generic_locks)
|
||||
|
||||
foreach (TEST ${TESTS})
|
||||
boost_test_run(${TEST} MULTI_THREADED DEPENDS boost_thread boost_unit_test_framework)
|
||||
endforeach (TEST ${TESTS})
|
||||
|
||||
boost_test_compile_fail(no_implicit_move_from_lvalue_thread)
|
||||
boost_test_compile_fail(no_implicit_assign_from_lvalue_thread)
|
||||
@@ -57,7 +57,6 @@ rule thread-run ( sources )
|
||||
[ thread-run test_shared_mutex_timed_locks.cpp ]
|
||||
[ thread-run test_lock_concept.cpp ]
|
||||
[ thread-run test_generic_locks.cpp ]
|
||||
[ thread-run test_futures.cpp ]
|
||||
[ compile-fail no_implicit_move_from_lvalue_thread.cpp ]
|
||||
[ compile-fail no_implicit_assign_from_lvalue_thread.cpp ]
|
||||
;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user