mirror of
https://github.com/boostorg/thread.git
synced 2026-02-09 11:32:12 +00:00
Compare commits
130 Commits
boost-1.40
...
svn-branch
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9e6b3df2c1 | ||
|
|
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 |
@@ -1,28 +0,0 @@
|
||||
#
|
||||
# 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
|
||||
)
|
||||
|
||||
|
||||
@@ -31,6 +31,25 @@ boostbook standalone
|
||||
# Use the main Boost stylesheet:
|
||||
<xsl:param>html.stylesheet=../../../../doc/html/boostbook.css
|
||||
|
||||
# PDF Options:
|
||||
# TOC Generation: this is needed for FOP-0.9 and later:
|
||||
#<xsl:param>fop1.extensions=1
|
||||
# Or enable this if you're using XEP:
|
||||
<xsl:param>xep.extensions=1
|
||||
# TOC generation: this is needed for FOP 0.2, but must not be set to zero for FOP-0.9!
|
||||
<xsl:param>fop.extensions=0
|
||||
# No indent on body text:
|
||||
<xsl:param>body.start.indent=0pt
|
||||
# Margin size:
|
||||
<xsl:param>page.margin.inner=0.5in
|
||||
# Margin size:
|
||||
<xsl:param>page.margin.outer=0.5in
|
||||
# Yes, we want graphics for admonishments:
|
||||
<xsl:param>admon.graphics=1
|
||||
# Set this one for PDF generation *only*:
|
||||
# default pnd graphics are awful in PDF form,
|
||||
# better use SVG's instead:
|
||||
<format>pdf:<xsl:param>admon.graphics.extension=".svg"
|
||||
<format>pdf:<xsl:param>admon.graphics.path=$(boost-images)/
|
||||
;
|
||||
|
||||
|
||||
|
||||
@@ -5,23 +5,7 @@
|
||||
http://www.boost.org/LICENSE_1_0.txt).
|
||||
]
|
||||
|
||||
[section:changes Changes since boost 1.35]
|
||||
|
||||
The 1.36.0 release of Boost includes a few new features in the thread library:
|
||||
|
||||
* New generic __lock_multiple_ref__ and __try_lock_multiple_ref__ functions for locking multiple mutexes at once.
|
||||
|
||||
* Rvalue reference support for move semantics where the compilers supports it.
|
||||
|
||||
* A few bugs fixed and missing functions added (including the serious win32 condition variable bug).
|
||||
|
||||
* `scoped_try_lock` types are now backwards-compatible with Boost 1.34.0 and previous releases.
|
||||
|
||||
* Support for passing function arguments to the thread function by supplying additional arguments to the __thread__ constructor.
|
||||
|
||||
* Backwards-compatibility overloads added for `timed_lock` and `timed_wait` functions to allow use of `xtime` for timeouts.
|
||||
|
||||
[heading Changes since boost 1.34]
|
||||
[section:changes Changes since boost 1.34]
|
||||
|
||||
Almost every line of code in __boost_thread__ has been changed since the 1.34 release of boost. However, most of the interface
|
||||
changes have been extensions, so the new code is largely backwards-compatible with the old code. The new features and breaking
|
||||
@@ -77,7 +61,4 @@ been moved to __thread_id__.
|
||||
|
||||
* __mutex__ is now never recursive. For Boost releases prior to 1.35 __mutex__ was recursive on Windows and not on POSIX platforms.
|
||||
|
||||
* When using a __recursive_mutex__ with a call to [cond_any_wait_link `boost::condition_variable_any::wait()`], the mutex is only
|
||||
unlocked one level, and not completely. This prior behaviour was not guaranteed and did not feature in the tests.
|
||||
|
||||
[endsect]
|
||||
|
||||
@@ -74,8 +74,6 @@ optimizations in some cases, based on the knowledge of the mutex type;
|
||||
|
||||
[section:condition_variable Class `condition_variable`]
|
||||
|
||||
#include <boost/thread/condition_variable.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
class condition_variable
|
||||
@@ -296,8 +294,6 @@ return true;
|
||||
|
||||
[section:condition_variable_any Class `condition_variable_any`]
|
||||
|
||||
#include <boost/thread/condition_variable.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
class condition_variable_any
|
||||
@@ -502,8 +498,6 @@ return true;
|
||||
|
||||
[section:condition Typedef `condition`]
|
||||
|
||||
#include <boost/thread/condition.hpp>
|
||||
|
||||
typedef condition_variable_any condition;
|
||||
|
||||
The typedef `condition` is provided for backwards compatibility with previous boost releases.
|
||||
|
||||
@@ -312,8 +312,6 @@ without blocking.]]
|
||||
|
||||
[section:lock_guard Class template `lock_guard`]
|
||||
|
||||
#include <boost/thread/locks.hpp>
|
||||
|
||||
template<typename Lockable>
|
||||
class lock_guard
|
||||
{
|
||||
@@ -378,8 +376,6 @@ object passed to the constructor.]]
|
||||
|
||||
[section:unique_lock Class template `unique_lock`]
|
||||
|
||||
#include <boost/thread/locks.hpp>
|
||||
|
||||
template<typename Lockable>
|
||||
class unique_lock
|
||||
{
|
||||
@@ -621,8 +617,6 @@ __owns_lock_ref__ returns `false`.]]
|
||||
|
||||
[section:shared_lock Class template `shared_lock`]
|
||||
|
||||
#include <boost/thread/locks.hpp>
|
||||
|
||||
template<typename Lockable>
|
||||
class shared_lock
|
||||
{
|
||||
@@ -856,8 +850,6 @@ __owns_lock_shared_ref__ returns `false`.]]
|
||||
|
||||
[section:upgrade_lock Class template `upgrade_lock`]
|
||||
|
||||
#include <boost/thread/locks.hpp>
|
||||
|
||||
template<typename Lockable>
|
||||
class upgrade_lock
|
||||
{
|
||||
@@ -905,8 +897,6 @@ state (including the destructor) must be called by the same thread that acquired
|
||||
|
||||
[section:upgrade_to_unique_lock Class template `upgrade_to_unique_lock`]
|
||||
|
||||
#include <boost/thread/locks.hpp>
|
||||
|
||||
template <class Lockable>
|
||||
class upgrade_to_unique_lock
|
||||
{
|
||||
@@ -931,189 +921,4 @@ __lockable_concept_type__ is downgraded back to ['upgrade ownership].
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:scoped_try_lock Mutex-specific class `scoped_try_lock`]
|
||||
|
||||
class MutexType::scoped_try_lock
|
||||
{
|
||||
private:
|
||||
MutexType::scoped_try_lock(MutexType::scoped_try_lock<MutexType>& other);
|
||||
MutexType::scoped_try_lock& operator=(MutexType::scoped_try_lock<MutexType>& other);
|
||||
public:
|
||||
MutexType::scoped_try_lock();
|
||||
explicit MutexType::scoped_try_lock(MutexType& m);
|
||||
MutexType::scoped_try_lock(MutexType& m_,adopt_lock_t);
|
||||
MutexType::scoped_try_lock(MutexType& m_,defer_lock_t);
|
||||
MutexType::scoped_try_lock(MutexType& m_,try_to_lock_t);
|
||||
|
||||
MutexType::scoped_try_lock(MutexType::scoped_try_lock<MutexType>&& other);
|
||||
MutexType::scoped_try_lock& operator=(MutexType::scoped_try_lock<MutexType>&& other);
|
||||
|
||||
void swap(MutexType::scoped_try_lock&& other);
|
||||
|
||||
void lock();
|
||||
bool try_lock();
|
||||
void unlock();
|
||||
bool owns_lock() const;
|
||||
|
||||
MutexType* mutex() const;
|
||||
MutexType* release();
|
||||
bool operator!() const;
|
||||
|
||||
typedef ``['unspecified-bool-type]`` bool_type;
|
||||
operator bool_type() const;
|
||||
};
|
||||
|
||||
The member typedef `scoped_try_lock` is provided for each distinct
|
||||
`MutexType` as a typedef to a class with the preceding definition. The
|
||||
semantics of each constructor and member function are identical to
|
||||
those of [unique_lock_link `boost::unique_lock<MutexType>`] for the same `MutexType`, except
|
||||
that the constructor that takes a single reference to a mutex will
|
||||
call [try_lock_ref_link `m.try_lock()`] rather than `m.lock()`.
|
||||
|
||||
|
||||
[endsect]
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:lock_functions Lock functions]
|
||||
|
||||
[section:lock_multiple Non-member function `lock(Lockable1,Lockable2,...)`]
|
||||
|
||||
template<typename Lockable1,typename Lockable2>
|
||||
void lock(Lockable1& l1,Lockable2& l2);
|
||||
|
||||
template<typename Lockable1,typename Lockable2,typename Lockable3>
|
||||
void lock(Lockable1& l1,Lockable2& l2,Lockable3& l3);
|
||||
|
||||
template<typename Lockable1,typename Lockable2,typename Lockable3,typename Lockable4>
|
||||
void lock(Lockable1& l1,Lockable2& l2,Lockable3& l3,Lockable4& l4);
|
||||
|
||||
template<typename Lockable1,typename Lockable2,typename Lockable3,typename Lockable4,typename Lockable5>
|
||||
void lock(Lockable1& l1,Lockable2& l2,Lockable3& l3,Lockable4& l4,Lockable5& l5);
|
||||
|
||||
[variablelist
|
||||
|
||||
[[Effects:] [Locks the __lockable_concept_type__ objects supplied as
|
||||
arguments in an unspecified and indeterminate order in a way that
|
||||
avoids deadlock. It is safe to call this function concurrently from
|
||||
multiple threads with the same mutexes (or other lockable objects) in
|
||||
different orders without risk of deadlock. If any of the __lock_ref__
|
||||
or __try_lock_ref__ operations on the supplied
|
||||
__lockable_concept_type__ objects throws an exception any locks
|
||||
acquired by the function will be released before the function exits.]]
|
||||
|
||||
[[Throws:] [Any exceptions thrown by calling __lock_ref__ or
|
||||
__try_lock_ref__ on the supplied __lockable_concept_type__ objects.]]
|
||||
|
||||
[[Postcondition:] [All the supplied __lockable_concept_type__ objects
|
||||
are locked by the calling thread.]]
|
||||
|
||||
]
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:lock_range Non-member function `lock(begin,end)`]
|
||||
|
||||
template<typename ForwardIterator>
|
||||
void lock(ForwardIterator begin,ForwardIterator end);
|
||||
|
||||
[variablelist
|
||||
|
||||
[[Preconditions:] [The `value_type` of `ForwardIterator` must implement the __lockable_concept__]]
|
||||
|
||||
[[Effects:] [Locks all the __lockable_concept_type__ objects in the
|
||||
supplied range in an unspecified and indeterminate order in a way that
|
||||
avoids deadlock. It is safe to call this function concurrently from
|
||||
multiple threads with the same mutexes (or other lockable objects) in
|
||||
different orders without risk of deadlock. If any of the __lock_ref__
|
||||
or __try_lock_ref__ operations on the __lockable_concept_type__
|
||||
objects in the supplied range throws an exception any locks acquired
|
||||
by the function will be released before the function exits.]]
|
||||
|
||||
[[Throws:] [Any exceptions thrown by calling __lock_ref__ or
|
||||
__try_lock_ref__ on the supplied __lockable_concept_type__ objects.]]
|
||||
|
||||
[[Postcondition:] [All the __lockable_concept_type__ objects in the
|
||||
supplied range are locked by the calling thread.]]
|
||||
|
||||
]
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:try_lock_multiple Non-member function `try_lock(Lockable1,Lockable2,...)`]
|
||||
|
||||
template<typename Lockable1,typename Lockable2>
|
||||
int try_lock(Lockable1& l1,Lockable2& l2);
|
||||
|
||||
template<typename Lockable1,typename Lockable2,typename Lockable3>
|
||||
int try_lock(Lockable1& l1,Lockable2& l2,Lockable3& l3);
|
||||
|
||||
template<typename Lockable1,typename Lockable2,typename Lockable3,typename Lockable4>
|
||||
int try_lock(Lockable1& l1,Lockable2& l2,Lockable3& l3,Lockable4& l4);
|
||||
|
||||
template<typename Lockable1,typename Lockable2,typename Lockable3,typename Lockable4,typename Lockable5>
|
||||
int try_lock(Lockable1& l1,Lockable2& l2,Lockable3& l3,Lockable4& l4,Lockable5& l5);
|
||||
|
||||
[variablelist
|
||||
|
||||
[[Effects:] [Calls __try_lock_ref__ on each of the
|
||||
__lockable_concept_type__ objects supplied as arguments. If any of the
|
||||
calls to __try_lock_ref__ returns `false` then all locks acquired are
|
||||
released and the zero-based index of the failed lock is returned.
|
||||
|
||||
If any of the __try_lock_ref__ operations on the supplied
|
||||
__lockable_concept_type__ objects throws an exception any locks
|
||||
acquired by the function will be released before the function exits.]]
|
||||
|
||||
[[Returns:] [`-1` if all the supplied __lockable_concept_type__ objects
|
||||
are now locked by the calling thread, the zero-based index of the
|
||||
object which could not be locked otherwise.]]
|
||||
|
||||
[[Throws:] [Any exceptions thrown by calling __try_lock_ref__ on the
|
||||
supplied __lockable_concept_type__ objects.]]
|
||||
|
||||
[[Postcondition:] [If the function returns `-1`, all the supplied
|
||||
__lockable_concept_type__ objects are locked by the calling
|
||||
thread. Otherwise any locks acquired by this function will have been
|
||||
released.]]
|
||||
|
||||
]
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:try_lock_range Non-member function `try_lock(begin,end)`]
|
||||
|
||||
template<typename ForwardIterator>
|
||||
ForwardIterator try_lock(ForwardIterator begin,ForwardIterator end);
|
||||
|
||||
[variablelist
|
||||
|
||||
[[Preconditions:] [The `value_type` of `ForwardIterator` must implement the __lockable_concept__]]
|
||||
|
||||
[[Effects:] [Calls __try_lock_ref__ on each of the
|
||||
__lockable_concept_type__ objects in the supplied range. If any of the
|
||||
calls to __try_lock_ref__ returns `false` then all locks acquired are
|
||||
released and an iterator referencing the failed lock is returned.
|
||||
|
||||
If any of the __try_lock_ref__ operations on the supplied
|
||||
__lockable_concept_type__ objects throws an exception any locks
|
||||
acquired by the function will be released before the function exits.]]
|
||||
|
||||
[[Returns:] [`end` if all the supplied __lockable_concept_type__
|
||||
objects are now locked by the calling thread, an iterator referencing
|
||||
the object which could not be locked otherwise.]]
|
||||
|
||||
[[Throws:] [Any exceptions thrown by calling __try_lock_ref__ on the
|
||||
supplied __lockable_concept_type__ objects.]]
|
||||
|
||||
[[Postcondition:] [If the function returns `end` then all the
|
||||
__lockable_concept_type__ objects in the supplied range are locked by
|
||||
the calling thread, otherwise all locks acquired by the function have
|
||||
been released.]]
|
||||
|
||||
]
|
||||
|
||||
[endsect]
|
||||
|
||||
|
||||
[endsect]
|
||||
|
||||
@@ -9,8 +9,6 @@
|
||||
|
||||
[section:mutex Class `mutex`]
|
||||
|
||||
#include <boost/thread/mutex.hpp>
|
||||
|
||||
class mutex:
|
||||
boost::noncopyable
|
||||
{
|
||||
@@ -26,7 +24,7 @@
|
||||
native_handle_type native_handle();
|
||||
|
||||
typedef unique_lock<mutex> scoped_lock;
|
||||
typedef unspecified-type scoped_try_lock;
|
||||
typedef scoped_lock scoped_try_lock;
|
||||
};
|
||||
|
||||
__mutex__ implements the __lockable_concept__ to provide an exclusive-ownership mutex. At most one thread can own the lock on a given
|
||||
@@ -53,8 +51,6 @@ implementation. If no such instance exists, `native_handle()` and `native_handle
|
||||
|
||||
[section:try_mutex Typedef `try_mutex`]
|
||||
|
||||
#include <boost/thread/mutex.hpp>
|
||||
|
||||
typedef mutex try_mutex;
|
||||
|
||||
__try_mutex__ is a `typedef` to __mutex__, provided for backwards compatibility with previous releases of boost.
|
||||
@@ -63,8 +59,6 @@ __try_mutex__ is a `typedef` to __mutex__, provided for backwards compatibility
|
||||
|
||||
[section:timed_mutex Class `timed_mutex`]
|
||||
|
||||
#include <boost/thread/mutex.hpp>
|
||||
|
||||
class timed_mutex:
|
||||
boost::noncopyable
|
||||
{
|
||||
@@ -84,7 +78,7 @@ __try_mutex__ is a `typedef` to __mutex__, provided for backwards compatibility
|
||||
native_handle_type native_handle();
|
||||
|
||||
typedef unique_lock<timed_mutex> scoped_timed_lock;
|
||||
typedef unspecified-type scoped_try_lock;
|
||||
typedef scoped_timed_lock scoped_try_lock;
|
||||
typedef scoped_timed_lock scoped_lock;
|
||||
};
|
||||
|
||||
@@ -112,8 +106,6 @@ implementation. If no such instance exists, `native_handle()` and `native_handle
|
||||
|
||||
[section:recursive_mutex Class `recursive_mutex`]
|
||||
|
||||
#include <boost/thread/recursive_mutex.hpp>
|
||||
|
||||
class recursive_mutex:
|
||||
boost::noncopyable
|
||||
{
|
||||
@@ -129,7 +121,7 @@ implementation. If no such instance exists, `native_handle()` and `native_handle
|
||||
native_handle_type native_handle();
|
||||
|
||||
typedef unique_lock<recursive_mutex> scoped_lock;
|
||||
typedef unspecified-type scoped_try_lock;
|
||||
typedef scoped_lock scoped_try_lock;
|
||||
};
|
||||
|
||||
__recursive_mutex__ implements the __lockable_concept__ to provide an exclusive-ownership recursive mutex. At most one thread can
|
||||
@@ -158,8 +150,6 @@ implementation. If no such instance exists, `native_handle()` and `native_handle
|
||||
|
||||
[section:recursive_try_mutex Typedef `recursive_try_mutex`]
|
||||
|
||||
#include <boost/thread/recursive_mutex.hpp>
|
||||
|
||||
typedef recursive_mutex recursive_try_mutex;
|
||||
|
||||
__recursive_try_mutex__ is a `typedef` to __recursive_mutex__, provided for backwards compatibility with previous releases of boost.
|
||||
@@ -168,8 +158,6 @@ __recursive_try_mutex__ is a `typedef` to __recursive_mutex__, provided for back
|
||||
|
||||
[section:recursive_timed_mutex Class `recursive_timed_mutex`]
|
||||
|
||||
#include <boost/thread/recursive_mutex.hpp>
|
||||
|
||||
class recursive_timed_mutex:
|
||||
boost::noncopyable
|
||||
{
|
||||
@@ -190,7 +178,7 @@ __recursive_try_mutex__ is a `typedef` to __recursive_mutex__, provided for back
|
||||
native_handle_type native_handle();
|
||||
|
||||
typedef unique_lock<recursive_timed_mutex> scoped_lock;
|
||||
typedef unspecified-type scoped_try_lock;
|
||||
typedef scoped_lock scoped_try_lock;
|
||||
typedef scoped_lock scoped_timed_lock;
|
||||
};
|
||||
|
||||
|
||||
@@ -11,8 +11,6 @@
|
||||
|
||||
[section:once_flag Typedef `once_flag`]
|
||||
|
||||
#include <boost/thread/once.hpp>
|
||||
|
||||
typedef platform-specific-type once_flag;
|
||||
#define BOOST_ONCE_INIT platform-specific-initializer
|
||||
|
||||
@@ -24,8 +22,6 @@ Objects of type `boost::once_flag` shall be initialized with `BOOST_ONCE_INIT`:
|
||||
|
||||
[section:call_once Non-member function `call_once`]
|
||||
|
||||
#include <boost/thread/once.hpp>
|
||||
|
||||
template<typename Callable>
|
||||
void call_once(once_flag& flag,Callable func);
|
||||
|
||||
|
||||
@@ -19,12 +19,4 @@ closely follow the proposals presented to the C++ Standards Committee, in partic
|
||||
[@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2139.html N2139], and
|
||||
[@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2094.html N2094]
|
||||
|
||||
In order to use the classes and functions described here, you can
|
||||
either include the specific headers specified by the descriptions of
|
||||
each class or function, or include the master thread library header:
|
||||
|
||||
#include <boost/thread.hpp>
|
||||
|
||||
which includes all the other headers in turn.
|
||||
|
||||
[endsect]
|
||||
|
||||
@@ -7,8 +7,6 @@
|
||||
|
||||
[section:shared_mutex Class `shared_mutex`]
|
||||
|
||||
#include <boost/thread/shared_mutex.hpp>
|
||||
|
||||
class shared_mutex
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -38,12 +38,6 @@
|
||||
[template lock_ref_link[link_text] [link thread.synchronization.mutex_concepts.lockable.lock [link_text]]]
|
||||
[def __lock_ref__ [lock_ref_link `lock()`]]
|
||||
|
||||
[template lock_multiple_ref_link[link_text] [link thread.synchronization.lock_functions.lock_multiple [link_text]]]
|
||||
[def __lock_multiple_ref__ [lock_multiple_ref_link `lock()`]]
|
||||
|
||||
[template try_lock_multiple_ref_link[link_text] [link thread.synchronization.lock_functions.try_lock_multiple [link_text]]]
|
||||
[def __try_lock_multiple_ref__ [try_lock_multiple_ref_link `try_lock()`]]
|
||||
|
||||
[template unlock_ref_link[link_text] [link thread.synchronization.mutex_concepts.lockable.unlock [link_text]]]
|
||||
[def __unlock_ref__ [unlock_ref_link `unlock()`]]
|
||||
|
||||
@@ -107,10 +101,8 @@
|
||||
[def __recursive_timed_mutex__ [link thread.synchronization.mutex_types.recursive_timed_mutex `boost::recursive_timed_mutex`]]
|
||||
[def __shared_mutex__ [link thread.synchronization.mutex_types.shared_mutex `boost::shared_mutex`]]
|
||||
|
||||
[template unique_lock_link[link_text] [link thread.synchronization.locks.unique_lock [link_text]]]
|
||||
|
||||
[def __lock_guard__ [link thread.synchronization.locks.lock_guard `boost::lock_guard`]]
|
||||
[def __unique_lock__ [unique_lock_link `boost::unique_lock`]]
|
||||
[def __unique_lock__ [link thread.synchronization.locks.unique_lock `boost::unique_lock`]]
|
||||
[def __shared_lock__ [link thread.synchronization.locks.shared_lock `boost::shared_lock`]]
|
||||
[def __upgrade_lock__ [link thread.synchronization.locks.upgrade_lock `boost::upgrade_lock`]]
|
||||
[def __upgrade_to_unique_lock__ [link thread.synchronization.locks.upgrade_to_unique_lock `boost::upgrade_to_unique_lock`]]
|
||||
|
||||
@@ -165,8 +165,6 @@ __thread_id__ yield a total order for every non-equal thread ID.
|
||||
|
||||
[section:thread Class `thread`]
|
||||
|
||||
#include <boost/thread/thread.hpp>
|
||||
|
||||
class thread
|
||||
{
|
||||
public:
|
||||
@@ -176,9 +174,6 @@ __thread_id__ yield a total order for every non-equal thread ID.
|
||||
template <class F>
|
||||
explicit thread(F f);
|
||||
|
||||
template <class F,class A1,class A2,...>
|
||||
thread(F f,A1 a1,A2 a2,...);
|
||||
|
||||
template <class F>
|
||||
thread(detail::thread_move_t<F> f);
|
||||
|
||||
@@ -255,30 +250,6 @@ not of type __thread_interrupted__, then `std::terminate()` will be called.]]
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:multiple_argument_constructor Thread Constructor with arguments]
|
||||
|
||||
template <class F,class A1,class A2,...>
|
||||
thread(F f,A1 a1,A2 a2,...);
|
||||
|
||||
[variablelist
|
||||
|
||||
[[Preconditions:] [`F` and each `A`n must by copyable or movable.]]
|
||||
|
||||
[[Effects:] [As if [link
|
||||
thread.thread_management.thread.callable_constructor
|
||||
`thread(boost::bind(f,a1,a2,...))`. Consequently, `f` and each `a`n
|
||||
are copied into internal storage for access by the new thread.]]]
|
||||
|
||||
[[Postconditions:] [`*this` refers to the newly created thread of execution.]]
|
||||
|
||||
[[Throws:] [__thread_resource_error__ if an error occurs.]]
|
||||
|
||||
[[Note:] [Currently up to nine additional arguments `a1` to `a9` can be specified in addition to the function `f`.]]
|
||||
|
||||
]
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:destructor Thread Destructor]
|
||||
|
||||
~thread();
|
||||
@@ -509,8 +480,6 @@ value as `this->get_id()` prior to the call.]]
|
||||
|
||||
[section:non_member_swap Non-member function `swap()`]
|
||||
|
||||
#include <boost/thread/thread.hpp>
|
||||
|
||||
void swap(thread& lhs,thread& rhs);
|
||||
|
||||
[variablelist
|
||||
@@ -524,8 +493,6 @@ value as `this->get_id()` prior to the call.]]
|
||||
|
||||
[section:id Class `boost::thread::id`]
|
||||
|
||||
#include <boost/thread/thread.hpp>
|
||||
|
||||
class thread::id
|
||||
{
|
||||
public:
|
||||
@@ -674,8 +641,6 @@ instances of __thread_id__ `a` and `b` is the same if `a==b`, and different if `
|
||||
|
||||
[section:get_id Non-member function `get_id()`]
|
||||
|
||||
#include <boost/thread/thread.hpp>
|
||||
|
||||
namespace this_thread
|
||||
{
|
||||
thread::id get_id();
|
||||
@@ -693,8 +658,6 @@ instances of __thread_id__ `a` and `b` is the same if `a==b`, and different if `
|
||||
|
||||
[section:interruption_point Non-member function `interruption_point()`]
|
||||
|
||||
#include <boost/thread/thread.hpp>
|
||||
|
||||
namespace this_thread
|
||||
{
|
||||
void interruption_point();
|
||||
@@ -712,8 +675,6 @@ instances of __thread_id__ `a` and `b` is the same if `a==b`, and different if `
|
||||
|
||||
[section:interruption_requested Non-member function `interruption_requested()`]
|
||||
|
||||
#include <boost/thread/thread.hpp>
|
||||
|
||||
namespace this_thread
|
||||
{
|
||||
bool interruption_requested();
|
||||
@@ -731,8 +692,6 @@ instances of __thread_id__ `a` and `b` is the same if `a==b`, and different if `
|
||||
|
||||
[section:interruption_enabled Non-member function `interruption_enabled()`]
|
||||
|
||||
#include <boost/thread/thread.hpp>
|
||||
|
||||
namespace this_thread
|
||||
{
|
||||
bool interruption_enabled();
|
||||
@@ -750,8 +709,6 @@ instances of __thread_id__ `a` and `b` is the same if `a==b`, and different if `
|
||||
|
||||
[section:sleep Non-member function `sleep()`]
|
||||
|
||||
#include <boost/thread/thread.hpp>
|
||||
|
||||
namespace this_thread
|
||||
{
|
||||
template<typename TimeDuration>
|
||||
@@ -772,8 +729,6 @@ instances of __thread_id__ `a` and `b` is the same if `a==b`, and different if `
|
||||
|
||||
[section:yield Non-member function `yield()`]
|
||||
|
||||
#include <boost/thread/thread.hpp>
|
||||
|
||||
namespace this_thread
|
||||
{
|
||||
void yield();
|
||||
@@ -791,8 +746,6 @@ instances of __thread_id__ `a` and `b` is the same if `a==b`, and different if `
|
||||
|
||||
[section:disable_interruption Class `disable_interruption`]
|
||||
|
||||
#include <boost/thread/thread.hpp>
|
||||
|
||||
namespace this_thread
|
||||
{
|
||||
class disable_interruption
|
||||
@@ -844,8 +797,6 @@ interruption state on destruction. Instances of `disable_interruption` cannot be
|
||||
|
||||
[section:restore_interruption Class `restore_interruption`]
|
||||
|
||||
#include <boost/thread/thread.hpp>
|
||||
|
||||
namespace this_thread
|
||||
{
|
||||
class restore_interruption
|
||||
@@ -900,16 +851,12 @@ is destroyed, interruption is again disabled. Instances of `restore_interruption
|
||||
|
||||
[section:atthreadexit Non-member function template `at_thread_exit()`]
|
||||
|
||||
#include <boost/thread/thread.hpp>
|
||||
|
||||
template<typename Callable>
|
||||
void at_thread_exit(Callable func);
|
||||
|
||||
[variablelist
|
||||
|
||||
[[Effects:] [A copy of `func` is placed in
|
||||
thread-specific storage. This copy is invoked when the current thread
|
||||
exits (even if the thread has been interrupted).]]
|
||||
[[Effects:] [A copy of `func` is taken and stored to in thread-specific storage. This copy is invoked when the current thread exits.]]
|
||||
|
||||
[[Postconditions:] [A copy of `func` has been saved for invocation on thread exit.]]
|
||||
|
||||
@@ -924,8 +871,6 @@ error occurs within the thread library. Any exception thrown whilst copying `fun
|
||||
|
||||
[section:threadgroup Class `thread_group`]
|
||||
|
||||
#include <boost/thread/thread.hpp>
|
||||
|
||||
class thread_group:
|
||||
private noncopyable
|
||||
{
|
||||
@@ -933,8 +878,7 @@ error occurs within the thread library. Any exception thrown whilst copying `fun
|
||||
thread_group();
|
||||
~thread_group();
|
||||
|
||||
template<typename F>
|
||||
thread* create_thread(F threadfunc);
|
||||
thread* create_thread(const function0<void>& threadfunc);
|
||||
void add_thread(thread* thrd);
|
||||
void remove_thread(thread* thrd);
|
||||
void join_all();
|
||||
@@ -971,8 +915,7 @@ error occurs within the thread library. Any exception thrown whilst copying `fun
|
||||
|
||||
[section:create_thread Member function `create_thread()`]
|
||||
|
||||
template<typename F>
|
||||
thread* create_thread(F threadfunc);
|
||||
thread* create_thread(const function0<void>& threadfunc);
|
||||
|
||||
[variablelist
|
||||
|
||||
|
||||
@@ -47,8 +47,6 @@ date_time.posix_time.time_duration Boost.Date_Time Time Duration requirements] c
|
||||
|
||||
[section:system_time Typedef `system_time`]
|
||||
|
||||
#include <boost/thread/thread_time.hpp>
|
||||
|
||||
typedef boost::posix_time::ptime system_time;
|
||||
|
||||
See the documentation for [link date_time.posix_time.ptime_class `boost::posix_time::ptime`] in the Boost.Date_Time library.
|
||||
@@ -57,8 +55,6 @@ See the documentation for [link date_time.posix_time.ptime_class `boost::posix_t
|
||||
|
||||
[section:get_system_time Non-member function `get_system_time()`]
|
||||
|
||||
#include <boost/thread/thread_time.hpp>
|
||||
|
||||
system_time get_system_time();
|
||||
|
||||
[variablelist
|
||||
|
||||
@@ -44,8 +44,6 @@ cleaned up, that value is added to the cleanup list. Cleanup finishes when there
|
||||
|
||||
[section:thread_specific_ptr Class `thread_specific_ptr`]
|
||||
|
||||
#include <boost/thread/tss.hpp>
|
||||
|
||||
template <typename T>
|
||||
class thread_specific_ptr
|
||||
{
|
||||
|
||||
@@ -6,10 +6,8 @@
|
||||
#ifndef BOOST_THREAD_MOVE_HPP
|
||||
#define BOOST_THREAD_MOVE_HPP
|
||||
|
||||
#ifndef BOOST_NO_SFINAE
|
||||
#include <boost/utility/enable_if.hpp>
|
||||
#include <boost/type_traits/is_convertible.hpp>
|
||||
#endif
|
||||
|
||||
#include <boost/config/abi_prefix.hpp>
|
||||
|
||||
@@ -39,13 +37,11 @@ namespace boost
|
||||
};
|
||||
}
|
||||
|
||||
#ifndef BOOST_NO_SFINAE
|
||||
template<typename T>
|
||||
typename enable_if<boost::is_convertible<T&,detail::thread_move_t<T> >, T >::type move(T& t)
|
||||
typename enable_if<boost::is_convertible<T&,detail::thread_move_t<T> >, detail::thread_move_t<T> >::type move(T& t)
|
||||
{
|
||||
return T(detail::thread_move_t<T>(t));
|
||||
return t;
|
||||
}
|
||||
#endif
|
||||
|
||||
template<typename T>
|
||||
detail::thread_move_t<T> move(detail::thread_move_t<T> t)
|
||||
|
||||
@@ -172,14 +172,6 @@ namespace boost
|
||||
return static_cast<thread&&>(*this);
|
||||
}
|
||||
|
||||
#else
|
||||
#ifdef BOOST_NO_SFINAE
|
||||
template <class F>
|
||||
explicit thread(F f):
|
||||
thread_info(make_thread_info(f))
|
||||
{
|
||||
start_thread();
|
||||
}
|
||||
#else
|
||||
template <class F>
|
||||
explicit thread(F f,typename disable_if<boost::is_convertible<F&,detail::thread_move_t<F> >, dummy* >::type=0):
|
||||
@@ -187,10 +179,9 @@ namespace boost
|
||||
{
|
||||
start_thread();
|
||||
}
|
||||
#endif
|
||||
|
||||
template <class F>
|
||||
explicit thread(detail::thread_move_t<F> f):
|
||||
thread(detail::thread_move_t<F> f):
|
||||
thread_info(make_thread_info(f))
|
||||
{
|
||||
start_thread();
|
||||
@@ -339,9 +330,9 @@ namespace boost
|
||||
return t;
|
||||
}
|
||||
#else
|
||||
inline thread move(detail::thread_move_t<thread> t)
|
||||
inline detail::thread_move_t<thread> move(detail::thread_move_t<thread> t)
|
||||
{
|
||||
return thread(t);
|
||||
return t;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -10,21 +10,14 @@
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
#include <boost/thread/thread_time.hpp>
|
||||
#include <boost/detail/workaround.hpp>
|
||||
#include <boost/utility/enable_if.hpp>
|
||||
|
||||
#include <boost/config/abi_prefix.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
struct xtime;
|
||||
|
||||
#if defined(BOOST_NO_SFINAE) || \
|
||||
BOOST_WORKAROUND(__IBMCPP__, BOOST_TESTED_AT(600)) || \
|
||||
BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x590))
|
||||
#define BOOST_THREAD_NO_AUTO_DETECT_MUTEX_TYPES
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_THREAD_NO_AUTO_DETECT_MUTEX_TYPES
|
||||
|
||||
namespace detail
|
||||
{
|
||||
template<typename T>
|
||||
@@ -86,13 +79,7 @@ namespace boost
|
||||
detail::has_member_try_lock<T>::value);
|
||||
|
||||
};
|
||||
#else
|
||||
template<typename T>
|
||||
struct is_mutex_type
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(bool, value = false);
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
struct defer_lock_t
|
||||
{};
|
||||
@@ -111,74 +98,6 @@ namespace boost
|
||||
template<typename Mutex>
|
||||
class upgrade_lock;
|
||||
|
||||
template<typename Mutex>
|
||||
class unique_lock;
|
||||
|
||||
namespace detail
|
||||
{
|
||||
template<typename Mutex>
|
||||
class try_lock_wrapper;
|
||||
}
|
||||
|
||||
#ifdef BOOST_THREAD_NO_AUTO_DETECT_MUTEX_TYPES
|
||||
template<typename T>
|
||||
struct is_mutex_type<unique_lock<T> >
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(bool, value = true);
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct is_mutex_type<shared_lock<T> >
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(bool, value = true);
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct is_mutex_type<upgrade_lock<T> >
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(bool, value = true);
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct is_mutex_type<detail::try_lock_wrapper<T> >
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(bool, value = true);
|
||||
};
|
||||
|
||||
class mutex;
|
||||
class timed_mutex;
|
||||
class recursive_mutex;
|
||||
class recursive_timed_mutex;
|
||||
class shared_mutex;
|
||||
|
||||
template<>
|
||||
struct is_mutex_type<mutex>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(bool, value = true);
|
||||
};
|
||||
template<>
|
||||
struct is_mutex_type<timed_mutex>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(bool, value = true);
|
||||
};
|
||||
template<>
|
||||
struct is_mutex_type<recursive_mutex>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(bool, value = true);
|
||||
};
|
||||
template<>
|
||||
struct is_mutex_type<recursive_timed_mutex>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(bool, value = true);
|
||||
};
|
||||
template<>
|
||||
struct is_mutex_type<shared_mutex>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(bool, value = true);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
template<typename Mutex>
|
||||
class lock_guard
|
||||
{
|
||||
@@ -234,12 +153,6 @@ namespace boost
|
||||
{
|
||||
try_lock();
|
||||
}
|
||||
template<typename TimeDuration>
|
||||
unique_lock(Mutex& m_,TimeDuration const& target_time):
|
||||
m(&m_),is_locked(false)
|
||||
{
|
||||
timed_lock(target_time);
|
||||
}
|
||||
unique_lock(Mutex& m_,system_time const& target_time):
|
||||
m(&m_),is_locked(false)
|
||||
{
|
||||
@@ -536,7 +449,7 @@ namespace boost
|
||||
std::swap(m,other.m);
|
||||
std::swap(is_locked,other.is_locked);
|
||||
}
|
||||
void swap(boost::detail::thread_move_t<shared_lock<Mutex> > other)
|
||||
void swap(boost::detail::thread_move_t<shared_lock> other)
|
||||
{
|
||||
std::swap(m,other->m);
|
||||
std::swap(is_locked,other->is_locked);
|
||||
@@ -602,7 +515,7 @@ namespace boost
|
||||
is_locked=false;
|
||||
}
|
||||
|
||||
typedef void (shared_lock<Mutex>::*bool_type)();
|
||||
typedef void (shared_lock::*bool_type)();
|
||||
operator bool_type() const
|
||||
{
|
||||
return is_locked?&shared_lock::lock:0;
|
||||
@@ -933,7 +846,7 @@ namespace boost
|
||||
typedef typename base::bool_type bool_type;
|
||||
operator bool_type() const
|
||||
{
|
||||
return base::operator bool_type();
|
||||
return static_cast<base const&>(*this);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1074,63 +987,28 @@ namespace boost
|
||||
}
|
||||
}
|
||||
|
||||
namespace detail
|
||||
template<typename MutexType1,typename MutexType2>
|
||||
typename enable_if<is_mutex_type<MutexType1>, void>::type lock(MutexType1& m1,MutexType2& m2)
|
||||
{
|
||||
template<bool x>
|
||||
struct is_mutex_type_wrapper
|
||||
{};
|
||||
|
||||
template<typename MutexType1,typename MutexType2>
|
||||
void lock_impl(MutexType1& m1,MutexType2& m2,is_mutex_type_wrapper<true>)
|
||||
unsigned const lock_count=2;
|
||||
unsigned lock_first=0;
|
||||
while(true)
|
||||
{
|
||||
unsigned const lock_count=2;
|
||||
unsigned lock_first=0;
|
||||
while(true)
|
||||
switch(lock_first)
|
||||
{
|
||||
switch(lock_first)
|
||||
{
|
||||
case 0:
|
||||
lock_first=detail::lock_helper(m1,m2);
|
||||
if(!lock_first)
|
||||
return;
|
||||
break;
|
||||
case 1:
|
||||
lock_first=detail::lock_helper(m2,m1);
|
||||
if(!lock_first)
|
||||
return;
|
||||
lock_first=(lock_first+1)%lock_count;
|
||||
break;
|
||||
}
|
||||
case 0:
|
||||
lock_first=detail::lock_helper(m1,m2);
|
||||
if(!lock_first)
|
||||
return;
|
||||
break;
|
||||
case 1:
|
||||
lock_first=detail::lock_helper(m2,m1);
|
||||
if(!lock_first)
|
||||
return;
|
||||
lock_first=(lock_first+1)%lock_count;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Iterator>
|
||||
void lock_impl(Iterator begin,Iterator end,is_mutex_type_wrapper<false>);
|
||||
}
|
||||
|
||||
|
||||
template<typename MutexType1,typename MutexType2>
|
||||
void lock(MutexType1& m1,MutexType2& m2)
|
||||
{
|
||||
detail::lock_impl(m1,m2,detail::is_mutex_type_wrapper<is_mutex_type<MutexType1>::value>());
|
||||
}
|
||||
|
||||
template<typename MutexType1,typename MutexType2>
|
||||
void lock(const MutexType1& m1,MutexType2& m2)
|
||||
{
|
||||
detail::lock_impl(m1,m2,detail::is_mutex_type_wrapper<is_mutex_type<MutexType1>::value>());
|
||||
}
|
||||
|
||||
template<typename MutexType1,typename MutexType2>
|
||||
void lock(MutexType1& m1,const MutexType2& m2)
|
||||
{
|
||||
detail::lock_impl(m1,m2,detail::is_mutex_type_wrapper<is_mutex_type<MutexType1>::value>());
|
||||
}
|
||||
|
||||
template<typename MutexType1,typename MutexType2>
|
||||
void lock(const MutexType1& m1,const MutexType2& m2)
|
||||
{
|
||||
detail::lock_impl(m1,m2,detail::is_mutex_type_wrapper<is_mutex_type<MutexType1>::value>());
|
||||
}
|
||||
|
||||
template<typename MutexType1,typename MutexType2,typename MutexType3>
|
||||
@@ -1245,52 +1123,10 @@ namespace boost
|
||||
}
|
||||
}
|
||||
|
||||
namespace detail
|
||||
{
|
||||
template<typename Mutex,bool x=is_mutex_type<Mutex>::value>
|
||||
struct try_lock_impl_return
|
||||
{
|
||||
typedef int type;
|
||||
};
|
||||
|
||||
template<typename Iterator>
|
||||
struct try_lock_impl_return<Iterator,false>
|
||||
{
|
||||
typedef Iterator type;
|
||||
};
|
||||
|
||||
template<typename MutexType1,typename MutexType2>
|
||||
int try_lock_impl(MutexType1& m1,MutexType2& m2,is_mutex_type_wrapper<true>)
|
||||
{
|
||||
return ((int)detail::try_lock_internal(m1,m2))-1;
|
||||
}
|
||||
|
||||
template<typename Iterator>
|
||||
Iterator try_lock_impl(Iterator begin,Iterator end,is_mutex_type_wrapper<false>);
|
||||
}
|
||||
|
||||
template<typename MutexType1,typename MutexType2>
|
||||
typename detail::try_lock_impl_return<MutexType1>::type try_lock(MutexType1& m1,MutexType2& m2)
|
||||
typename enable_if<is_mutex_type<MutexType1>, int>::type try_lock(MutexType1& m1,MutexType2& m2)
|
||||
{
|
||||
return detail::try_lock_impl(m1,m2,detail::is_mutex_type_wrapper<is_mutex_type<MutexType1>::value>());
|
||||
}
|
||||
|
||||
template<typename MutexType1,typename MutexType2>
|
||||
typename detail::try_lock_impl_return<MutexType1>::type try_lock(const MutexType1& m1,MutexType2& m2)
|
||||
{
|
||||
return detail::try_lock_impl(m1,m2,detail::is_mutex_type_wrapper<is_mutex_type<MutexType1>::value>());
|
||||
}
|
||||
|
||||
template<typename MutexType1,typename MutexType2>
|
||||
typename detail::try_lock_impl_return<MutexType1>::type try_lock(MutexType1& m1,const MutexType2& m2)
|
||||
{
|
||||
return detail::try_lock_impl(m1,m2,detail::is_mutex_type_wrapper<is_mutex_type<MutexType1>::value>());
|
||||
}
|
||||
|
||||
template<typename MutexType1,typename MutexType2>
|
||||
typename detail::try_lock_impl_return<MutexType1>::type try_lock(const MutexType1& m1,const MutexType2& m2)
|
||||
{
|
||||
return detail::try_lock_impl(m1,m2,detail::is_mutex_type_wrapper<is_mutex_type<MutexType1>::value>());
|
||||
return ((int)detail::try_lock_internal(m1,m2))-1;
|
||||
}
|
||||
|
||||
template<typename MutexType1,typename MutexType2,typename MutexType3>
|
||||
@@ -1312,6 +1148,9 @@ namespace boost
|
||||
}
|
||||
|
||||
|
||||
template<typename Iterator>
|
||||
typename disable_if<is_mutex_type<Iterator>, void>::type lock(Iterator begin,Iterator end);
|
||||
|
||||
namespace detail
|
||||
{
|
||||
template<typename Iterator>
|
||||
@@ -1339,59 +1178,70 @@ namespace boost
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Iterator>
|
||||
Iterator try_lock_impl(Iterator begin,Iterator end,is_mutex_type_wrapper<false>)
|
||||
|
||||
{
|
||||
if(begin==end)
|
||||
{
|
||||
return end;
|
||||
}
|
||||
typedef typename std::iterator_traits<Iterator>::value_type lock_type;
|
||||
unique_lock<lock_type> guard(*begin,try_to_lock);
|
||||
|
||||
if(!guard.owns_lock())
|
||||
{
|
||||
return begin;
|
||||
}
|
||||
Iterator const failed=try_lock(++begin,end);
|
||||
if(failed==end)
|
||||
{
|
||||
guard.release();
|
||||
}
|
||||
|
||||
return failed;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
namespace detail
|
||||
template<typename Iterator>
|
||||
typename disable_if<is_mutex_type<Iterator>, Iterator>::type try_lock(Iterator begin,Iterator end)
|
||||
{
|
||||
template<typename Iterator>
|
||||
void lock_impl(Iterator begin,Iterator end,is_mutex_type_wrapper<false>)
|
||||
if(begin==end)
|
||||
{
|
||||
typedef typename std::iterator_traits<Iterator>::value_type lock_type;
|
||||
return end;
|
||||
}
|
||||
typedef typename std::iterator_traits<Iterator>::value_type lock_type;
|
||||
unique_lock<lock_type> guard(*begin,try_to_lock);
|
||||
|
||||
if(begin==end)
|
||||
{
|
||||
return;
|
||||
}
|
||||
bool start_with_begin=true;
|
||||
Iterator second=begin;
|
||||
++second;
|
||||
Iterator next=second;
|
||||
if(!guard.owns_lock())
|
||||
{
|
||||
return begin;
|
||||
}
|
||||
Iterator const failed=try_lock(++begin,end);
|
||||
if(failed==end)
|
||||
{
|
||||
guard.release();
|
||||
}
|
||||
|
||||
for(;;)
|
||||
return failed;
|
||||
}
|
||||
|
||||
template<typename Iterator>
|
||||
typename disable_if<is_mutex_type<Iterator>, void>::type lock(Iterator begin,Iterator end)
|
||||
{
|
||||
typedef typename std::iterator_traits<Iterator>::value_type lock_type;
|
||||
|
||||
if(begin==end)
|
||||
{
|
||||
return;
|
||||
}
|
||||
bool start_with_begin=true;
|
||||
Iterator second=begin;
|
||||
++second;
|
||||
Iterator next=second;
|
||||
|
||||
for(;;)
|
||||
{
|
||||
unique_lock<lock_type> begin_lock(*begin,defer_lock);
|
||||
if(start_with_begin)
|
||||
{
|
||||
unique_lock<lock_type> begin_lock(*begin,defer_lock);
|
||||
if(start_with_begin)
|
||||
begin_lock.lock();
|
||||
Iterator const failed_lock=try_lock(next,end);
|
||||
if(failed_lock==end)
|
||||
{
|
||||
begin_lock.lock();
|
||||
Iterator const failed_lock=try_lock(next,end);
|
||||
if(failed_lock==end)
|
||||
begin_lock.release();
|
||||
return;
|
||||
}
|
||||
start_with_begin=false;
|
||||
next=failed_lock;
|
||||
}
|
||||
else
|
||||
{
|
||||
detail::range_lock_guard<Iterator> guard(next,end);
|
||||
if(begin_lock.try_lock())
|
||||
{
|
||||
Iterator const failed_lock=try_lock(second,next);
|
||||
if(failed_lock==next)
|
||||
{
|
||||
begin_lock.release();
|
||||
guard.release();
|
||||
return;
|
||||
}
|
||||
start_with_begin=false;
|
||||
@@ -1399,32 +1249,16 @@ namespace boost
|
||||
}
|
||||
else
|
||||
{
|
||||
detail::range_lock_guard<Iterator> guard(next,end);
|
||||
if(begin_lock.try_lock())
|
||||
{
|
||||
Iterator const failed_lock=try_lock(second,next);
|
||||
if(failed_lock==next)
|
||||
{
|
||||
begin_lock.release();
|
||||
guard.release();
|
||||
return;
|
||||
}
|
||||
start_with_begin=false;
|
||||
next=failed_lock;
|
||||
}
|
||||
else
|
||||
{
|
||||
start_with_begin=true;
|
||||
next=second;
|
||||
}
|
||||
start_with_begin=true;
|
||||
next=second;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#include <boost/config/abi_suffix.hpp>
|
||||
#include <boost/mpl/identity.hpp>
|
||||
|
||||
#endif
|
||||
|
||||
@@ -177,7 +177,7 @@ namespace boost
|
||||
{
|
||||
struct timespec const timeout=detail::get_timespec(abs_time);
|
||||
int const res=pthread_mutex_timedlock(&m,&timeout);
|
||||
BOOST_ASSERT(!res || res==ETIMEDOUT);
|
||||
BOOST_ASSERT(!res || res==EBUSY);
|
||||
return !res;
|
||||
}
|
||||
|
||||
|
||||
@@ -57,18 +57,18 @@ namespace boost
|
||||
void lock_shared()
|
||||
{
|
||||
boost::this_thread::disable_interruption do_not_disturb;
|
||||
boost::mutex::scoped_lock lk(state_change);
|
||||
boost::mutex::scoped_lock lock(state_change);
|
||||
|
||||
while(state.exclusive || state.exclusive_waiting_blocked)
|
||||
{
|
||||
shared_cond.wait(lk);
|
||||
shared_cond.wait(lock);
|
||||
}
|
||||
++state.shared_count;
|
||||
}
|
||||
|
||||
bool try_lock_shared()
|
||||
{
|
||||
boost::mutex::scoped_lock lk(state_change);
|
||||
boost::mutex::scoped_lock lock(state_change);
|
||||
|
||||
if(state.exclusive || state.exclusive_waiting_blocked)
|
||||
{
|
||||
@@ -84,11 +84,11 @@ namespace boost
|
||||
bool timed_lock_shared(system_time const& timeout)
|
||||
{
|
||||
boost::this_thread::disable_interruption do_not_disturb;
|
||||
boost::mutex::scoped_lock lk(state_change);
|
||||
boost::mutex::scoped_lock lock(state_change);
|
||||
|
||||
while(state.exclusive || state.exclusive_waiting_blocked)
|
||||
{
|
||||
if(!shared_cond.timed_wait(lk,timeout))
|
||||
if(!shared_cond.timed_wait(lock,timeout))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -105,7 +105,7 @@ namespace boost
|
||||
|
||||
void unlock_shared()
|
||||
{
|
||||
boost::mutex::scoped_lock lk(state_change);
|
||||
boost::mutex::scoped_lock lock(state_change);
|
||||
bool const last_reader=!--state.shared_count;
|
||||
|
||||
if(last_reader)
|
||||
@@ -127,12 +127,12 @@ namespace boost
|
||||
void lock()
|
||||
{
|
||||
boost::this_thread::disable_interruption do_not_disturb;
|
||||
boost::mutex::scoped_lock lk(state_change);
|
||||
boost::mutex::scoped_lock lock(state_change);
|
||||
|
||||
while(state.shared_count || state.exclusive)
|
||||
{
|
||||
state.exclusive_waiting_blocked=true;
|
||||
exclusive_cond.wait(lk);
|
||||
exclusive_cond.wait(lock);
|
||||
}
|
||||
state.exclusive=true;
|
||||
}
|
||||
@@ -140,12 +140,12 @@ namespace boost
|
||||
bool timed_lock(system_time const& timeout)
|
||||
{
|
||||
boost::this_thread::disable_interruption do_not_disturb;
|
||||
boost::mutex::scoped_lock lk(state_change);
|
||||
boost::mutex::scoped_lock lock(state_change);
|
||||
|
||||
while(state.shared_count || state.exclusive)
|
||||
{
|
||||
state.exclusive_waiting_blocked=true;
|
||||
if(!exclusive_cond.timed_wait(lk,timeout))
|
||||
if(!exclusive_cond.timed_wait(lock,timeout))
|
||||
{
|
||||
if(state.shared_count || state.exclusive)
|
||||
{
|
||||
@@ -168,7 +168,7 @@ namespace boost
|
||||
|
||||
bool try_lock()
|
||||
{
|
||||
boost::mutex::scoped_lock lk(state_change);
|
||||
boost::mutex::scoped_lock lock(state_change);
|
||||
|
||||
if(state.shared_count || state.exclusive)
|
||||
{
|
||||
@@ -184,7 +184,7 @@ namespace boost
|
||||
|
||||
void unlock()
|
||||
{
|
||||
boost::mutex::scoped_lock lk(state_change);
|
||||
boost::mutex::scoped_lock lock(state_change);
|
||||
state.exclusive=false;
|
||||
state.exclusive_waiting_blocked=false;
|
||||
release_waiters();
|
||||
@@ -193,10 +193,10 @@ namespace boost
|
||||
void lock_upgrade()
|
||||
{
|
||||
boost::this_thread::disable_interruption do_not_disturb;
|
||||
boost::mutex::scoped_lock lk(state_change);
|
||||
boost::mutex::scoped_lock lock(state_change);
|
||||
while(state.exclusive || state.exclusive_waiting_blocked || state.upgrade)
|
||||
{
|
||||
shared_cond.wait(lk);
|
||||
shared_cond.wait(lock);
|
||||
}
|
||||
++state.shared_count;
|
||||
state.upgrade=true;
|
||||
@@ -205,10 +205,10 @@ namespace boost
|
||||
bool timed_lock_upgrade(system_time const& timeout)
|
||||
{
|
||||
boost::this_thread::disable_interruption do_not_disturb;
|
||||
boost::mutex::scoped_lock lk(state_change);
|
||||
boost::mutex::scoped_lock lock(state_change);
|
||||
while(state.exclusive || state.exclusive_waiting_blocked || state.upgrade)
|
||||
{
|
||||
if(!shared_cond.timed_wait(lk,timeout))
|
||||
if(!shared_cond.timed_wait(lock,timeout))
|
||||
{
|
||||
if(state.exclusive || state.exclusive_waiting_blocked || state.upgrade)
|
||||
{
|
||||
@@ -230,7 +230,7 @@ namespace boost
|
||||
|
||||
bool try_lock_upgrade()
|
||||
{
|
||||
boost::mutex::scoped_lock lk(state_change);
|
||||
boost::mutex::scoped_lock lock(state_change);
|
||||
if(state.exclusive || state.exclusive_waiting_blocked || state.upgrade)
|
||||
{
|
||||
return false;
|
||||
@@ -245,7 +245,7 @@ namespace boost
|
||||
|
||||
void unlock_upgrade()
|
||||
{
|
||||
boost::mutex::scoped_lock lk(state_change);
|
||||
boost::mutex::scoped_lock lock(state_change);
|
||||
state.upgrade=false;
|
||||
bool const last_reader=!--state.shared_count;
|
||||
|
||||
@@ -259,11 +259,11 @@ namespace boost
|
||||
void unlock_upgrade_and_lock()
|
||||
{
|
||||
boost::this_thread::disable_interruption do_not_disturb;
|
||||
boost::mutex::scoped_lock lk(state_change);
|
||||
boost::mutex::scoped_lock lock(state_change);
|
||||
--state.shared_count;
|
||||
while(state.shared_count)
|
||||
{
|
||||
upgrade_cond.wait(lk);
|
||||
upgrade_cond.wait(lock);
|
||||
}
|
||||
state.upgrade=false;
|
||||
state.exclusive=true;
|
||||
@@ -271,7 +271,7 @@ namespace boost
|
||||
|
||||
void unlock_and_lock_upgrade()
|
||||
{
|
||||
boost::mutex::scoped_lock lk(state_change);
|
||||
boost::mutex::scoped_lock lock(state_change);
|
||||
state.exclusive=false;
|
||||
state.upgrade=true;
|
||||
++state.shared_count;
|
||||
@@ -281,7 +281,7 @@ namespace boost
|
||||
|
||||
void unlock_and_lock_shared()
|
||||
{
|
||||
boost::mutex::scoped_lock lk(state_change);
|
||||
boost::mutex::scoped_lock lock(state_change);
|
||||
state.exclusive=false;
|
||||
++state.shared_count;
|
||||
state.exclusive_waiting_blocked=false;
|
||||
@@ -290,7 +290,7 @@ namespace boost
|
||||
|
||||
void unlock_upgrade_and_lock_shared()
|
||||
{
|
||||
boost::mutex::scoped_lock lk(state_change);
|
||||
boost::mutex::scoped_lock lock(state_change);
|
||||
state.upgrade=false;
|
||||
state.exclusive_waiting_blocked=false;
|
||||
release_waiters();
|
||||
|
||||
@@ -64,6 +64,11 @@ namespace boost
|
||||
return timed_lock(get_system_time()+timeout);
|
||||
}
|
||||
|
||||
long get_active_count()
|
||||
{
|
||||
return mutex.get_active_count();
|
||||
}
|
||||
|
||||
void unlock()
|
||||
{
|
||||
if(!--recursion_count)
|
||||
@@ -73,6 +78,11 @@ namespace boost
|
||||
}
|
||||
}
|
||||
|
||||
bool locked()
|
||||
{
|
||||
return mutex.locked();
|
||||
}
|
||||
|
||||
private:
|
||||
bool try_recursive_lock(long current_thread_id)
|
||||
{
|
||||
|
||||
@@ -123,6 +123,11 @@ namespace boost
|
||||
return timed_lock(system_time(timeout));
|
||||
}
|
||||
|
||||
long get_active_count()
|
||||
{
|
||||
return ::boost::detail::interlocked_read_acquire(&active_count);
|
||||
}
|
||||
|
||||
void unlock()
|
||||
{
|
||||
long const offset=lock_flag_value;
|
||||
@@ -136,6 +141,11 @@ namespace boost
|
||||
}
|
||||
}
|
||||
|
||||
bool locked()
|
||||
{
|
||||
return get_active_count()>=lock_flag_value;
|
||||
}
|
||||
|
||||
private:
|
||||
void* get_event()
|
||||
{
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
boost_module(thread DEPENDS date_time bind optional range)
|
||||
@@ -1,21 +0,0 @@
|
||||
#
|
||||
# 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
|
||||
)
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
#elif defined(__APPLE__) || defined(__FreeBSD__)
|
||||
#include <sys/types.h>
|
||||
#include <sys/sysctl.h>
|
||||
#elif defined BOOST_HAS_UNISTD_H
|
||||
#elif defined(__sun) || defined(__CYGWIN__)
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
@@ -132,12 +132,10 @@ namespace boost
|
||||
catch(thread_interrupted const&)
|
||||
{
|
||||
}
|
||||
// Removed as it stops the debugger identifying the cause of the exception
|
||||
// Unhandled exceptions still cause the application to terminate
|
||||
// catch(...)
|
||||
// {
|
||||
// std::terminate();
|
||||
// }
|
||||
catch(...)
|
||||
{
|
||||
std::terminate();
|
||||
}
|
||||
|
||||
detail::tls_destructor(thread_info.get());
|
||||
detail::set_current_thread_data(0);
|
||||
@@ -396,7 +394,7 @@ namespace boost
|
||||
int count;
|
||||
size_t size=sizeof(count);
|
||||
return sysctlbyname("hw.ncpu",&count,&size,NULL,0)?0:count;
|
||||
#elif defined(BOOST_HAS_UNISTD_H) && defined(_SC_NPROCESSORS_ONLN)
|
||||
#elif defined(__sun) || defined(__CYGWIN__)
|
||||
int const count=sysconf(_SC_NPROCESSORS_ONLN);
|
||||
return (count>0)?count:0;
|
||||
#else
|
||||
|
||||
@@ -29,26 +29,13 @@ namespace boost
|
||||
|
||||
void create_current_thread_tls_key()
|
||||
{
|
||||
tss_cleanup_implemented(); // if anyone uses TSS, we need the cleanup linked in
|
||||
current_thread_tls_key=TlsAlloc();
|
||||
BOOST_ASSERT(current_thread_tls_key!=TLS_OUT_OF_INDEXES);
|
||||
}
|
||||
|
||||
void cleanup_tls_key()
|
||||
{
|
||||
if(current_thread_tls_key)
|
||||
{
|
||||
TlsFree(current_thread_tls_key);
|
||||
current_thread_tls_key=0;
|
||||
}
|
||||
}
|
||||
|
||||
detail::thread_data_base* get_current_thread_data()
|
||||
{
|
||||
if(!current_thread_tls_key)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
boost::call_once(current_thread_tls_init_flag,create_current_thread_tls_key);
|
||||
return (detail::thread_data_base*)TlsGetValue(current_thread_tls_key);
|
||||
}
|
||||
|
||||
@@ -154,8 +141,8 @@ namespace boost
|
||||
}
|
||||
}
|
||||
|
||||
set_current_thread_data(0);
|
||||
}
|
||||
set_current_thread_data(0);
|
||||
}
|
||||
|
||||
unsigned __stdcall thread_start_function(void* param)
|
||||
@@ -169,12 +156,10 @@ namespace boost
|
||||
catch(thread_interrupted const&)
|
||||
{
|
||||
}
|
||||
// Removed as it stops the debugger identifying the cause of the exception
|
||||
// Unhandled exceptions still cause the application to terminate
|
||||
// catch(...)
|
||||
// {
|
||||
// std::terminate();
|
||||
// }
|
||||
catch(...)
|
||||
{
|
||||
std::terminate();
|
||||
}
|
||||
run_thread_exit_callbacks();
|
||||
return 0;
|
||||
}
|
||||
@@ -559,6 +544,7 @@ namespace boost
|
||||
|
||||
void set_tss_data(void const* key,boost::shared_ptr<tss_cleanup_function> func,void* tss_data,bool cleanup_existing)
|
||||
{
|
||||
tss_cleanup_implemented(); // if anyone uses TSS, we need the cleanup linked in
|
||||
if(tss_data_node* const current_node=find_tss_data(key))
|
||||
{
|
||||
if(cleanup_existing && current_node->func.get())
|
||||
@@ -586,9 +572,7 @@ extern "C" BOOST_THREAD_DECL void on_thread_enter()
|
||||
{}
|
||||
|
||||
extern "C" BOOST_THREAD_DECL void on_process_exit()
|
||||
{
|
||||
boost::cleanup_tls_key();
|
||||
}
|
||||
{}
|
||||
|
||||
extern "C" BOOST_THREAD_DECL void on_thread_exit()
|
||||
{
|
||||
|
||||
@@ -26,11 +26,11 @@ namespace {
|
||||
{
|
||||
switch (dwReason)
|
||||
{
|
||||
case DLL_THREAD_DETACH:
|
||||
{
|
||||
on_thread_exit();
|
||||
break;
|
||||
}
|
||||
case DLL_THREAD_DETACH:
|
||||
{
|
||||
on_thread_exit();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -125,10 +125,10 @@ extern "C" const IMAGE_TLS_DIRECTORY32 _tls_used __attribute__ ((section(".rdata
|
||||
#pragma section(".CRT$XCU",long,read)
|
||||
#pragma section(".CRT$XTU",long,read)
|
||||
#pragma section(".CRT$XLC",long,read)
|
||||
__declspec(allocate(".CRT$XLC")) _TLSCB __xl_ca=on_tls_callback;
|
||||
__declspec(allocate(".CRT$XIU"))_PVFV p_tls_prepare = on_tls_prepare;
|
||||
__declspec(allocate(".CRT$XCU"))_PVFV p_process_init = on_process_init;
|
||||
__declspec(allocate(".CRT$XTU"))_PVFV p_process_term = on_process_term;
|
||||
static __declspec(allocate(".CRT$XLC")) _TLSCB __xl_ca=on_tls_callback;
|
||||
static __declspec(allocate(".CRT$XIU"))_PVFV p_tls_prepare = on_tls_prepare;
|
||||
static __declspec(allocate(".CRT$XCU"))_PVFV p_process_init = on_process_init;
|
||||
static __declspec(allocate(".CRT$XTU"))_PVFV p_process_term = on_process_term;
|
||||
#else
|
||||
#if (_MSC_VER >= 1300) // 1300 == VC++ 7.0
|
||||
# pragma data_seg(push, old_seg)
|
||||
@@ -168,7 +168,6 @@ extern "C" const IMAGE_TLS_DIRECTORY32 _tls_used __attribute__ ((section(".rdata
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4189)
|
||||
#endif
|
||||
|
||||
PVAPI on_tls_prepare(void)
|
||||
{
|
||||
//The following line has an important side effect:
|
||||
@@ -240,32 +239,15 @@ extern "C" const IMAGE_TLS_DIRECTORY32 _tls_used __attribute__ ((section(".rdata
|
||||
{
|
||||
switch (dwReason)
|
||||
{
|
||||
case DLL_THREAD_DETACH:
|
||||
on_thread_exit();
|
||||
break;
|
||||
case DLL_THREAD_DETACH:
|
||||
{
|
||||
on_thread_exit();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BOOL WINAPI dll_callback(HANDLE, DWORD dwReason, LPVOID)
|
||||
{
|
||||
switch (dwReason)
|
||||
{
|
||||
case DLL_THREAD_DETACH:
|
||||
on_thread_exit();
|
||||
break;
|
||||
case DLL_PROCESS_DETACH:
|
||||
on_process_exit();
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
} //namespace
|
||||
|
||||
extern "C"
|
||||
{
|
||||
extern BOOL (WINAPI * const _pRawDllMain)(HANDLE, DWORD, LPVOID)=&dll_callback;
|
||||
}
|
||||
|
||||
extern "C" void tss_cleanup_implemented(void)
|
||||
{
|
||||
/*
|
||||
|
||||
@@ -1,39 +0,0 @@
|
||||
#
|
||||
# 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)
|
||||
@@ -272,16 +272,6 @@ struct dummy_mutex
|
||||
}
|
||||
};
|
||||
|
||||
namespace boost
|
||||
{
|
||||
template<>
|
||||
struct is_mutex_type<dummy_mutex>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(bool, value = true);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
||||
void test_lock_five_in_range()
|
||||
{
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
#include <boost/thread/detail/config.hpp>
|
||||
|
||||
#include <boost/thread/mutex.hpp>
|
||||
#include <boost/thread/thread.hpp>
|
||||
#include <boost/thread/recursive_mutex.hpp>
|
||||
#include <boost/thread/thread_time.hpp>
|
||||
#include <boost/thread/condition.hpp>
|
||||
@@ -97,86 +96,6 @@ struct test_trylock
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Mutex>
|
||||
struct test_lock_times_out_if_other_thread_has_lock
|
||||
{
|
||||
typedef boost::unique_lock<Mutex> Lock;
|
||||
|
||||
Mutex m;
|
||||
boost::mutex done_mutex;
|
||||
bool done;
|
||||
bool locked;
|
||||
boost::condition_variable done_cond;
|
||||
|
||||
test_lock_times_out_if_other_thread_has_lock():
|
||||
done(false),locked(false)
|
||||
{}
|
||||
|
||||
void locking_thread()
|
||||
{
|
||||
Lock lock(m,boost::defer_lock);
|
||||
lock.timed_lock(boost::posix_time::milliseconds(50));
|
||||
|
||||
boost::lock_guard<boost::mutex> lk(done_mutex);
|
||||
locked=lock.owns_lock();
|
||||
done=true;
|
||||
done_cond.notify_one();
|
||||
}
|
||||
|
||||
void locking_thread_through_constructor()
|
||||
{
|
||||
Lock lock(m,boost::posix_time::milliseconds(50));
|
||||
|
||||
boost::lock_guard<boost::mutex> lk(done_mutex);
|
||||
locked=lock.owns_lock();
|
||||
done=true;
|
||||
done_cond.notify_one();
|
||||
}
|
||||
|
||||
bool is_done() const
|
||||
{
|
||||
return done;
|
||||
}
|
||||
|
||||
typedef test_lock_times_out_if_other_thread_has_lock<Mutex> this_type;
|
||||
|
||||
void do_test(void (this_type::*test_func)())
|
||||
{
|
||||
Lock lock(m);
|
||||
|
||||
locked=false;
|
||||
done=false;
|
||||
|
||||
boost::thread t(test_func,this);
|
||||
|
||||
try
|
||||
{
|
||||
{
|
||||
boost::mutex::scoped_lock lk(done_mutex);
|
||||
BOOST_CHECK(done_cond.timed_wait(lk,boost::posix_time::seconds(2),
|
||||
boost::bind(&this_type::is_done,this)));
|
||||
BOOST_CHECK(!locked);
|
||||
}
|
||||
|
||||
lock.unlock();
|
||||
t.join();
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
lock.unlock();
|
||||
t.join();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void operator()()
|
||||
{
|
||||
do_test(&this_type::locking_thread);
|
||||
do_test(&this_type::locking_thread_through_constructor);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename M>
|
||||
struct test_timedlock
|
||||
{
|
||||
@@ -190,8 +109,6 @@ struct test_timedlock
|
||||
|
||||
void operator()()
|
||||
{
|
||||
test_lock_times_out_if_other_thread_has_lock<mutex_type>()();
|
||||
|
||||
mutex_type mutex;
|
||||
boost::condition condition;
|
||||
|
||||
@@ -261,7 +178,6 @@ struct test_recursive_lock
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
void do_test_mutex()
|
||||
{
|
||||
test_lock<boost::mutex>()();
|
||||
|
||||
@@ -5,59 +5,26 @@
|
||||
#include <boost/thread/thread.hpp>
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
void do_nothing(boost::thread::id* my_id)
|
||||
{
|
||||
*my_id=boost::this_thread::get_id();
|
||||
}
|
||||
void do_nothing()
|
||||
{}
|
||||
|
||||
void test_move_on_construction()
|
||||
{
|
||||
boost::thread::id the_id;
|
||||
boost::thread x=boost::thread(do_nothing,&the_id);
|
||||
boost::thread::id x_id=x.get_id();
|
||||
boost::thread x=boost::thread(do_nothing);
|
||||
x.join();
|
||||
BOOST_CHECK_EQUAL(the_id,x_id);
|
||||
}
|
||||
|
||||
boost::thread make_thread(boost::thread::id* the_id)
|
||||
boost::thread make_thread()
|
||||
{
|
||||
return boost::thread(do_nothing,the_id);
|
||||
return boost::thread(do_nothing);
|
||||
}
|
||||
|
||||
void test_move_from_function_return()
|
||||
{
|
||||
boost::thread::id the_id;
|
||||
boost::thread x=make_thread(&the_id);
|
||||
boost::thread::id x_id=x.get_id();
|
||||
boost::thread x=make_thread();
|
||||
x.join();
|
||||
BOOST_CHECK_EQUAL(the_id,x_id);
|
||||
}
|
||||
|
||||
boost::thread make_thread_return_lvalue(boost::thread::id* the_id)
|
||||
{
|
||||
boost::thread t(do_nothing,the_id);
|
||||
return boost::move(t);
|
||||
}
|
||||
|
||||
void test_move_from_function_return_lvalue()
|
||||
{
|
||||
boost::thread::id the_id;
|
||||
boost::thread x=make_thread_return_lvalue(&the_id);
|
||||
boost::thread::id x_id=x.get_id();
|
||||
x.join();
|
||||
BOOST_CHECK_EQUAL(the_id,x_id);
|
||||
}
|
||||
|
||||
void test_move_assign()
|
||||
{
|
||||
boost::thread::id the_id;
|
||||
boost::thread x(do_nothing,&the_id);
|
||||
boost::thread y;
|
||||
y=boost::move(x);
|
||||
boost::thread::id y_id=y.get_id();
|
||||
y.join();
|
||||
BOOST_CHECK_EQUAL(the_id,y_id);
|
||||
}
|
||||
|
||||
boost::unit_test_framework::test_suite* init_unit_test_suite(int, char*[])
|
||||
{
|
||||
@@ -66,7 +33,5 @@ boost::unit_test_framework::test_suite* init_unit_test_suite(int, char*[])
|
||||
|
||||
test->add(BOOST_TEST_CASE(test_move_on_construction));
|
||||
test->add(BOOST_TEST_CASE(test_move_from_function_return));
|
||||
test->add(BOOST_TEST_CASE(test_move_from_function_return_lvalue));
|
||||
test->add(BOOST_TEST_CASE(test_move_assign));
|
||||
return test;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user