2
0
mirror of https://github.com/boostorg/thread.git synced 2026-02-07 23:02:13 +00:00

Compare commits

..

1 Commits

Author SHA1 Message Date
Christopher Hite
71d10aadc7 optional_optimization branch
[SVN r77091]
2012-02-22 10:37:27 +00:00
64 changed files with 494 additions and 4430 deletions

View File

@@ -445,7 +445,6 @@ object passed to the constructor.]]
class unique_lock
{
public:
typedef Lockable mutex_type;
unique_lock() noexcept;
explicit unique_lock(Lockable& m_);
unique_lock(Lockable& m_,adopt_lock_t);
@@ -459,16 +458,20 @@ object passed to the constructor.]]
unique_lock(Mutex& mtx, const chrono::duration<Rep, Period>& d);
~unique_lock();
unique_lock(unique_lock const&) = delete;
unique_lock& operator=(unique_lock const&) = delete;
unique_lock(unique_lock<Lockable>&& other) noexcept;
unique_lock(detail::thread_move_t<unique_lock<Lockable> > other) noexcept;
unique_lock(upgrade_lock<Lockable>&& other) noexcept;
unique_lock(detail::thread_move_t<upgrade_lock<Lockable> > other) noexcept;
operator detail::thread_move_t<unique_lock<Lockable> >();
detail::thread_move_t<unique_lock<Lockable> > move();
unique_lock& operator=(unique_lock<Lockable>&& other) noexcept;
unique_lock& operator=(detail::thread_move_t<unique_lock<Lockable> > other) noexcept;
unique_lock& operator=(upgrade_lock<Lockable>&& other) noexcept;
unique_lock& operator=(detail::thread_move_t<upgrade_lock<Lockable> > other) noexcept;
void swap(unique_lock& other) noexcept;
Lockable* release() noexcept;
void swap(detail::thread_move_t<unique_lock<Lockable> > other) noexcept;
void lock();
bool try_lock();
@@ -484,14 +487,12 @@ object passed to the constructor.]]
void unlock();
bool owns_lock() const noexcept;
#if defined(BOOST_NO_EXPLICIT_CONVERSION_OPERATORS)
explicit operator bool() const noexcept;
operator ``['unspecified-bool-type]``() const noexcept;
bool operator!() const noexcept;
#else
explicit operator bool() const noexcept;
#endif
Lockable* mutex() const noexcept;
Lockable* release() noexcept;
};
__unique_lock__ is more complex than __lock_guard__: not only does it provide for RAII-style locking, it also allows for deferring
@@ -499,7 +500,7 @@ acquiring the lock until the __lock_ref__ member function is called explicitly,
fashion, or with a timeout. Consequently, __unlock_ref__ is only called in the destructor if the lock object has locked the
__lockable_concept_type__ object, or otherwise adopted a lock on the __lockable_concept_type__ object.
Specializations of __unique_lock__ model the __timed_lockable_concept__ if the supplied Lockable type itself models
Specializations of __unique_lock__ model the __timed_lockable_concept__ if the supplied __lockable_concept_type__ type itself models
__timed_lockable_concept__ (e.g. `boost::unique_lock<boost::timed_mutex>`), or the __lockable_concept__ otherwise
(e.g. `boost::unique_lock<boost::mutex>`).
@@ -685,18 +686,6 @@ object associated with `*this`.]]
[endsect]
[section:explicit_bool_conversion `explicit operator bool() const`]
[variablelist
[[Returns:] [`__owns_lock_ref__()`.]]
[[Throws:] [Nothing.]]
]
[endsect]
[section:bool_conversion `operator unspecified-bool-type() const`]
[variablelist
@@ -711,6 +700,17 @@ boolean contexts.]]
[endsect]
[section:explicit_bool_conversion `explicit operator bool() const`]
[variablelist
[[Returns:] [`__owns_lock_ref__()`.]]
[[Throws:] [Nothing.]]
]
[endsect]
[section:operator_not `bool operator!() const`]
@@ -754,25 +754,24 @@ __owns_lock_ref__ returns `false`.]]
class shared_lock
{
public:
typedef Lockable mutex_type;
shared_lock();
explicit shared_lock(Lockable& m_);
shared_lock(Lockable& m_,adopt_lock_t);
shared_lock(Lockable& m_,defer_lock_t);
shared_lock(Lockable& m_,try_to_lock_t);
shared_lock(Lockable& m_,system_time const& target_time);
shared_lock(detail::thread_move_t<shared_lock<Lockable> > other);
shared_lock(detail::thread_move_t<unique_lock<Lockable> > other);
shared_lock(detail::thread_move_t<upgrade_lock<Lockable> > other);
~shared_lock();
shared_lock(shared_lock const&) = delete;
shared_lock& operator=(shared_lock const&) = delete;
operator detail::thread_move_t<shared_lock<Lockable> >();
detail::thread_move_t<shared_lock<Lockable> > move();
shared_lock(shared_lock<Lockable> && other);
shared_lock(unique_lock<Lockable> && other);
shared_lock(upgrade_lock<Lockable> && other);
shared_lock& operator=(shared_lock<Lockable> && other);
shared_lock& operator=(unique_lock<Lockable> && other);
shared_lock& operator=(upgrade_lock<Lockable> && other);
shared_lock& operator=(detail::thread_move_t<shared_lock<Lockable> > other);
shared_lock& operator=(detail::thread_move_t<unique_lock<Lockable> > other);
shared_lock& operator=(detail::thread_move_t<upgrade_lock<Lockable> > other);
void swap(shared_lock& other);
void lock();
@@ -780,12 +779,8 @@ __owns_lock_ref__ returns `false`.]]
bool timed_lock(boost::system_time const& target_time);
void unlock();
#if defined(BOOST_NO_EXPLICIT_CONVERSION_OPERATORS)
operator ``['unspecified-bool-type]``() const;
bool operator!() const;
#else
explicit operator bool() const;
#endif
bool owns_lock() const;
};
@@ -964,18 +959,6 @@ boolean contexts.]]
[endsect]
[section:explicit_operator_bool `explicit operator bool() const`]
[variablelist
[[Returns:] [__owns_lock_shared_ref__.]]
[[Throws:] [Nothing.]]
]
[endsect]
[section:release `Lockable* release()`]
[variablelist
@@ -1006,31 +989,26 @@ __owns_lock_shared_ref__ returns `false`.]]
class upgrade_lock
{
public:
typedef Lockable mutex_type;
explicit upgrade_lock(Lockable& m_);
upgrade_lock(upgrade_lock<Lockable> && other);
upgrade_lock(unique_lock<Lockable> && other);
upgrade_lock(detail::thread_move_t<upgrade_lock<Lockable> > other);
upgrade_lock(detail::thread_move_t<unique_lock<Lockable> > other);
~upgrade_lock();
upgrade_lock(const upgrade_lock& other) = delete;
upgrade_lock& operator=(const upgrade_lock<Lockable> & other) = delete;
operator detail::thread_move_t<upgrade_lock<Lockable> >();
detail::thread_move_t<upgrade_lock<Lockable> > move();
upgrade_lock& operator=(upgrade_lock<Lockable> && other);
upgrade_lock& operator=(unique_lock<Lockable> && other);
upgrade_lock& operator=(detail::thread_move_t<upgrade_lock<Lockable> > other);
upgrade_lock& operator=(detail::thread_move_t<unique_lock<Lockable> > other);
void swap(upgrade_lock& other);
void lock();
void unlock();
#if defined(BOOST_NO_EXPLICIT_CONVERSION_OPERATORS)
operator ``['unspecified-bool-type]``() const;
bool operator!() const;
#else
explicit operator bool() const;
#endif
bool owns_lock() const;
};
@@ -1060,24 +1038,16 @@ state (including the destructor) must be called by the same thread that acquired
class upgrade_to_unique_lock
{
public:
typedef Lockable mutex_type;
explicit upgrade_to_unique_lock(upgrade_lock<Lockable>& m_);
~upgrade_to_unique_lock();
upgrade_to_unique_lock(upgrade_to_unique_lock const& other) = delete;
upgrade_to_unique_lock& operator=(upgrade_to_unique_lock<Lockable> const& other) = delete;
upgrade_to_unique_lock(upgrade_to_unique_lock<Lockable> && other);
upgrade_to_unique_lock& operator=(upgrade_to_unique_lock<Lockable> && other);
upgrade_to_unique_lock(detail::thread_move_t<upgrade_to_unique_lock<Lockable> > other);
upgrade_to_unique_lock& operator=(detail::thread_move_t<upgrade_to_unique_lock<Lockable> > other);
void swap(upgrade_to_unique_lock& other);
#if defined(BOOST_NO_EXPLICIT_CONVERSION_OPERATORS)
operator ``['unspecified-bool-type]``() const;
bool operator!() const;
#else
explicit operator bool() const;
#endif
bool owns_lock() const;
};
@@ -1114,13 +1084,10 @@ __lockable_concept_type__ is downgraded back to ['upgrade ownership].
MutexType* mutex() const;
MutexType* release();
#if defined(BOOST_NO_EXPLICIT_CONVERSION_OPERATORS)
operator ``['unspecified-bool-type]``() const;
bool operator!() const;
#else
explicit operator bool() const;
#endif
typedef ``['unspecified-bool-type]`` bool_type;
operator bool_type() const;
};
The member typedef `scoped_try_lock` is provided for each distinct

View File

@@ -363,13 +363,15 @@ This behavior is incompatible with the current Boost.Thread design, so the use o
thread(F f,A1 a1,A2 a2,...);
template <class F>
thread(F &&f);
thread(detail::thread_move_t<F> f);
template <class F, class ...Args> explicit thread(F&& f, Args&&... args);
// move support
thread(thread && x);
thread& operator=(thread && x);
thread(detail::thread_move_t<thread> x);
thread& operator=(detail::thread_move_t<thread> x);
operator detail::thread_move_t<thread>();
detail::thread_move_t<thread> move();
void swap(thread& x) noexcept;
@@ -406,6 +408,7 @@ This behavior is incompatible with the current Boost.Thread design, so the use o
};
void swap(thread& lhs,thread& rhs) noexcep;
detail::thread_move_t<thread> move(detail::thread_move_t<thread> t);
[section:default_constructor Default Constructor]
@@ -424,6 +427,7 @@ This behavior is incompatible with the current Boost.Thread design, so the use o
[section:move_constructor Move Constructor]
thread(thread&& other) noexcept;
thread(detail::thread_move_t<thread> other);
[variablelist
@@ -440,6 +444,7 @@ This behavior is incompatible with the current Boost.Thread design, so the use o
[section:move_assignment Move assignment operator]
thread& operator=(thread&& other) noexcept;
thread& operator=(detail::thread_move_t<thread> other);
[variablelist
@@ -858,7 +863,6 @@ value as `this->get_id()` prior to the call.]]
[endsect]
[/
[section:non_member_move Non-member function `move()`]
#include <boost/thread/thread.hpp>
@@ -878,7 +882,7 @@ Enables moving thread objects. e.g.
boost::thread t2(boost::move(t)); // transfer thread from t to t2
[endsect]
]
[section:id Class `boost::thread::id`]

View File

@@ -1,136 +0,0 @@
// Copyright (C) 2012 Vicente J. Botet Escriba
//
// 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 <iostream>
#include <boost/thread/mutex.hpp>
#include <boost/thread/shared_mutex.hpp>
#include <boost/thread/thread.hpp>
#include <boost/chrono/chrono_io.hpp>
#include <cassert>
#include <vector>
#define EXCLUSIVE 1
#define SHARED 2
#define MODE SHARED
class A
{
#if MODE == EXCLUSIVE
typedef boost::mutex mutex_type;
#elif MODE == SHARED
typedef boost::shared_mutex mutex_type;
#else
#error MODE not set
#endif
typedef std::vector<double> C;
mutable mutex_type mut_;
C data_;
public:
A() : data_(10000000) {}
A(const A& a);
A& operator=(const A& a);
void compute(const A& x, const A& y);
};
A::A(const A& a)
{
#if MODE == EXCLUSIVE
boost::unique_lock<mutex_type> lk(a.mut_);
#elif MODE == SHARED
boost::shared_lock<mutex_type> lk(a.mut_);
#else
#error MODE not set
#endif
data_ = a.data_;
}
A&
A::operator=(const A& a)
{
if (this != &a)
{
boost::unique_lock<mutex_type> lk1(mut_, boost::defer_lock);
#if MODE == EXCLUSIVE
boost::unique_lock<mutex_type> lk2(a.mut_, boost::defer_lock);
#elif MODE == SHARED
boost::shared_lock<mutex_type> lk2(a.mut_, boost::defer_lock);
#else
#error MODE not set
#endif
boost::lock(lk1, lk2);
data_ = a.data_;
}
return *this;
}
void
A::compute(const A& x, const A& y)
{
boost::unique_lock<mutex_type> lk1(mut_, boost::defer_lock);
#if MODE == EXCLUSIVE
boost::unique_lock<mutex_type> lk2(x.mut_, boost::defer_lock);
boost::unique_lock<mutex_type> lk3(y.mut_, boost::defer_lock);
#elif MODE == SHARED
boost::shared_lock<mutex_type> lk2(x.mut_, boost::defer_lock);
boost::shared_lock<mutex_type> lk3(y.mut_, boost::defer_lock);
#else
#error MODE not set
#endif
boost::lock(lk1, lk2, lk3);
assert(data_.size() == x.data_.size());
assert(data_.size() == y.data_.size());
for (unsigned i = 0; i < data_.size(); ++i)
data_[i] = (x.data_[i] + y.data_[i]) / 2;
}
A a1;
A a2;
void test_s()
{
A la3 = a1;
for (int i = 0; i < 150; ++i)
{
la3.compute(a1, a2);
}
}
void test_w()
{
A la3 = a1;
for (int i = 0; i < 10; ++i)
{
la3.compute(a1, a2);
a1 = la3;
a2 = la3;
// boost::this_thread::sleep_for(boost::chrono::seconds(1));
}
}
int main()
{
typedef boost::chrono::high_resolution_clock Clock;
typedef boost::chrono::duration<double> sec;
Clock::time_point t0 = Clock::now();
std::vector<boost::thread*> v;
boost::thread thw(test_w);
v.push_back(&thw);
boost::thread thr0(test_w);
v.push_back(&thr0);
boost::thread thr1(test_w);
v.push_back(&thr1);
boost::thread thr2(test_w);
v.push_back(&thr2);
boost::thread thr3(test_w);
v.push_back(&thr3);
for (int i = 0; i < v.size(); ++i)
v[i]->join();
Clock::time_point t1 = Clock::now();
std::cout << sec(t1-t0) << '\n';
return 0;
}

View File

@@ -1,722 +0,0 @@
// Copyright (C) 2012 Vicente J. Botet Escriba
//
// 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)
#define BOOST_THREAD_SHARED_MUTEX_PROVIDES_UPWARDS_CONVERSION
#define BOOST_THREAD_PROVIDES_EXPLICIT_LOCK_CONVERSION
#include <iostream>
#include <boost/thread/mutex.hpp>
#include <boost/thread/shared_mutex.hpp>
#include <boost/thread/thread.hpp>
#include <boost/chrono/chrono_io.hpp>
#include <cassert>
#include <vector>
enum {reading, writing};
int state = reading;
#if 1
boost::mutex&
cout_mut()
{
static boost::mutex m;
return m;
}
void
print(const char* tag, unsigned count, char ch)
{
boost::lock_guard<boost::mutex> _(cout_mut());
std::cout << tag << count << ch;
}
#elif 0
boost::recursive_mutex&
cout_mut()
{
static boost::recursive_mutex m;
return m;
}
void print() {}
template <class A0, class ...Args>
void
print(const A0& a0, const Args& ...args)
{
boost::lock_guard<boost::recursive_mutex> _(cout_mut());
std::cout << a0;
print(args...);
}
#else
template <class A0, class A1, class A2>
void
print(const A0&, const A1& a1, const A2&)
{
assert(a1 > 10000);
}
#endif
namespace S
{
boost::shared_mutex mut;
void reader()
{
typedef boost::chrono::steady_clock Clock;
unsigned count = 0;
Clock::time_point until = Clock::now() + boost::chrono::seconds(3);
while (Clock::now() < until)
{
mut.lock_shared();
assert(state == reading);
++count;
mut.unlock_shared();
}
print("reader = ", count, '\n');
}
void writer()
{
typedef boost::chrono::steady_clock Clock;
unsigned count = 0;
Clock::time_point until = Clock::now() + boost::chrono::seconds(3);
while (Clock::now() < until)
{
mut.lock();
state = writing;
assert(state == writing);
state = reading;
++count;
mut.unlock();
}
print("writer = ", count, '\n');
}
void try_reader()
{
typedef boost::chrono::steady_clock Clock;
unsigned count = 0;
Clock::time_point until = Clock::now() + boost::chrono::seconds(3);
while (Clock::now() < until)
{
if (mut.try_lock_shared())
{
assert(state == reading);
++count;
mut.unlock_shared();
}
}
print("try_reader = ", count, '\n');
}
void try_writer()
{
typedef boost::chrono::steady_clock Clock;
unsigned count = 0;
Clock::time_point until = Clock::now() + boost::chrono::seconds(3);
while (Clock::now() < until)
{
if (mut.try_lock())
{
state = writing;
assert(state == writing);
state = reading;
++count;
mut.unlock();
}
}
print("try_writer = ", count, '\n');
}
void try_for_reader()
{
typedef boost::chrono::steady_clock Clock;
unsigned count = 0;
Clock::time_point until = Clock::now() + boost::chrono::seconds(3);
while (Clock::now() < until)
{
if (mut.try_lock_shared_for(boost::chrono::microseconds(5)))
{
assert(state == reading);
++count;
mut.unlock_shared();
}
}
print("try_for_reader = ", count, '\n');
}
void try_for_writer()
{
typedef boost::chrono::steady_clock Clock;
unsigned count = 0;
Clock::time_point until = Clock::now() + boost::chrono::seconds(3);
while (Clock::now() < until)
{
if (mut.try_lock_for(boost::chrono::microseconds(5)))
{
state = writing;
assert(state == writing);
state = reading;
++count;
mut.unlock();
}
}
print("try_for_writer = ", count, '\n');
}
void
test_shared_mutex()
{
{
boost::thread t1(reader);
boost::thread t2(writer);
boost::thread t3(reader);
t1.join();
t2.join();
t3.join();
}
{
boost::thread t1(try_reader);
boost::thread t2(try_writer);
boost::thread t3(try_reader);
t1.join();
t2.join();
t3.join();
}
{
boost::thread t1(try_for_reader);
boost::thread t2(try_for_writer);
boost::thread t3(try_for_reader);
t1.join();
t2.join();
t3.join();
}
}
}
namespace U
{
boost::upgrade_mutex mut;
void reader()
{
typedef boost::chrono::steady_clock Clock;
unsigned count = 0;
Clock::time_point until = Clock::now() + boost::chrono::seconds(3);
while (Clock::now() < until)
{
mut.lock_shared();
assert(state == reading);
++count;
mut.unlock_shared();
}
print("reader = ", count, '\n');
}
void writer()
{
typedef boost::chrono::steady_clock Clock;
unsigned count = 0;
Clock::time_point until = Clock::now() + boost::chrono::seconds(3);
while (Clock::now() < until)
{
mut.lock();
state = writing;
assert(state == writing);
state = reading;
++count;
mut.unlock();
}
print("writer = ", count, '\n');
}
void try_reader()
{
typedef boost::chrono::steady_clock Clock;
unsigned count = 0;
Clock::time_point until = Clock::now() + boost::chrono::seconds(3);
while (Clock::now() < until)
{
if (mut.try_lock_shared())
{
assert(state == reading);
++count;
mut.unlock_shared();
}
}
print("try_reader = ", count, '\n');
}
void try_writer()
{
typedef boost::chrono::steady_clock Clock;
unsigned count = 0;
Clock::time_point until = Clock::now() + boost::chrono::seconds(3);
while (Clock::now() < until)
{
if (mut.try_lock())
{
state = writing;
assert(state == writing);
state = reading;
++count;
mut.unlock();
}
}
print("try_writer = ", count, '\n');
}
void try_for_reader()
{
typedef boost::chrono::steady_clock Clock;
unsigned count = 0;
Clock::time_point until = Clock::now() + boost::chrono::seconds(3);
while (Clock::now() < until)
{
if (mut.try_lock_shared_for(boost::chrono::microseconds(5)))
{
assert(state == reading);
++count;
mut.unlock_shared();
}
}
print("try_for_reader = ", count, '\n');
}
void try_for_writer()
{
typedef boost::chrono::steady_clock Clock;
unsigned count = 0;
Clock::time_point until = Clock::now() + boost::chrono::seconds(3);
while (Clock::now() < until)
{
if (mut.try_lock_for(boost::chrono::microseconds(5)))
{
state = writing;
assert(state == writing);
state = reading;
++count;
mut.unlock();
}
}
print("try_for_writer = ", count, '\n');
}
void upgradable()
{
typedef boost::chrono::steady_clock Clock;
unsigned count = 0;
Clock::time_point until = Clock::now() + boost::chrono::seconds(3);
while (Clock::now() < until)
{
mut.lock_upgrade();
assert(state == reading);
++count;
mut.unlock_upgrade();
}
print("upgradable = ", count, '\n');
}
void try_upgradable()
{
typedef boost::chrono::steady_clock Clock;
unsigned count = 0;
Clock::time_point until = Clock::now() + boost::chrono::seconds(3);
while (Clock::now() < until)
{
if (mut.try_lock_upgrade())
{
assert(state == reading);
++count;
mut.unlock_upgrade();
}
}
print("try_upgradable = ", count, '\n');
}
void try_for_upgradable()
{
typedef boost::chrono::steady_clock Clock;
unsigned count = 0;
Clock::time_point until = Clock::now() + boost::chrono::seconds(3);
while (Clock::now() < until)
{
if (mut.try_lock_upgrade_for(boost::chrono::microseconds(5)))
{
assert(state == reading);
++count;
mut.unlock_upgrade();
}
}
print("try_for_upgradable = ", count, '\n');
}
void clockwise()
{
typedef boost::chrono::steady_clock Clock;
unsigned count = 0;
Clock::time_point until = Clock::now() + boost::chrono::seconds(3);
while (Clock::now() < until)
{
mut.lock_shared();
assert(state == reading);
if (mut.try_unlock_shared_and_lock())
{
state = writing;
}
else if (mut.try_unlock_shared_and_lock_upgrade())
{
assert(state == reading);
mut.unlock_upgrade_and_lock();
state = writing;
}
else
{
mut.unlock_shared();
continue;
}
assert(state == writing);
state = reading;
mut.unlock_and_lock_upgrade();
assert(state == reading);
mut.unlock_upgrade_and_lock_shared();
assert(state == reading);
mut.unlock_shared();
++count;
}
print("clockwise = ", count, '\n');
}
void counter_clockwise()
{
typedef boost::chrono::steady_clock Clock;
unsigned count = 0;
Clock::time_point until = Clock::now() + boost::chrono::seconds(3);
while (Clock::now() < until)
{
mut.lock_upgrade();
assert(state == reading);
mut.unlock_upgrade_and_lock();
assert(state == reading);
state = writing;
assert(state == writing);
state = reading;
mut.unlock_and_lock_shared();
assert(state == reading);
mut.unlock_shared();
++count;
}
print("counter_clockwise = ", count, '\n');
}
void try_clockwise()
{
typedef boost::chrono::steady_clock Clock;
unsigned count = 0;
Clock::time_point until = Clock::now() + boost::chrono::seconds(3);
while (Clock::now() < until)
{
if (mut.try_lock_shared())
{
assert(state == reading);
if (mut.try_unlock_shared_and_lock())
{
state = writing;
}
else if (mut.try_unlock_shared_and_lock_upgrade())
{
assert(state == reading);
mut.unlock_upgrade_and_lock();
state = writing;
}
else
{
mut.unlock_shared();
continue;
}
assert(state == writing);
state = reading;
mut.unlock_and_lock_upgrade();
assert(state == reading);
mut.unlock_upgrade_and_lock_shared();
assert(state == reading);
mut.unlock_shared();
++count;
}
}
print("try_clockwise = ", count, '\n');
}
void try_for_clockwise()
{
typedef boost::chrono::steady_clock Clock;
unsigned count = 0;
Clock::time_point until = Clock::now() + boost::chrono::seconds(3);
while (Clock::now() < until)
{
if (mut.try_lock_shared_for(boost::chrono::microseconds(5)))
{
assert(state == reading);
if (mut.try_unlock_shared_and_lock_for(boost::chrono::microseconds(5)))
{
state = writing;
}
else if (mut.try_unlock_shared_and_lock_upgrade_for(boost::chrono::microseconds(5)))
{
assert(state == reading);
mut.unlock_upgrade_and_lock();
state = writing;
}
else
{
mut.unlock_shared();
continue;
}
assert(state == writing);
state = reading;
mut.unlock_and_lock_upgrade();
assert(state == reading);
mut.unlock_upgrade_and_lock_shared();
assert(state == reading);
mut.unlock_shared();
++count;
}
}
print("try_for_clockwise = ", count, '\n');
}
void try_counter_clockwise()
{
typedef boost::chrono::steady_clock Clock;
unsigned count = 0;
Clock::time_point until = Clock::now() + boost::chrono::seconds(3);
while (Clock::now() < until)
{
if (mut.try_lock_upgrade())
{
assert(state == reading);
if (mut.try_unlock_upgrade_and_lock())
{
assert(state == reading);
state = writing;
assert(state == writing);
state = reading;
mut.unlock_and_lock_shared();
assert(state == reading);
mut.unlock_shared();
++count;
}
else
{
mut.unlock_upgrade();
}
}
}
print("try_counter_clockwise = ", count, '\n');
}
void try_for_counter_clockwise()
{
typedef boost::chrono::steady_clock Clock;
unsigned count = 0;
Clock::time_point until = Clock::now() + boost::chrono::seconds(3);
while (Clock::now() < until)
{
if (mut.try_lock_upgrade_for(boost::chrono::microseconds(5)))
{
assert(state == reading);
if (mut.try_unlock_upgrade_and_lock_for(boost::chrono::microseconds(5)))
{
assert(state == reading);
state = writing;
assert(state == writing);
state = reading;
mut.unlock_and_lock_shared();
assert(state == reading);
mut.unlock_shared();
++count;
}
else
{
mut.unlock_upgrade();
}
}
}
print("try_for_counter_clockwise = ", count, '\n');
}
void
test_upgrade_mutex()
{
{
boost::thread t1(reader);
boost::thread t2(writer);
boost::thread t3(reader);
t1.join();
t2.join();
t3.join();
}
{
boost::thread t1(try_reader);
boost::thread t2(try_writer);
boost::thread t3(try_reader);
t1.join();
t2.join();
t3.join();
}
{
boost::thread t1(try_for_reader);
boost::thread t2(try_for_writer);
boost::thread t3(try_for_reader);
t1.join();
t2.join();
t3.join();
}
{
boost::thread t1(reader);
boost::thread t2(writer);
boost::thread t3(upgradable);
t1.join();
t2.join();
t3.join();
}
{
boost::thread t1(reader);
boost::thread t2(writer);
boost::thread t3(try_upgradable);
t1.join();
t2.join();
t3.join();
}
{
boost::thread t1(reader);
boost::thread t2(writer);
boost::thread t3(try_for_upgradable);
t1.join();
t2.join();
t3.join();
}
{
state = reading;
boost::thread t1(clockwise);
boost::thread t2(counter_clockwise);
boost::thread t3(clockwise);
boost::thread t4(counter_clockwise);
t1.join();
t2.join();
t3.join();
t4.join();
}
{
state = reading;
boost::thread t1(try_clockwise);
boost::thread t2(try_counter_clockwise);
t1.join();
t2.join();
}
{
state = reading;
boost::thread t1(try_for_clockwise);
boost::thread t2(try_for_counter_clockwise);
t1.join();
t2.join();
}
}
}
namespace Assignment
{
class A
{
typedef boost::upgrade_mutex mutex_type;
typedef boost::shared_lock<mutex_type> SharedLock;
typedef boost::upgrade_lock<mutex_type> UpgradeLock;
typedef boost::unique_lock<mutex_type> Lock;
mutable mutex_type mut_;
std::vector<double> data_;
public:
A(const A& a)
{
SharedLock _(a.mut_);
data_ = a.data_;
}
A& operator=(const A& a)
{
if (this != &a)
{
Lock this_lock(mut_, boost::defer_lock);
SharedLock that_lock(a.mut_, boost::defer_lock);
boost::lock(this_lock, that_lock);
data_ = a.data_;
}
return *this;
}
void swap(A& a)
{
Lock this_lock(mut_, boost::defer_lock);
Lock that_lock(a.mut_, boost::defer_lock);
boost::lock(this_lock, that_lock);
data_.swap(a.data_);
}
void average(A& a)
{
assert(data_.size() == a.data_.size());
assert(this != &a);
Lock this_lock(mut_, boost::defer_lock);
UpgradeLock share_that_lock(a.mut_, boost::defer_lock);
boost::lock(this_lock, share_that_lock);
for (unsigned i = 0; i < data_.size(); ++i)
data_[i] = (data_[i] + a.data_[i]) / 2;
SharedLock share_this_lock(boost::move(this_lock));
Lock that_lock(boost::move(share_that_lock));
a.data_ = data_;
}
};
} // Assignment
void temp()
{
using namespace boost;
static upgrade_mutex mut;
unique_lock<upgrade_mutex> ul(mut);
shared_lock<upgrade_mutex> sl;
sl = shared_lock<upgrade_mutex>(boost::move(ul));
}
int main()
{
typedef boost::chrono::high_resolution_clock Clock;
typedef boost::chrono::duration<double> sec;
Clock::time_point t0 = Clock::now();
S::test_shared_mutex();
U::test_upgrade_mutex();
Clock::time_point t1 = Clock::now();
std::cout << sec(t1 - t0) << '\n';
return 0;
}

View File

@@ -26,20 +26,6 @@
#define BOOST_THREAD_USES_CHRONO
#endif
//#if BOOST_WORKAROUND(__SUNPRO_CC, < 0x5100)
//#define BOOST_THREAD_DONT_USE_MOVE
//#endif
//#define BOOST_THREAD_SHARED_MUTEX_PROVIDES_UPWARDS_CONVERSION
//#define BOOST_THREAD_PROVIDES_EXPLICIT_LOCK_CONVERSION
#if defined BOOST_THREAD_PROVIDES_EXPLICIT_LOCK_CONVERSION
#define BOOST_THREAD_EXPLICIT_LOCK_CONVERSION explicit
#else
#define BOOST_THREAD_EXPLICIT_LOCK_CONVERSION
#endif
#if ! defined BOOST_THREAD_DONT_USE_MOVE
#define BOOST_THREAD_USES_MOVE
#endif

View File

@@ -144,7 +144,7 @@ namespace boost
class BOOST_THREAD_DECL thread
{
public:
//typedef int boost_move_emulation_t;
typedef int boost_move_emulation_t;
typedef thread_attributes attributes;
#ifndef BOOST_NO_DELETED_FUNCTIONS
@@ -153,8 +153,20 @@ namespace boost
thread& operator=(thread const&) = delete;
#else // BOOST_NO_DELETED_FUNCTIONS
private:
// BOOST_MOVABLE_BUT_NOT_COPYABLE(thread)
#if defined BOOST_THREAD_USES_MOVE
private:
//thread(thread const&);
thread(thread &);
//thread& operator=(thread const&);
thread& operator=(thread &);
#else
private:
thread(thread&);
thread& operator=(thread&);
#endif
public:
#endif // BOOST_NO_DELETED_FUNCTIONS
private:
@@ -388,15 +400,6 @@ namespace boost
#endif
#if defined BOOST_THREAD_USES_MOVE
::boost::rv<thread>& move()
{
return *static_cast< ::boost::rv<thread>* >(this);
}
const ::boost::rv<thread>& move() const
{
return *static_cast<const ::boost::rv<thread>* >(this);
}
operator ::boost::rv<thread>&()
{
return *static_cast< ::boost::rv<thread>* >(this);
@@ -500,24 +503,19 @@ namespace boost
template <class Rep, class Period>
bool try_join_for(const chrono::duration<Rep, Period>& rel_time)
{
return try_join_until(chrono::steady_clock::now() + rel_time);
return try_join_for(chrono::ceil<chrono::milliseconds>(rel_time));
}
template <class Clock, class Duration>
bool try_join_until(const chrono::time_point<Clock, Duration>& t)
{
using namespace chrono;
system_clock::time_point s_now = system_clock::now();
typename Clock::time_point c_now = Clock::now();
return try_join_until(s_now + ceil<nanoseconds>(t - c_now));
return try_join_for(chrono::ceil<chrono::milliseconds>(t - c_now));
}
template <class Duration>
bool try_join_until(const chrono::time_point<chrono::system_clock, Duration>& t)
{
using namespace chrono;
typedef time_point<system_clock, nanoseconds> nano_sys_tmpt;
return try_join_until(nano_sys_tmpt(ceil<nanoseconds>(t.time_since_epoch())));
}
bool try_join_until(const chrono::time_point<chrono::system_clock, chrono::nanoseconds>& tp);
#endif
private:
#ifdef BOOST_THREAD_USES_CHRONO
bool do_try_join_for(chrono::milliseconds const &rel_time_in_milliseconds);
#endif
public:

View File

@@ -104,17 +104,14 @@ namespace boost
}
}
class BOOST_SYMBOL_VISIBLE future_error
class BOOST_THREAD_DECL future_error
: public std::logic_error
{
system::error_code ec_;
public:
future_error(system::error_code ec)
: logic_error(ec.message()),
ec_(ec)
{
}
future_error(system::error_code ec);
BOOST_SYMBOL_VISIBLE
const system::error_code& code() const BOOST_NOEXCEPT
{
return ec_;
@@ -789,8 +786,8 @@ namespace boost
#ifndef BOOST_NO_DELETED_FUNCTIONS
public:
BOOST_THREAD_FUTURE(BOOST_THREAD_FUTURE const& rhs) = delete;
BOOST_THREAD_FUTURE& operator=(BOOST_THREAD_FUTURE const& rhs) = delete;
BOOST_THREAD_FUTURE(BOOST_THREAD_FUTURE & rhs) = delete;
BOOST_THREAD_FUTURE& operator=(BOOST_THREAD_FUTURE& rhs) = delete;
#else // BOOST_NO_DELETED_FUNCTIONS
private:
BOOST_THREAD_FUTURE(BOOST_THREAD_FUTURE & rhs);// = delete;
@@ -824,11 +821,11 @@ namespace boost
{}
#ifndef BOOST_NO_RVALUE_REFERENCES
BOOST_THREAD_FUTURE(BOOST_THREAD_FUTURE && other) BOOST_NOEXCEPT
BOOST_THREAD_FUTURE(BOOST_THREAD_FUTURE && other)
{
future_.swap(other.future_);
}
BOOST_THREAD_FUTURE& operator=(BOOST_THREAD_FUTURE && other) BOOST_NOEXCEPT
BOOST_THREAD_FUTURE& operator=(BOOST_THREAD_FUTURE && other)
{
future_=other.future_;
other.future_.reset();
@@ -836,13 +833,13 @@ namespace boost
}
#else
#if defined BOOST_THREAD_USES_MOVE
BOOST_THREAD_FUTURE(boost::rv<BOOST_THREAD_FUTURE>& other) BOOST_NOEXCEPT:
BOOST_THREAD_FUTURE(boost::rv<BOOST_THREAD_FUTURE>& other):
future_(other.future_)
{
other.future_.reset();
}
BOOST_THREAD_FUTURE& operator=(boost::rv<BOOST_THREAD_FUTURE>& other) BOOST_NOEXCEPT
BOOST_THREAD_FUTURE& operator=(boost::rv<BOOST_THREAD_FUTURE>& other)
{
future_=other.future_;
other.future_.reset();
@@ -856,22 +853,14 @@ namespace boost
{
return *static_cast<const ::boost::rv<BOOST_THREAD_FUTURE>* >(this);
}
::boost::rv<BOOST_THREAD_FUTURE>& move()
{
return *static_cast< ::boost::rv<BOOST_THREAD_FUTURE>* >(this);
}
const ::boost::rv<BOOST_THREAD_FUTURE>& move() const
{
return *static_cast<const ::boost::rv<BOOST_THREAD_FUTURE>* >(this);
}
#else
BOOST_THREAD_FUTURE(boost::detail::thread_move_t<BOOST_THREAD_FUTURE> other) BOOST_NOEXCEPT:
BOOST_THREAD_FUTURE(boost::detail::thread_move_t<BOOST_THREAD_FUTURE> other):
future_(other->future_)
{
other->future_.reset();
}
BOOST_THREAD_FUTURE& operator=(boost::detail::thread_move_t<BOOST_THREAD_FUTURE> other) BOOST_NOEXCEPT
BOOST_THREAD_FUTURE& operator=(boost::detail::thread_move_t<BOOST_THREAD_FUTURE> other)
{
future_=other->future_;
other->future_.reset();
@@ -882,16 +871,8 @@ namespace boost
{
return boost::detail::thread_move_t<BOOST_THREAD_FUTURE>(*this);
}
boost::detail::thread_move_t<BOOST_THREAD_FUTURE> move()
{
return boost::detail::thread_move_t<BOOST_THREAD_FUTURE>(*this);
}
#endif
#endif
shared_future<R> share()
{
return shared_future<R>(::boost::move(*this));
}
void swap(BOOST_THREAD_FUTURE& other)
{
@@ -910,7 +891,7 @@ namespace boost
}
// functions to check state, and wait for ready
state get_state() const BOOST_NOEXCEPT
state get_state() const
{
if(!future_)
{
@@ -920,22 +901,22 @@ namespace boost
}
bool is_ready() const BOOST_NOEXCEPT
bool is_ready() const
{
return get_state()==future_state::ready;
}
bool has_exception() const BOOST_NOEXCEPT
bool has_exception() const
{
return future_ && future_->has_exception();
}
bool has_value() const BOOST_NOEXCEPT
bool has_value() const
{
return future_ && future_->has_value();
}
bool valid() const BOOST_NOEXCEPT
bool valid() const
{
return future_ != 0;
}
@@ -1029,21 +1010,21 @@ namespace boost
return *this;
}
#ifndef BOOST_NO_RVALUE_REFERENCES
shared_future(shared_future && other) BOOST_NOEXCEPT
shared_future(shared_future && other)
{
future_.swap(other.future_);
}
shared_future(BOOST_THREAD_FUTURE<R> && other) BOOST_NOEXCEPT
shared_future(BOOST_THREAD_FUTURE<R> && other)
{
future_.swap(other.future_);
}
shared_future& operator=(shared_future && other) BOOST_NOEXCEPT
shared_future& operator=(shared_future && other)
{
future_.swap(other.future_);
other.future_.reset();
return *this;
}
shared_future& operator=(BOOST_THREAD_FUTURE<R> && other) BOOST_NOEXCEPT
shared_future& operator=(BOOST_THREAD_FUTURE<R> && other)
{
future_.swap(other.future_);
other.future_.reset();
@@ -1051,24 +1032,24 @@ namespace boost
}
#else
#if defined BOOST_THREAD_USES_MOVE
shared_future(boost::rv<shared_future>& other) BOOST_NOEXCEPT :
shared_future(boost::rv<shared_future>& other):
future_(other.future_)
{
other.future_.reset();
}
// shared_future(const BOOST_THREAD_FUTURE<R> &) = delete;
shared_future(boost::rv<BOOST_THREAD_FUTURE<R> >& other) BOOST_NOEXCEPT :
shared_future(boost::rv<BOOST_THREAD_FUTURE<R> >& other):
future_(other.future_)
{
other.future_.reset();
}
shared_future& operator=(boost::rv<shared_future>& other) BOOST_NOEXCEPT
shared_future& operator=(boost::rv<shared_future>& other)
{
future_.swap(other.future_);
other.future_.reset();
return *this;
}
shared_future& operator=(boost::rv<BOOST_THREAD_FUTURE<R> >& other) BOOST_NOEXCEPT
shared_future& operator=(boost::rv<BOOST_THREAD_FUTURE<R> >& other)
{
future_.swap(other.future_);
other.future_.reset();
@@ -1082,35 +1063,27 @@ namespace boost
{
return *static_cast<const ::boost::rv<shared_future>* >(this);
}
::boost::rv<shared_future>& move()
{
return *static_cast< ::boost::rv<shared_future>* >(this);
}
const ::boost::rv<shared_future>& move() const
{
return *static_cast<const ::boost::rv<shared_future>* >(this);
}
#else
shared_future(boost::detail::thread_move_t<shared_future> other) BOOST_NOEXCEPT :
shared_future(boost::detail::thread_move_t<shared_future> other):
future_(other->future_)
{
other->future_.reset();
}
// shared_future(const BOOST_THREAD_FUTURE<R> &) = delete;
shared_future(boost::detail::thread_move_t<BOOST_THREAD_FUTURE<R> > other) BOOST_NOEXCEPT :
shared_future(boost::detail::thread_move_t<BOOST_THREAD_FUTURE<R> > other):
future_(other->future_)
{
other->future_.reset();
}
shared_future& operator=(boost::detail::thread_move_t<shared_future> other) BOOST_NOEXCEPT
shared_future& operator=(boost::detail::thread_move_t<shared_future> other)
{
future_.swap(other->future_);
other->future_.reset();
return *this;
}
shared_future& operator=(boost::detail::thread_move_t<BOOST_THREAD_FUTURE<R> > other) BOOST_NOEXCEPT
shared_future& operator=(boost::detail::thread_move_t<BOOST_THREAD_FUTURE<R> > other)
{
future_.swap(other->future_);
other->future_.reset();
@@ -1121,14 +1094,10 @@ namespace boost
{
return boost::detail::thread_move_t<shared_future>(*this);
}
boost::detail::thread_move_t<shared_future> move()
{
return boost::detail::thread_move_t<shared_future>(*this);
}
#endif
#endif
void swap(shared_future& other) BOOST_NOEXCEPT
void swap(shared_future& other)
{
future_.swap(other.future_);
}
@@ -1145,7 +1114,7 @@ namespace boost
}
// functions to check state, and wait for ready
state get_state() const BOOST_NOEXCEPT
state get_state() const
{
if(!future_)
{
@@ -1154,22 +1123,18 @@ namespace boost
return future_->get_state();
}
bool valid() const BOOST_NOEXCEPT
{
return future_ != 0;
}
bool is_ready() const BOOST_NOEXCEPT
bool is_ready() const
{
return get_state()==future_state::ready;
}
bool has_exception() const BOOST_NOEXCEPT
bool has_exception() const
{
return future_ && future_->has_exception();
}
bool has_value() const BOOST_NOEXCEPT
bool has_value() const
{
return future_ && future_->has_value();
}
@@ -1236,8 +1201,8 @@ namespace boost
#ifndef BOOST_NO_DELETED_FUNCTIONS
public:
promise(promise const& rhs) = delete;
promise & operator=(promise const & rhs) = delete;
promise(promise const& rhs);// = delete;
promise & operator=(promise const & rhs);// = delete;
#else // BOOST_NO_DELETED_FUNCTIONS
private:
promise(promise & rhs);// = delete;
@@ -1283,21 +1248,21 @@ namespace boost
// Assignment
#ifndef BOOST_NO_RVALUE_REFERENCES
promise(promise && rhs) BOOST_NOEXCEPT:
//#if ! BOOST_THREAD_VERSION==1
// future_(rhs.future_),
//#endif
promise(promise && rhs):
#if ! BOOST_THREAD_VERSION==1
future_(rhs.future_),
#endif
future_obtained(rhs.future_obtained)
{
//#if BOOST_THREAD_VERSION==1
future_.swap(rhs.future_);
//#else
// we need to release the future as shared_ptr doesn't implements move semantics
#if BOOST_THREAD_VERSION==1
future_.swap(rhs.future_);
#else
// we need to release the future as shared_ptr doesn't implements move semantics
rhs.future_.reset();
//#endif
#endif
rhs.future_obtained=false;
}
promise & operator=(promise&& rhs) BOOST_NOEXCEPT
promise & operator=(promise&& rhs)
{
#if BOOST_THREAD_VERSION==1
future_.swap(rhs.future_);
@@ -1312,13 +1277,13 @@ namespace boost
}
#else
#if defined BOOST_THREAD_USES_MOVE
promise(boost::rv<promise>& rhs) BOOST_NOEXCEPT :
promise(boost::rv<promise>& rhs):
future_(rhs.future_),future_obtained(rhs.future_obtained)
{
rhs.future_.reset();
rhs.future_obtained=false;
}
promise & operator=(boost::rv<promise>& rhs) BOOST_NOEXCEPT
promise & operator=(boost::rv<promise>& rhs)
{
future_=rhs.future_;
future_obtained=rhs.future_obtained;
@@ -1334,22 +1299,14 @@ namespace boost
{
return *static_cast<const ::boost::rv<promise>* >(this);
}
::boost::rv<promise>& move()
{
return *static_cast< ::boost::rv<promise>* >(this);
}
const ::boost::rv<promise>& move() const
{
return *static_cast<const ::boost::rv<promise>* >(this);
}
#else
promise(boost::detail::thread_move_t<promise> rhs) BOOST_NOEXCEPT:
promise(boost::detail::thread_move_t<promise> rhs):
future_(rhs->future_),future_obtained(rhs->future_obtained)
{
rhs->future_.reset();
rhs->future_obtained=false;
}
promise & operator=(boost::detail::thread_move_t<promise> rhs) BOOST_NOEXCEPT
promise & operator=(boost::detail::thread_move_t<promise> rhs)
{
future_=rhs->future_;
future_obtained=rhs->future_obtained;
@@ -1374,16 +1331,22 @@ namespace boost
// Result retrieval
BOOST_THREAD_FUTURE<R> get_future()
{
std::cout<< __LINE__ << " " << int(future_obtained) << std::endl;
lazy_init();
std::cout<< __LINE__ << " " << int(future_obtained) << std::endl;
if (future_.get()==0)
{
std::cout<< __LINE__ << " " << int(future_obtained) << std::endl;
boost::throw_exception(promise_moved());
}
if (future_obtained)
{
std::cout<< __LINE__ << " " << int(future_obtained) << std::endl;
boost::throw_exception(future_already_retrieved());
}
std::cout<< __LINE__ << " " << int(future_obtained) << std::endl;
future_obtained=true;
std::cout<< __LINE__ << " " << int(future_obtained) << std::endl;
return BOOST_THREAD_FUTURE<R>(future_);
}
@@ -1440,8 +1403,8 @@ namespace boost
#ifndef BOOST_NO_DELETED_FUNCTIONS
public:
promise(promise const& rhs) = delete;
promise & operator=(promise const & rhs) = delete;
promise(promise const& rhs);// = delete;
promise & operator=(promise const & rhs);// = delete;
#else // BOOST_NO_DELETED_FUNCTIONS
private:
promise(promise & rhs);// = delete;
@@ -1451,24 +1414,17 @@ namespace boost
void lazy_init()
{
#if BOOST_THREAD_VERSION==1
if(!atomic_load(&future_))
{
future_ptr blank;
atomic_compare_exchange(&future_,&blank,future_ptr(new detail::future_object<void>));
}
#endif
}
public:
// template <class Allocator> explicit promise(Allocator a);
promise():
#if BOOST_THREAD_VERSION==1
future_(),
#else
future_(new detail::future_object<void>),
#endif
future_obtained(false)
future_(),future_obtained(false)
{}
~promise()
@@ -1486,15 +1442,13 @@ namespace boost
// Assignment
#ifndef BOOST_NO_RVALUE_REFERENCES
promise(promise && rhs) BOOST_NOEXCEPT :
promise(promise && rhs):
future_obtained(rhs.future_obtained)
{
future_.swap(rhs.future_);
// we need to release the future as shared_ptr doesn't implements move semantics
rhs.future_.reset();
rhs.future_obtained=false;
}
promise & operator=(promise&& rhs) BOOST_NOEXCEPT
promise & operator=(promise&& rhs)
{
future_.swap(rhs.future_);
future_obtained=rhs.future_obtained;
@@ -1504,13 +1458,13 @@ namespace boost
}
#else
#if defined BOOST_THREAD_USES_MOVE
promise(boost::rv<promise>& rhs) BOOST_NOEXCEPT :
promise(boost::rv<promise>& rhs):
future_(rhs.future_),future_obtained(rhs.future_obtained)
{
rhs.future_.reset();
rhs.future_obtained=false;
}
promise & operator=(boost::rv<promise>& rhs) BOOST_NOEXCEPT
promise & operator=(boost::rv<promise>& rhs)
{
future_=rhs.future_;
future_obtained=rhs.future_obtained;
@@ -1526,22 +1480,14 @@ namespace boost
{
return *static_cast<const ::boost::rv<promise>* >(this);
}
::boost::rv<promise>& move()
{
return *static_cast< ::boost::rv<promise>* >(this);
}
const ::boost::rv<promise>& move() const
{
return *static_cast<const ::boost::rv<promise>* >(this);
}
#else
promise(boost::detail::thread_move_t<promise> rhs) BOOST_NOEXCEPT :
promise(boost::detail::thread_move_t<promise> rhs):
future_(rhs->future_),future_obtained(rhs->future_obtained)
{
rhs->future_.reset();
rhs->future_obtained=false;
}
promise & operator=(boost::detail::thread_move_t<promise> rhs) BOOST_NOEXCEPT
promise & operator=(boost::detail::thread_move_t<promise> rhs)
{
future_=rhs->future_;
future_obtained=rhs->future_obtained;
@@ -1554,10 +1500,6 @@ namespace boost
{
return boost::detail::thread_move_t<promise>(*this);
}
boost::detail::thread_move_t<promise> move()
{
return boost::detail::thread_move_t<promise>(*this);
}
#endif
#endif
@@ -1572,10 +1514,6 @@ namespace boost
{
lazy_init();
if (future_.get()==0)
{
boost::throw_exception(promise_moved());
}
if(future_obtained)
{
boost::throw_exception(future_already_retrieved());
@@ -1692,7 +1630,7 @@ namespace boost
{
this->mark_finished_with_result(f());
}
catch(thread_interrupted& )
catch(thread_interrupted& it)
{
this->mark_interrupted_finish();
}
@@ -1734,7 +1672,7 @@ namespace boost
f();
this->mark_finished_with_result();
}
catch(thread_interrupted& )
catch(thread_interrupted& it)
{
this->mark_interrupted_finish();
}
@@ -1756,8 +1694,8 @@ namespace boost
#ifndef BOOST_NO_DELETED_FUNCTIONS
public:
packaged_task(packaged_task const&) = delete;
packaged_task& operator=(packaged_task const&) = delete;
packaged_task(packaged_task const&);// = delete;
packaged_task& operator=(packaged_task const&);// = delete;
#else // BOOST_NO_DELETED_FUNCTIONS
private:
packaged_task(packaged_task&);// = delete;
@@ -1812,13 +1750,13 @@ namespace boost
// assignment
#ifndef BOOST_NO_RVALUE_REFERENCES
packaged_task(packaged_task&& other) BOOST_NOEXCEPT :
packaged_task(packaged_task&& other):
future_obtained(other.future_obtained)
{
task.swap(other.task);
other.future_obtained=false;
}
packaged_task& operator=(packaged_task&& other) BOOST_NOEXCEPT
packaged_task& operator=(packaged_task&& other)
{
packaged_task temp(static_cast<packaged_task&&>(other));
swap(temp);
@@ -1826,13 +1764,13 @@ namespace boost
}
#else
#if defined BOOST_THREAD_USES_MOVE
packaged_task(boost::rv<packaged_task>& other) BOOST_NOEXCEPT :
packaged_task(boost::rv<packaged_task>& other):
future_obtained(other.future_obtained)
{
task.swap(other.task);
other.future_obtained=false;
}
packaged_task& operator=(boost::rv<packaged_task>& other) BOOST_NOEXCEPT
packaged_task& operator=(boost::rv<packaged_task>& other)
{
packaged_task temp(other);
swap(temp);
@@ -1846,22 +1784,14 @@ namespace boost
{
return *static_cast<const ::boost::rv<packaged_task>* >(this);
}
::boost::rv<packaged_task>& move()
{
return *static_cast< ::boost::rv<packaged_task>* >(this);
}
const ::boost::rv<packaged_task>& move() const
{
return *static_cast<const ::boost::rv<packaged_task>* >(this);
}
#else
packaged_task(boost::detail::thread_move_t<packaged_task> other) BOOST_NOEXCEPT:
packaged_task(boost::detail::thread_move_t<packaged_task> other):
future_obtained(other->future_obtained)
{
task.swap(other->task);
other->future_obtained=false;
}
packaged_task& operator=(boost::detail::thread_move_t<packaged_task> other) BOOST_NOEXCEPT
packaged_task& operator=(boost::detail::thread_move_t<packaged_task> other)
{
packaged_task temp(other);
swap(temp);
@@ -1871,22 +1801,14 @@ namespace boost
{
return boost::detail::thread_move_t<packaged_task>(*this);
}
boost::detail::thread_move_t<packaged_task> move()
{
return boost::detail::thread_move_t<packaged_task>(*this);
}
#endif
#endif
void swap(packaged_task& other) BOOST_NOEXCEPT
void swap(packaged_task& other)
{
task.swap(other.task);
std::swap(future_obtained,other.future_obtained);
}
bool valid() const BOOST_NOEXCEPT
{
return task.get()!=0;
}
// result retrieval
BOOST_THREAD_FUTURE<R> get_future()

View File

@@ -2,7 +2,6 @@
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// (C) Copyright 2007 Anthony Williams
// (C) Copyright 2011-2012 Vicente J. Botet Escriba
#ifndef BOOST_THREAD_LOCKS_HPP
#define BOOST_THREAD_LOCKS_HPP
#include <boost/thread/detail/config.hpp>
@@ -278,6 +277,7 @@ namespace boost
}
};
template<typename Mutex>
class unique_lock
{
@@ -355,24 +355,22 @@ namespace boost
other.is_locked=false;
other.m=0;
}
BOOST_THREAD_EXPLICIT_LOCK_CONVERSION unique_lock(upgrade_lock<Mutex>&& other);
explicit unique_lock(upgrade_lock<Mutex>&& other);
unique_lock& operator=(unique_lock&& other) BOOST_NOEXCEPT
{
unique_lock temp(::boost::move(other));
unique_lock temp(move(other));
swap(temp);
return *this;
}
#ifndef BOOST_THREAD_PROVIDES_EXPLICIT_LOCK_CONVERSION
unique_lock& operator=(upgrade_lock<Mutex>&& other) BOOST_NOEXCEPT
{
unique_lock temp(::boost::move(other));
unique_lock temp(move(other));
swap(temp);
return *this;
}
#endif
#else
#if defined BOOST_THREAD_USES_MOVE
unique_lock(boost::rv<unique_lock<Mutex> >& other) BOOST_NOEXCEPT:
@@ -381,7 +379,7 @@ namespace boost
other.is_locked=false;
other.m=0;
}
BOOST_THREAD_EXPLICIT_LOCK_CONVERSION unique_lock(boost::rv<upgrade_lock<Mutex> >& other);
unique_lock(boost::rv<upgrade_lock<Mutex> >& other);
operator ::boost::rv<unique_lock<Mutex> >&()
{
@@ -391,14 +389,7 @@ namespace boost
{
return *static_cast<const ::boost::rv<unique_lock<Mutex> >* >(this);
}
::boost::rv<unique_lock<Mutex> >& move()
{
return *static_cast< ::boost::rv<unique_lock<Mutex> >* >(this);
}
const ::boost::rv<unique_lock<Mutex> >& move() const
{
return *static_cast<const ::boost::rv<unique_lock<Mutex> >* >(this);
}
#if BOOST_WORKAROUND(__SUNPRO_CC, < 0x5100)
unique_lock& operator=(unique_lock<Mutex> other)
{
@@ -414,14 +405,12 @@ namespace boost
}
#endif
#ifndef BOOST_THREAD_PROVIDES_EXPLICIT_LOCK_CONVERSION
unique_lock& operator=(boost::rv<upgrade_lock<Mutex> >& other) BOOST_NOEXCEPT
{
unique_lock temp(other);
swap(temp);
return *this;
}
#endif
#else
unique_lock(detail::thread_move_t<unique_lock<Mutex> > other) BOOST_NOEXCEPT:
m(other->m),is_locked(other->is_locked)
@@ -429,7 +418,7 @@ namespace boost
other->is_locked=false;
other->m=0;
}
BOOST_THREAD_EXPLICIT_LOCK_CONVERSION unique_lock(detail::thread_move_t<upgrade_lock<Mutex> > other);
unique_lock(detail::thread_move_t<upgrade_lock<Mutex> > other);
operator detail::thread_move_t<unique_lock<Mutex> >()
{
@@ -456,15 +445,12 @@ namespace boost
}
#endif
#ifndef BOOST_THREAD_PROVIDES_EXPLICIT_LOCK_CONVERSION
unique_lock& operator=(detail::thread_move_t<upgrade_lock<Mutex> > other) BOOST_NOEXCEPT
{
unique_lock temp(other);
swap(temp);
return *this;
}
#endif
void swap(detail::thread_move_t<unique_lock<Mutex> > other) BOOST_NOEXCEPT
{
std::swap(m,other->m);
@@ -472,174 +458,6 @@ namespace boost
}
#endif
#endif
#ifndef BOOST_NO_RVALUE_REFERENCES
// Conversion from upgrade locking
unique_lock(upgrade_lock<mutex_type>&& ul, try_to_lock_t)
: m(0),is_locked(false)
{
if (ul.owns_lock()) {
if (ul.mutex()->try_unlock_upgrade_and_lock())
{
m = ul.release();
is_locked = true;
}
}
else
{
m = ul.release();
}
}
#ifdef BOOST_THREAD_USES_CHRONO
template <class Clock, class Duration>
unique_lock(upgrade_lock<mutex_type>&& ul,
const chrono::time_point<Clock, Duration>& abs_time)
: m(0),is_locked(false)
{
if (ul.owns_lock()) {
if (ul.mutex()->try_unlock_upgrade_and_lock_until(abs_time))
{
m = ul.release();
is_locked = true;
}
}
else
{
m = ul.release();
}
}
template <class Rep, class Period>
unique_lock(upgrade_lock<mutex_type>&& ul,
const chrono::duration<Rep, Period>& rel_time)
: m(0),is_locked(false)
{
if (ul.owns_lock()) {
if (ul.mutex()->try_unlock_upgrade_and_lock_for(rel_time))
{
m = ul.release();
is_locked = true;
}
}
else
{
m = ul.release();
}
}
#endif
#else
#if defined BOOST_THREAD_USES_MOVE
// Conversion from upgrade locking
unique_lock(boost::rv<upgrade_lock<mutex_type> > &ul, try_to_lock_t)
: m(0),is_locked(false)
{
if (ul.owns_lock()) {
if (ul.mutex()->try_unlock_upgrade_and_lock())
{
m = ul.release();
is_locked = true;
}
}
else
{
m = ul.release();
}
}
#ifdef BOOST_THREAD_USES_CHRONO
template <class Clock, class Duration>
unique_lock(boost::rv<upgrade_lock<mutex_type> > &ul,
const chrono::time_point<Clock, Duration>& abs_time)
: m(0),is_locked(false)
{
if (ul.owns_lock()) {
if (ul.mutex()->try_unlock_upgrade_and_lock_until(abs_time))
{
m = ul.release();
is_locked = true;
}
}
else
{
m = ul.release();
}
}
template <class Rep, class Period>
unique_lock(boost::rv<upgrade_lock<mutex_type> > &ul,
const chrono::duration<Rep, Period>& rel_time)
: m(0),is_locked(false)
{
if (ul.owns_lock()) {
if (ul.mutex()->try_unlock_upgrade_and_lock_for(rel_time))
{
m = ul.release();
is_locked = true;
}
}
else
{
m = ul.release();
}
}
#endif
#else
// Conversion from upgrade locking
unique_lock(detail::thread_move_t<upgrade_lock<mutex_type> > ul, try_to_lock_t)
: m(0),is_locked(false)
{
if (ul.owns_lock()) {
if (ul.mutex()->try_unlock_upgrade_and_lock())
{
m = ul.release();
is_locked = true;
}
}
else
{
m = ul.release();
}
}
#ifdef BOOST_THREAD_USES_CHRONO
template <class Clock, class Duration>
unique_lock(detail::thread_move_t<upgrade_lock<mutex_type> > ul,
const chrono::time_point<Clock, Duration>& abs_time)
: m(0),is_locked(false)
{
if (ul.owns_lock()) {
if (ul.mutex()->try_unlock_upgrade_and_lock_until(abs_time))
{
m = ul.release();
is_locked = true;
}
}
else
{
m = ul.release();
}
}
template <class Rep, class Period>
unique_lock(detail::thread_move_t<upgrade_lock<mutex_type> > ul,
const chrono::duration<Rep, Period>& rel_time)
: m(0),is_locked(false)
{
if (ul.owns_lock()) {
if (ul.mutex()->try_unlock_upgrade_and_lock_for(rel_time))
{
m = ul.release();
is_locked = true;
}
}
else
{
m = ul.release();
}
}
#endif
#endif
#endif
void swap(unique_lock& other) BOOST_NOEXCEPT
{
std::swap(m,other.m);
@@ -883,7 +701,7 @@ namespace boost
other.m=0;
}
BOOST_THREAD_EXPLICIT_LOCK_CONVERSION shared_lock(unique_lock<Mutex> && other):
shared_lock(unique_lock<Mutex> && other):
m(other.m),is_locked(other.is_locked)
{
if(is_locked)
@@ -894,7 +712,7 @@ namespace boost
other.m=0;
}
BOOST_THREAD_EXPLICIT_LOCK_CONVERSION shared_lock(upgrade_lock<Mutex> && other):
shared_lock(upgrade_lock<Mutex> && other):
m(other.m),is_locked(other.is_locked)
{
if(is_locked)
@@ -908,26 +726,25 @@ namespace boost
shared_lock& operator=(shared_lock<Mutex> && other)
{
shared_lock temp(::boost::move(other));
shared_lock temp(other);
swap(temp);
return *this;
}
#ifndef BOOST_THREAD_PROVIDES_EXPLICIT_LOCK_CONVERSION
shared_lock& operator=(unique_lock<Mutex> && other)
{
shared_lock temp(::boost::move(other));
shared_lock temp(other);
swap(temp);
return *this;
}
shared_lock& operator=(upgrade_lock<Mutex> && other)
{
shared_lock temp(::boost::move(other));
shared_lock temp(other);
swap(temp);
return *this;
}
#endif
#else
#if defined BOOST_THREAD_USES_MOVE
shared_lock(boost::rv<shared_lock<Mutex> >& other):
@@ -937,7 +754,7 @@ namespace boost
other.m=0;
}
BOOST_THREAD_EXPLICIT_LOCK_CONVERSION shared_lock(boost::rv<unique_lock<Mutex> >& other):
shared_lock(boost::rv<unique_lock<Mutex> >& other):
m(other.m),is_locked(other.is_locked)
{
if(is_locked)
@@ -948,7 +765,7 @@ namespace boost
other.m=0;
}
BOOST_THREAD_EXPLICIT_LOCK_CONVERSION shared_lock(boost::rv<upgrade_lock<Mutex> >& other):
shared_lock(boost::rv<upgrade_lock<Mutex> >& other):
m(other.m),is_locked(other.is_locked)
{
if(is_locked)
@@ -967,14 +784,6 @@ namespace boost
{
return *static_cast<const ::boost::rv<shared_lock<Mutex> >* >(this);
}
::boost::rv<shared_lock<Mutex> >& move()
{
return *static_cast< ::boost::rv<shared_lock<Mutex> >* >(this);
}
const ::boost::rv<shared_lock<Mutex> >& move() const
{
return *static_cast<const ::boost::rv<shared_lock<Mutex> >* >(this);
}
shared_lock& operator=(::boost::rv<shared_lock<Mutex> >& other)
{
@@ -983,7 +792,6 @@ namespace boost
return *this;
}
#ifndef BOOST_THREAD_PROVIDES_EXPLICIT_LOCK_CONVERSION
shared_lock& operator=(::boost::rv<unique_lock<Mutex> >& other)
{
shared_lock temp(other);
@@ -997,7 +805,7 @@ namespace boost
swap(temp);
return *this;
}
#endif
#else
shared_lock(detail::thread_move_t<shared_lock<Mutex> > other):
@@ -1007,7 +815,7 @@ namespace boost
other->m=0;
}
BOOST_THREAD_EXPLICIT_LOCK_CONVERSION shared_lock(detail::thread_move_t<unique_lock<Mutex> > other):
shared_lock(detail::thread_move_t<unique_lock<Mutex> > other):
m(other->m),is_locked(other->is_locked)
{
if(is_locked)
@@ -1018,7 +826,7 @@ namespace boost
other->m=0;
}
BOOST_THREAD_EXPLICIT_LOCK_CONVERSION shared_lock(detail::thread_move_t<upgrade_lock<Mutex> > other):
shared_lock(detail::thread_move_t<upgrade_lock<Mutex> > other):
m(other->m),is_locked(other->is_locked)
{
if(is_locked)
@@ -1047,7 +855,6 @@ namespace boost
return *this;
}
#ifndef BOOST_THREAD_PROVIDES_EXPLICIT_LOCK_CONVERSION
shared_lock& operator=(detail::thread_move_t<unique_lock<Mutex> > other)
{
shared_lock temp(other);
@@ -1062,7 +869,6 @@ namespace boost
return *this;
}
#endif
#endif
#endif
void swap(shared_lock& other)
@@ -1218,6 +1024,7 @@ namespace boost
{};
#endif
template<typename Mutex>
void swap(shared_lock<Mutex>& lhs,shared_lock<Mutex>& rhs)
{
@@ -1261,20 +1068,6 @@ namespace boost
{
try_lock();
}
#ifdef BOOST_THREAD_USES_CHRONO
template <class Clock, class Duration>
upgrade_lock(Mutex& mtx, const chrono::time_point<Clock, Duration>& t)
: m(&mtx), is_locked(mtx.try_lock_upgrade_until(t))
{
}
template <class Rep, class Period>
upgrade_lock(Mutex& mtx, const chrono::duration<Rep, Period>& d)
: m(&mtx), is_locked(mtx.try_lock_upgrade_for(d))
{
}
#endif
#ifndef BOOST_NO_RVALUE_REFERENCES
upgrade_lock(upgrade_lock<Mutex>&& other):
m(other.m),is_locked(other.is_locked)
@@ -1283,7 +1076,7 @@ namespace boost
other.m=0;
}
BOOST_THREAD_EXPLICIT_LOCK_CONVERSION upgrade_lock(unique_lock<Mutex>&& other):
upgrade_lock(unique_lock<Mutex>&& other):
m(other.m),is_locked(other.is_locked)
{
if(is_locked)
@@ -1296,19 +1089,18 @@ namespace boost
upgrade_lock& operator=(upgrade_lock<Mutex>&& other)
{
upgrade_lock temp(::boost::move(other));
upgrade_lock temp(static_cast<upgrade_lock<Mutex>&&>(other));
swap(temp);
return *this;
}
#ifndef BOOST_THREAD_PROVIDES_EXPLICIT_LOCK_CONVERSION
upgrade_lock& operator=(unique_lock<Mutex>&& other)
{
upgrade_lock temp(::boost::move(other));
upgrade_lock temp(static_cast<unique_lock<Mutex>&&>(other));
swap(temp);
return *this;
}
#endif
#else
#if defined BOOST_THREAD_USES_MOVE
upgrade_lock(boost::rv<upgrade_lock<Mutex> >& other):
@@ -1318,7 +1110,7 @@ namespace boost
other.m=0;
}
BOOST_THREAD_EXPLICIT_LOCK_CONVERSION upgrade_lock(boost::rv<unique_lock<Mutex> >& other):
upgrade_lock(boost::rv<unique_lock<Mutex> >& other):
m(other.m),is_locked(other.is_locked)
{
if(is_locked)
@@ -1337,14 +1129,7 @@ namespace boost
{
return *static_cast<const ::boost::rv<upgrade_lock>* >(this);
}
::boost::rv<upgrade_lock>& move()
{
return *static_cast< ::boost::rv<upgrade_lock>* >(this);
}
const ::boost::rv<upgrade_lock>& move() const
{
return *static_cast<const ::boost::rv<upgrade_lock>* >(this);
}
upgrade_lock& operator=(boost::rv<upgrade_lock<Mutex> >& other)
{
upgrade_lock temp(other);
@@ -1352,14 +1137,12 @@ namespace boost
return *this;
}
#ifndef BOOST_THREAD_PROVIDES_EXPLICIT_LOCK_CONVERSION
upgrade_lock& operator=(boost::rv<unique_lock<Mutex> >& other)
{
upgrade_lock temp(other);
swap(temp);
return *this;
}
#endif
#else
upgrade_lock(detail::thread_move_t<upgrade_lock<Mutex> > other):
m(other->m),is_locked(other->is_locked)
@@ -1368,7 +1151,7 @@ namespace boost
other->m=0;
}
BOOST_THREAD_EXPLICIT_LOCK_CONVERSION upgrade_lock(detail::thread_move_t<unique_lock<Mutex> > other):
upgrade_lock(detail::thread_move_t<unique_lock<Mutex> > other):
m(other->m),is_locked(other->is_locked)
{
if(is_locked)
@@ -1397,7 +1180,6 @@ namespace boost
return *this;
}
#ifndef BOOST_THREAD_PROVIDES_EXPLICIT_LOCK_CONVERSION
upgrade_lock& operator=(detail::thread_move_t<unique_lock<Mutex> > other)
{
upgrade_lock temp(other);
@@ -1405,7 +1187,6 @@ namespace boost
return *this;
}
#endif
#endif
#endif
void swap(upgrade_lock& other)
@@ -1413,18 +1194,7 @@ namespace boost
std::swap(m,other.m);
std::swap(is_locked,other.is_locked);
}
Mutex* mutex() const
{
return m;
}
Mutex* release() BOOST_NOEXCEPT
{
Mutex* const res=m;
m=0;
is_locked=false;
return res;
}
~upgrade_lock()
{
if(owns_lock())
@@ -1434,10 +1204,6 @@ namespace boost
}
void lock()
{
if(m==0)
{
boost::throw_exception(boost::lock_error(system::errc::operation_not_permitted, "boost shared_lock has no mutex"));
}
if(owns_lock())
{
boost::throw_exception(boost::lock_error(system::errc::resource_deadlock_would_occur, "boost upgrade_lock owns already the mutex"));
@@ -1447,10 +1213,6 @@ namespace boost
}
bool try_lock()
{
if(m==0)
{
boost::throw_exception(boost::lock_error(system::errc::operation_not_permitted, "boost shared_lock has no mutex"));
}
if(owns_lock())
{
boost::throw_exception(boost::lock_error(system::errc::resource_deadlock_would_occur, "boost upgrade_lock owns already the mutex"));
@@ -1460,10 +1222,6 @@ namespace boost
}
void unlock()
{
if(m==0)
{
boost::throw_exception(boost::lock_error(system::errc::operation_not_permitted, "boost shared_lock has no mutex"));
}
if(!owns_lock())
{
boost::throw_exception(boost::lock_error(system::errc::operation_not_permitted, "boost upgrade_lock doesn't own the mutex"));
@@ -1471,36 +1229,7 @@ namespace boost
m->unlock_upgrade();
is_locked=false;
}
#ifdef BOOST_THREAD_USES_CHRONO
template <class Rep, class Period>
bool try_lock_for(const chrono::duration<Rep, Period>& rel_time)
{
if(m==0)
{
boost::throw_exception(boost::lock_error(system::errc::operation_not_permitted, "boost shared_lock has no mutex"));
}
if(owns_lock())
{
boost::throw_exception(boost::lock_error(system::errc::resource_deadlock_would_occur, "boost shared_lock owns already the mutex"));
}
is_locked=m->try_lock_upgrade_for(rel_time);
return is_locked;
}
template <class Clock, class Duration>
bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time)
{
if(m==0)
{
boost::throw_exception(boost::lock_error(system::errc::operation_not_permitted, "boost shared_lock has no mutex"));
}
if(owns_lock())
{
boost::throw_exception(boost::lock_error(system::errc::resource_deadlock_would_occur, "boost shared_lock owns already the mutex"));
}
is_locked=m->try_lock_upgrade_until(abs_time);
return is_locked;
}
#endif
#if defined(BOOST_NO_EXPLICIT_CONVERSION_OPERATORS)
typedef void (upgrade_lock::*bool_type)();
operator bool_type() const
@@ -1525,12 +1254,6 @@ namespace boost
friend class unique_lock<Mutex>;
};
template<typename Mutex>
void swap(upgrade_lock<Mutex>& lhs,upgrade_lock<Mutex>& rhs) BOOST_NOEXCEPT
{
lhs.swap(rhs);
}
#if defined BOOST_NO_RVALUE_REFERENCES && ! defined BOOST_THREAD_USES_MOVE
template <typename Mutex>
struct has_move_emulation_enabled_aux<upgrade_lock<Mutex> >
@@ -1544,11 +1267,11 @@ namespace boost
unique_lock<Mutex>::unique_lock(upgrade_lock<Mutex>&& other):
m(other.m),is_locked(other.is_locked)
{
other.is_locked=false;
if(is_locked)
{
m->unlock_upgrade_and_lock();
}
other.release();
}
#else
#if defined BOOST_THREAD_USES_MOVE
@@ -1556,22 +1279,22 @@ namespace boost
unique_lock<Mutex>::unique_lock(boost::rv<upgrade_lock<Mutex> >& other):
m(other.m),is_locked(other.is_locked)
{
other.is_locked=false;
if(is_locked)
{
m->unlock_upgrade_and_lock();
}
other.release();
}
#else
template<typename Mutex>
unique_lock<Mutex>::unique_lock(detail::thread_move_t<upgrade_lock<Mutex> > other):
m(other->m),is_locked(other->is_locked)
{
other->is_locked=false;
if(is_locked)
{
m->unlock_upgrade_and_lock();
}
other.release();
}
#endif
#endif
@@ -1594,19 +1317,19 @@ namespace boost
public:
typedef Mutex mutex_type;
explicit upgrade_to_unique_lock(upgrade_lock<Mutex>& m_):
source(&m_),exclusive(::boost::move(*source))
source(&m_),exclusive(move(*source))
{}
~upgrade_to_unique_lock()
{
if(source)
{
*source=upgrade_lock<Mutex>(::boost::move(exclusive));
*source=move(exclusive);
}
}
#ifndef BOOST_NO_RVALUE_REFERENCES
upgrade_to_unique_lock(upgrade_to_unique_lock<Mutex>&& other):
source(other.source),exclusive(::boost::move(other.exclusive))
source(other.source),exclusive(move(other.exclusive))
{
other.source=0;
}
@@ -1620,7 +1343,7 @@ namespace boost
#else
#if defined BOOST_THREAD_USES_MOVE
upgrade_to_unique_lock(boost::rv<upgrade_to_unique_lock<Mutex> >& other):
source(other.source),exclusive(::boost::move(other.exclusive))
source(other.source),exclusive(move(other.exclusive))
{
other.source=0;
}
@@ -1639,17 +1362,9 @@ namespace boost
{
return *static_cast<const ::boost::rv<upgrade_to_unique_lock>* >(this);
}
::boost::rv<upgrade_to_unique_lock>& move()
{
return *static_cast< ::boost::rv<upgrade_to_unique_lock>* >(this);
}
const ::boost::rv<upgrade_to_unique_lock>& move() const
{
return *static_cast<const ::boost::rv<upgrade_to_unique_lock>* >(this);
}
#else
upgrade_to_unique_lock(detail::thread_move_t<upgrade_to_unique_lock<Mutex> > other):
source(other->source),exclusive(::boost::move(other->exclusive))
source(other->source),exclusive(move(other->exclusive))
{
other->source=0;
}
@@ -1733,12 +1448,12 @@ namespace boost
{}
#ifndef BOOST_NO_RVALUE_REFERENCES
try_lock_wrapper(try_lock_wrapper&& other):
base(::boost::move(other))
base(move(other))
{}
try_lock_wrapper& operator=(try_lock_wrapper<Mutex>&& other)
{
try_lock_wrapper temp(::boost::move(other));
try_lock_wrapper temp(move(other));
swap(temp);
return *this;
}
@@ -1746,7 +1461,7 @@ namespace boost
#else
#if defined BOOST_THREAD_USES_MOVE
try_lock_wrapper(boost::rv<try_lock_wrapper<Mutex> >& other):
base(::boost::move(static_cast<base&>(other)))
base(boost::move(static_cast<base&>(other)))
{}
operator ::boost::rv<try_lock_wrapper>&()
@@ -1757,14 +1472,6 @@ namespace boost
{
return *static_cast<const ::boost::rv<try_lock_wrapper>* >(this);
}
::boost::rv<try_lock_wrapper>& move()
{
return *static_cast< ::boost::rv<try_lock_wrapper>* >(this);
}
const ::boost::rv<try_lock_wrapper>& move() const
{
return *static_cast<const ::boost::rv<try_lock_wrapper>* >(this);
}
try_lock_wrapper& operator=(boost::rv<try_lock_wrapper<Mutex> >& other)
{

View File

@@ -1,7 +1,6 @@
#ifndef BOOST_THREAD_PTHREAD_MUTEX_HPP
#define BOOST_THREAD_PTHREAD_MUTEX_HPP
// (C) Copyright 2007-8 Anthony Williams
// (C) Copyright 2011-2012 Vicente J. Botet Escriba
// 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)
@@ -98,7 +97,7 @@ namespace boost
// The following throw_exception has been replaced by an assertion and just return false,
// as this is an internal error and the user can do nothing with the exception.
//boost::throw_exception(lock_error(res,"boost: mutex try_lock failed in pthread_mutex_trylock"));
BOOST_ASSERT_MSG(false ,"boost: mutex try_lock failed in pthread_mutex_trylock");
BOOST_ASSERT(false && "boost: mutex try_lock failed in pthread_mutex_trylock");
return false;
}

View File

@@ -2,7 +2,6 @@
#define BOOST_THREAD_PTHREAD_SHARED_MUTEX_HPP
// (C) Copyright 2006-8 Anthony Williams
// (C) Copyright 2012 Vicente J. Botet Escriba
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
@@ -121,7 +120,18 @@ namespace boost
template <class Rep, class Period>
bool try_lock_shared_for(const chrono::duration<Rep, Period>& rel_time)
{
return try_lock_shared_until(chrono::steady_clock::now() + rel_time);
boost::this_thread::disable_interruption do_not_disturb;
boost::mutex::scoped_lock lk(state_change);
while(state.exclusive || state.exclusive_waiting_blocked)
{
if(cv_status::timeout==shared_cond.wait_for(lk,rel_time))
{
return false;
}
}
++state.shared_count;
return true;
}
template <class Clock, class Duration>
bool try_lock_shared_until(const chrono::time_point<Clock, Duration>& abs_time)
@@ -207,7 +217,25 @@ namespace boost
template <class Rep, class Period>
bool try_lock_for(const chrono::duration<Rep, Period>& rel_time)
{
return try_lock_until(chrono::steady_clock::now() + rel_time);
boost::this_thread::disable_interruption do_not_disturb;
boost::mutex::scoped_lock lk(state_change);
while(state.shared_count || state.exclusive)
{
state.exclusive_waiting_blocked=true;
if(cv_status::timeout == exclusive_cond.wait_for(lk,rel_time))
{
if(state.shared_count || state.exclusive)
{
state.exclusive_waiting_blocked=false;
release_waiters();
return false;
}
break;
}
}
state.exclusive=true;
return true;
}
template <class Clock, class Duration>
bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time)
@@ -300,7 +328,22 @@ namespace boost
template <class Rep, class Period>
bool try_lock_upgrade_for(const chrono::duration<Rep, Period>& rel_time)
{
return try_lock_upgrade_until(chrono::steady_clock::now() + rel_time);
boost::this_thread::disable_interruption do_not_disturb;
boost::mutex::scoped_lock lk(state_change);
while(state.exclusive || state.exclusive_waiting_blocked || state.upgrade)
{
if(cv_status::no_timeout == shared_cond.wait_for(lk,rel_time))
{
if(state.exclusive || state.exclusive_waiting_blocked || state.upgrade)
{
return false;
}
break;
}
}
++state.shared_count;
state.upgrade=true;
return true;
}
template <class Clock, class Duration>
bool try_lock_upgrade_until(const chrono::time_point<Clock, Duration>& abs_time)
@@ -309,7 +352,7 @@ namespace boost
boost::mutex::scoped_lock lk(state_change);
while(state.exclusive || state.exclusive_waiting_blocked || state.upgrade)
{
if(cv_status::timeout == shared_cond.wait_until(lk,abs_time))
if(cv_status::no_timeout == shared_cond.wait_until(lk,abs_time))
{
if(state.exclusive || state.exclusive_waiting_blocked || state.upgrade)
{
@@ -377,54 +420,16 @@ namespace boost
release_waiters();
}
bool try_unlock_upgrade_and_lock()
{
boost::mutex::scoped_lock lk(state_change);
if( !state.exclusive
&& !state.exclusive_waiting_blocked
&& state.upgrade
&& state.shared_count==1)
{
state.shared_count=0;
state.exclusive=true;
state.upgrade=false;
return true;
}
return false;
}
#ifdef BOOST_THREAD_USES_CHRONO
#if 0 // To be added
bool try_unlock_upgrade_and_lock();
template <class Rep, class Period>
bool
try_unlock_upgrade_and_lock_for(
const chrono::duration<Rep, Period>& rel_time)
{
return try_unlock_upgrade_and_lock_until(
chrono::steady_clock::now() + rel_time);
}
bool
try_unlock_upgrade_and_lock_for(
const chrono::duration<Rep, Period>& rel_time);
template <class Clock, class Duration>
bool
try_unlock_upgrade_and_lock_until(
const chrono::time_point<Clock, Duration>& abs_time)
{
boost::this_thread::disable_interruption do_not_disturb;
boost::mutex::scoped_lock lk(state_change);
if (state.shared_count != 1)
{
while (true)
{
cv_status status = shared_cond.wait_until(lk,abs_time);
if (state.shared_count == 1)
break;
if(status == cv_status::timeout)
return false;
}
}
state.upgrade=false;
state.exclusive=true;
state.exclusive_waiting_blocked=false;
state.shared_count=0;
return true;
}
bool
try_unlock_upgrade_and_lock_until(
const chrono::time_point<Clock, Duration>& abs_time);
#endif
// Shared <-> Exclusive
@@ -437,6 +442,18 @@ namespace boost
release_waiters();
}
#if 0 // To be added
bool try_unlock_shared_and_lock();
template <class Rep, class Period>
bool
try_unlock_shared_and_lock_for(
const chrono::duration<Rep, Period>& rel_time);
template <class Clock, class Duration>
bool
try_unlock_shared_and_lock_until(
const chrono::time_point<Clock, Duration>& abs_time);
#endif
// Shared <-> Upgrade
void unlock_upgrade_and_lock_shared()
{
@@ -446,9 +463,19 @@ namespace boost
release_waiters();
}
#if 0 // To be added
bool try_unlock_shared_and_lock_upgrade();
template <class Rep, class Period>
bool
try_unlock_shared_and_lock_upgrade_for(
const chrono::duration<Rep, Period>& rel_time);
template <class Clock, class Duration>
bool
try_unlock_shared_and_lock_upgrade_until(
const chrono::time_point<Clock, Duration>& abs_time);
#endif
};
typedef shared_mutex upgrade_mutex;
}
#include <boost/config/abi_suffix.hpp>

View File

@@ -145,7 +145,34 @@ namespace boost
}
return true;
}
bool try_lock_for(chrono::milliseconds const& rel_time)
{
if(try_lock())
{
return true;
}
long old_count=active_count;
mark_waiting_and_try_lock(old_count);
if(old_count&lock_flag_value)
{
bool lock_acquired=false;
void* const sem=get_event();
do
{
if(win32::WaitForSingleObject(sem,static_cast<unsigned long>(rel_time.count()))!=0)
{
BOOST_INTERLOCKED_DECREMENT(&active_count);
return false;
}
clear_waiting_and_try_lock(old_count);
lock_acquired=!(old_count&lock_flag_value);
}
while(!lock_acquired);
}
return true;
}
template<typename Duration>
bool timed_lock(Duration const& timeout)
@@ -158,56 +185,19 @@ namespace boost
return timed_lock(system_time(timeout));
}
template <class Rep, class Period>
bool try_lock_for(const chrono::duration<Rep, Period>& rel_time)
{
return try_lock_until(chrono::steady_clock::now() + rel_time);
}
template <class Clock, class Duration>
bool try_lock_until(const chrono::time_point<Clock, Duration>& t)
{
using namespace chrono;
system_clock::time_point s_now = system_clock::now();
typename Clock::time_point c_now = Clock::now();
return try_lock_until(s_now + ceil<system_clock::duration>(t - c_now));
}
template <class Duration>
bool try_lock_until(const chrono::time_point<chrono::system_clock, Duration>& t)
{
using namespace chrono;
typedef time_point<chrono::system_clock, chrono::system_clock::duration> sys_tmpt;
return try_lock_until(sys_tmpt(chrono::ceil<chrono::system_clock::duration>(t.time_since_epoch())));
}
bool try_lock_until(const chrono::time_point<chrono::system_clock, chrono::system_clock::duration>& tp)
{
if(try_lock())
{
return true;
}
long old_count=active_count;
mark_waiting_and_try_lock(old_count);
if(old_count&lock_flag_value)
{
bool lock_acquired=false;
void* const sem=get_event();
do
{
chrono::milliseconds rel_time= chrono::ceil<chrono::milliseconds>(tp-chrono::system_clock::now());
if(win32::WaitForSingleObject(sem,static_cast<unsigned long>(rel_time.count()))!=0)
{
BOOST_INTERLOCKED_DECREMENT(&active_count);
return false;
}
clear_waiting_and_try_lock(old_count);
lock_acquired=!(old_count&lock_flag_value);
}
while(!lock_acquired);
}
return true;
}
template <class Rep, class Period>
bool try_lock_for(const chrono::duration<Rep, Period>& rel_time)
{
using namespace chrono;
return try_lock_for(ceil<milliseconds>(rel_time));
}
template <class Clock, class Duration>
bool try_lock_until(const chrono::time_point<Clock, Duration>& t)
{
using namespace chrono;
typename Clock::time_point c_now = Clock::now();
return try_lock_for(ceil<milliseconds>(t - c_now));
}
void unlock()
{

View File

@@ -14,10 +14,6 @@
#include <limits.h>
#include <boost/utility.hpp>
#include <boost/thread/thread_time.hpp>
#ifdef BOOST_THREAD_USES_CHRONO
#include <boost/chrono/system_clocks.hpp>
#include <boost/chrono/ceil.hpp>
#endif
#include <boost/config/abi_prefix.hpp>
@@ -25,15 +21,9 @@ namespace boost
{
class shared_mutex
{
#ifndef BOOST_NO_DELETED_FUNCTIONS
public:
shared_mutex(shared_mutex const&) = delete;
shared_mutex& operator=(shared_mutex const&) = delete;
#else // BOOST_NO_DELETED_FUNCTIONS
private:
shared_mutex(shared_mutex const&);
shared_mutex& operator=(shared_mutex const&);
#endif // BOOST_NO_DELETED_FUNCTIONS
private:
struct state_data
{
@@ -228,113 +218,6 @@ namespace boost
}
}
template <class Rep, class Period>
bool try_lock_shared_for(const chrono::duration<Rep, Period>& rel_time)
{
return try_lock_shared_until(chrono::steady_clock::now() + rel_time);
}
template <class Clock, class Duration>
bool try_lock_shared_until(const chrono::time_point<Clock, Duration>& t)
{
using namespace chrono;
system_clock::time_point s_now = system_clock::now();
typename Clock::time_point c_now = Clock::now();
return try_lock_shared_until(s_now + ceil<system_clock::duration>(t - c_now));
}
template <class Duration>
bool try_lock_shared_until(const chrono::time_point<chrono::system_clock, Duration>& t)
{
using namespace chrono;
typedef time_point<chrono::system_clock, chrono::system_clock::duration> sys_tmpt;
return try_lock_shared_until(sys_tmpt(chrono::ceil<chrono::system_clock::duration>(t.time_since_epoch())));
}
bool try_lock_shared_until(const chrono::time_point<chrono::system_clock, chrono::system_clock::duration>& tp)
{
for(;;)
{
state_data old_state=state;
for(;;)
{
state_data new_state=old_state;
if(new_state.exclusive || new_state.exclusive_waiting_blocked)
{
++new_state.shared_waiting;
if(!new_state.shared_waiting)
{
boost::throw_exception(boost::lock_error());
}
}
else
{
++new_state.shared_count;
if(!new_state.shared_count)
{
boost::throw_exception(boost::lock_error());
}
}
state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
if(current_state==old_state)
{
break;
}
old_state=current_state;
}
if(!(old_state.exclusive| old_state.exclusive_waiting_blocked))
{
return true;
}
chrono::system_clock::time_point n = chrono::system_clock::now();
unsigned long res;
if (tp>n) {
chrono::milliseconds rel_time= chrono::ceil<chrono::milliseconds>(tp-n);
res=detail::win32::WaitForSingleObject(semaphores[unlock_sem],
static_cast<unsigned long>(rel_time.count()));
} else {
res=detail::win32::timeout;
}
if(res==detail::win32::timeout)
{
for(;;)
{
state_data new_state=old_state;
if(new_state.exclusive || new_state.exclusive_waiting_blocked)
{
if(new_state.shared_waiting)
{
--new_state.shared_waiting;
}
}
else
{
++new_state.shared_count;
if(!new_state.shared_count)
{
return false;
}
}
state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
if(current_state==old_state)
{
break;
}
old_state=current_state;
}
if(!(old_state.exclusive| old_state.exclusive_waiting_blocked))
{
return true;
}
return false;
}
BOOST_ASSERT(res==0);
}
}
void unlock_shared()
{
state_data old_state=state;
@@ -497,115 +380,6 @@ namespace boost
}
}
template <class Rep, class Period>
bool try_lock_for(const chrono::duration<Rep, Period>& rel_time)
{
return try_lock_until(chrono::steady_clock::now() + rel_time);
}
template <class Clock, class Duration>
bool try_lock_until(const chrono::time_point<Clock, Duration>& t)
{
using namespace chrono;
system_clock::time_point s_now = system_clock::now();
typename Clock::time_point c_now = Clock::now();
return try_lock_until(s_now + ceil<system_clock::duration>(t - c_now));
}
template <class Duration>
bool try_lock_until(const chrono::time_point<chrono::system_clock, Duration>& t)
{
using namespace chrono;
typedef time_point<chrono::system_clock, chrono::system_clock::duration> sys_tmpt;
return try_lock_until(sys_tmpt(chrono::ceil<chrono::system_clock::duration>(t.time_since_epoch())));
}
bool try_lock_until(const chrono::time_point<chrono::system_clock, chrono::system_clock::duration>& tp)
{
for(;;)
{
state_data old_state=state;
for(;;)
{
state_data new_state=old_state;
if(new_state.shared_count || new_state.exclusive)
{
++new_state.exclusive_waiting;
if(!new_state.exclusive_waiting)
{
boost::throw_exception(boost::lock_error());
}
new_state.exclusive_waiting_blocked=true;
}
else
{
new_state.exclusive=true;
}
state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
if(current_state==old_state)
{
break;
}
old_state=current_state;
}
if(!old_state.shared_count && !old_state.exclusive)
{
return true;
}
#ifndef UNDER_CE
const bool wait_all = true;
#else
const bool wait_all = false;
#endif
chrono::system_clock::time_point n = chrono::system_clock::now();
unsigned long wait_res;
if (tp>n) {
chrono::milliseconds rel_time= chrono::ceil<chrono::milliseconds>(tp-chrono::system_clock::now());
wait_res=detail::win32::WaitForMultipleObjects(2,semaphores,wait_all,
static_cast<unsigned long>(rel_time.count()));
} else {
wait_res=detail::win32::timeout;
}
if(wait_res==detail::win32::timeout)
{
for(;;)
{
state_data new_state=old_state;
if(new_state.shared_count || new_state.exclusive)
{
if(new_state.exclusive_waiting)
{
if(!--new_state.exclusive_waiting)
{
new_state.exclusive_waiting_blocked=false;
}
}
}
else
{
new_state.exclusive=true;
}
state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
if(current_state==old_state)
{
break;
}
old_state=current_state;
}
if(!old_state.shared_count && !old_state.exclusive)
{
return true;
}
return false;
}
BOOST_ASSERT(wait_res<2);
}
}
void unlock()
{
state_data old_state=state;
@@ -789,27 +563,6 @@ namespace boost
}
release_waiters(old_state);
}
// bool try_unlock_upgrade_and_lock()
// {
// return false;
// }
//#ifdef BOOST_THREAD_USES_CHRONO
// template <class Rep, class Period>
// bool
// try_unlock_upgrade_and_lock_for(
// const chrono::duration<Rep, Period>& rel_time)
// {
// return try_unlock_upgrade_and_lock_until(
// chrono::steady_clock::now() + rel_time);
// }
// template <class Clock, class Duration>
// bool
// try_unlock_upgrade_and_lock_until(
// const chrono::time_point<Clock, Duration>& abs_time)
// {
// return false;
// }
//#endif
void unlock_and_lock_shared()
{
@@ -835,6 +588,7 @@ namespace boost
}
release_waiters(old_state);
}
void unlock_upgrade_and_lock_shared()
{
state_data old_state=state;
@@ -860,8 +614,6 @@ namespace boost
}
};
typedef shared_mutex upgrade_mutex;
}
#include <boost/config/abi_suffix.hpp>

View File

@@ -53,4 +53,16 @@ namespace boost
return f;
}
future_error::future_error(system::error_code ec)
: logic_error(ec.message()),
ec_(ec)
{
}
// future_error::~future_error() //BOOST_NOEXCEPT
// {
// }
}

View File

@@ -319,9 +319,7 @@ namespace boost
}
#ifdef BOOST_THREAD_USES_CHRONO
bool thread::try_join_until(const chrono::time_point<chrono::system_clock, chrono::nanoseconds>& tp)
{
bool thread::do_try_join_for(chrono::milliseconds const &rel_time_in_milliseconds) {
if (this_thread::get_id() == get_id())
{
boost::throw_exception(thread_resource_error(system::errc::resource_deadlock_would_occur, "boost thread: trying joining itself"));
@@ -329,16 +327,15 @@ namespace boost
detail::thread_data_ptr local_thread_info=(get_thread_info)();
if(local_thread_info)
{
chrono::milliseconds rel_time= chrono::ceil<chrono::milliseconds>(tp-chrono::system_clock::now());
if(!this_thread::interruptible_wait(local_thread_info->thread_handle,rel_time.count()))
{
return false;
}
release_handle();
if(!this_thread::interruptible_wait(local_thread_info->thread_handle,rel_time_in_milliseconds.count()))
{
return false;
}
release_handle();
}
return true;
}
}
#endif
void thread::detach()

View File

@@ -35,10 +35,10 @@ rule thread-run ( sources )
rule thread-run2 ( sources : name )
{
return
[ run $(sources) ../build//boost_thread : : :
[ run $(sources) ../build//boost_thread : : :
: $(name) ]
[ run $(sources) ../src/tss_null.cpp ../build//boost_thread/<link>static
: : :
: : :
: $(name)_lib ]
;
}
@@ -48,7 +48,7 @@ rule thread-compile-fail-V2 ( sources : reqs * : name )
{
return
[ compile-fail $(sources)
: $(reqs)
: $(reqs)
: $(name) ]
;
}
@@ -78,11 +78,7 @@ rule thread-compile-fail-V2 ( sources : reqs * : name )
[ thread-run test_shared_mutex.cpp ]
[ thread-run test_shared_mutex_part_2.cpp ]
[ thread-run test_shared_mutex_timed_locks.cpp ]
[ thread-run test_shared_mutex_timed_locks_chrono.cpp ]
#uncomment the following once these works on windows
#[ thread-run test_v2_shared_mutex.cpp ]
#[ thread-run test_v2_shared_mutex_part_2.cpp ]
#[ thread-run test_v2_shared_mutex_timed_locks.cpp ]
#[ thread-run test_shared_mutex_timed_locks_chrono.cpp ]
[ thread-run test_lock_concept.cpp ]
[ thread-run test_generic_locks.cpp ]
[ thread-run test_futures.cpp ]
@@ -122,238 +118,163 @@ rule thread-compile-fail-V2 ( sources : reqs * : name )
#explicit conditions ;
test-suite conditions
:
[ thread-compile-fail-V2 ./sync/conditions/condition_variable/assign_fail.cpp : : condition_variable__assign_f ]
[ thread-compile-fail-V2 ./sync/conditions/condition_variable/copy_fail.cpp : : condition_variable__copy_f ]
[ thread-run2 ./sync/conditions/condition_variable/default_pass.cpp : condition_variable__default_p ]
[ thread-run2 ./sync/conditions/condition_variable/dtor_pass.cpp : condition_variable__dtor_p ]
[ thread-run2 ./sync/conditions/condition_variable/native_handle_pass.cpp : condition_variable__native_handle_p ]
[ thread-run2 ./sync/conditions/condition_variable/wait_for_pass.cpp : condition_variable__wait_for_p ]
[ thread-run2 ./sync/conditions/condition_variable/wait_for_pred_pass.cpp : condition_variable__wait_for_pred_p ]
[ thread-run2 ./sync/conditions/condition_variable/wait_until_pass.cpp : condition_variable__wait_until_p ]
[ thread-run2 ./sync/conditions/condition_variable/wait_until_pred_pass.cpp : condition_variable__wait_until_pred_p ]
[ thread-compile-fail-V2 ./sync/conditions/condition_variable/assign_fail.cpp : : conditions__condition_variable__assign_fail ]
[ thread-compile-fail-V2 ./sync/conditions/condition_variable/copy_fail.cpp : : conditions__condition_variable__copy_fail ]
[ thread-run2 ./sync/conditions/condition_variable/default_pass.cpp : conditions__condition_variable__default_pass ]
[ thread-run2 ./sync/conditions/condition_variable/dtor_pass.cpp : conditions__condition_variable__dtor_pass ]
[ thread-run2 ./sync/conditions/condition_variable/native_handle_pass.cpp : conditions__condition_variable__native_handle_pass ]
[ thread-run2 ./sync/conditions/condition_variable/wait_for_pass.cpp : conditions__condition_variable__wait_for_pass ]
[ thread-run2 ./sync/conditions/condition_variable/wait_for_pred_pass.cpp : conditions__condition_variable__wait_for_pred_pass ]
[ thread-run2 ./sync/conditions/condition_variable/wait_until_pass.cpp : conditions__condition_variable__wait_until_pass ]
[ thread-run2 ./sync/conditions/condition_variable/wait_until_pred_pass.cpp : conditions__condition_variable__wait_until_pred_pass ]
[ thread-compile-fail-V2 ./sync/conditions/condition_variable_any/assign_fail.cpp : : condition_variable_any__assign_f ]
[ thread-compile-fail-V2 ./sync/conditions/condition_variable_any/copy_fail.cpp : : condition_variable_any__copy_f ]
[ thread-run2 ./sync/conditions/condition_variable_any/default_pass.cpp : condition_variable_any__default_p ]
[ thread-run2 ./sync/conditions/condition_variable_any/dtor_pass.cpp : condition_variable_any__dtor_p ]
[ thread-run2 ./sync/conditions/condition_variable_any/wait_for_pass.cpp : condition_variable_any__wait_for_p ]
[ thread-run2 ./sync/conditions/condition_variable_any/wait_for_pred_pass.cpp : condition_variable_any__wait_for_pred_p ]
[ thread-run2 ./sync/conditions/condition_variable_any/wait_until_pass.cpp : condition_variable_any__wait_until_p ]
[ thread-run2 ./sync/conditions/condition_variable_any/wait_until_pred_pass.cpp : condition_variable_any__wait_until_pred_p ]
[ thread-run2 ./sync/conditions/cv_status/cv_status_pass.cpp : cv_status__cv_status_p ]
[ thread-compile-fail-V2 ./sync/conditions/condition_variable_any/assign_fail.cpp : : conditions__condition_variable_any__assign_fail ]
[ thread-compile-fail-V2 ./sync/conditions/condition_variable_any/copy_fail.cpp : : conditions__condition_variable_any__copy_fail ]
[ thread-run2 ./sync/conditions/condition_variable_any/default_pass.cpp : conditions__condition_variable_any__default_pass ]
[ thread-run2 ./sync/conditions/condition_variable_any/dtor_pass.cpp : conditions__condition_variable_any__dtor_pass ]
[ thread-run2 ./sync/conditions/condition_variable_any/wait_for_pass.cpp : conditions__condition_variable_any__wait_for_pass ]
[ thread-run2 ./sync/conditions/condition_variable_any/wait_for_pred_pass.cpp : conditions__condition_variable_any__wait_for_pred_pass ]
[ thread-run2 ./sync/conditions/condition_variable_any/wait_until_pass.cpp : conditions__condition_variable_any__wait_until_pass ]
[ thread-run2 ./sync/conditions/condition_variable_any/wait_until_pred_pass.cpp : conditions__condition_variable_any__wait_until_pred_pass ]
[ thread-run2 ./sync/conditions/cv_status/cv_status_pass.cpp : conditions__cv_status__cv_status_pass ]
;
#explicit futures ;
test-suite futures
:
# [ thread-run2 ./sync/futures/async/async_pass.cpp : async__async_p ]
[ thread-compile-fail-V2 ./sync/futures/promise/copy_assign_fail.cpp : : promise__copy_assign_f ]
[ thread-run2 ./sync/futures/promise/default_pass.cpp : promise__default_p ]
[ thread-run2 ./sync/futures/promise/dtor_pass.cpp : promise__dtor_p ]
[ thread-run2 ./sync/futures/promise/get_future_pass.cpp : promise__get_future_p ]
[ thread-run2 ./sync/futures/promise/move_ctor_pass.cpp : promise__move_ctor_p ]
[ thread-run2 ./sync/futures/promise/move_assign_pass.cpp : promise__move_asign_p ]
[ thread-run2 ./sync/futures/future/share_pass.cpp : future__share_p ]
# [ thread-run2 ./sync/futures/async/async_pass.cpp : futures__async__async_pass ]
[ thread-run2 ./sync/futures/promise/default_pass.cpp : futures__promise__default_pass ]
[ thread-run2 ./sync/futures/promise/dtor_pass.cpp : futures__promise__dtor_pass ]
[ thread-run2 ./sync/futures/promise/get_future_pass.cpp : futures__promise__get_future_pass ]
;
explicit tt ;
test-suite tt
:
[ thread-run2 ./sync/mutual_exclusion/locks/unique_lock/cons/try_to_lock_pass.cpp : xmutual_exclusion__locks__unique_lock__cons__try_to_lock_pass ]
;
#explicit mutual_exclusion ;
test-suite mutual_exclusion
:
#uncomment the following once these works on windows
[ thread-compile-fail-V2 ./sync/mutual_exclusion/locks/lock_guard/copy_assign_fail.cpp : : lock_guard__cons__copy_assign_f ]
[ thread-compile-fail-V2 ./sync/mutual_exclusion/locks/lock_guard/copy_ctor_fail.cpp : : lock_guard__cons__copy_ctor_f ]
[ thread-run2 ./sync/mutual_exclusion/locks/lock_guard/adopt_lock_pass.cpp : lock_guard__cons__adopt_lock_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/lock_guard/default_pass.cpp : lock_guard__cons__default_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/lock_guard/types_pass.cpp : lock_guard__types_p ]
[ thread-compile-fail-V2 ./sync/mutual_exclusion/locks/unique_lock/cons/copy_assign_fail.cpp : : unique_lock__cons__copy_assign_f ]
[ thread-compile-fail-V2 ./sync/mutual_exclusion/locks/unique_lock/cons/copy_ctor_fail.cpp : : unique_lock__cons__copy_ctor_f ]
[ thread-run2 ./sync/mutual_exclusion/locks/unique_lock/cons/adopt_lock_pass.cpp : unique_lock__cons__adopt_lock_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/unique_lock/cons/default_pass.cpp : unique_lock__cons__default_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/unique_lock/cons/defer_lock_pass.cpp : unique_lock__cons__defer_lock_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/unique_lock/cons/duration_pass.cpp : unique_lock__cons__duration_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/unique_lock/cons/move_assign_pass.cpp : unique_lock__cons__move_assign_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_pass.cpp : unique_lock__cons__move_ctor_p ]
[ thread-compile-fail-V2 ./sync/mutual_exclusion/locks/unique_lock/cons/copy_assign_fail.cpp : : mutual_exclusion__locks__unique_lock__cons__copy_assign_fail ]
[ thread-compile-fail-V2 ./sync/mutual_exclusion/locks/unique_lock/cons/copy_ctor_fail.cpp : : mutual_exclusion__locks__unique_lock__cons__copy_ctor_fail ]
[ thread-run2 ./sync/mutual_exclusion/locks/unique_lock/cons/adopt_lock_pass.cpp : mutual_exclusion__locks__unique_lock__cons__adopt_lock_pass ]
[ thread-run2 ./sync/mutual_exclusion/locks/unique_lock/cons/default_pass.cpp : mutual_exclusion__locks__unique_lock__cons__default_pass ]
[ thread-run2 ./sync/mutual_exclusion/locks/unique_lock/cons/defer_lock_pass.cpp : mutual_exclusion__locks__unique_lock__cons__defer_lock_pass ]
[ thread-run2 ./sync/mutual_exclusion/locks/unique_lock/cons/duration_pass.cpp : mutual_exclusion__locks__unique_lock__cons__duration_pass ]
[ thread-run2 ./sync/mutual_exclusion/locks/unique_lock/cons/move_assign_pass.cpp : mutual_exclusion__locks__unique_lock__cons__move_assign_pass ]
[ thread-run2 ./sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_pass.cpp : mutual_exclusion__locks__unique_lock__cons__move_ctor_pass ]
[ thread-run2 ./sync/mutual_exclusion/locks/unique_lock/cons/mutex_pass.cpp : mutual_exclusion__locks__unique_lock__cons__mutex_pass ]
[ thread-run2 ./sync/mutual_exclusion/locks/unique_lock/cons/time_point_pass.cpp : mutual_exclusion__locks__unique_lock__cons__time_point_pass ]
[ thread-run2 ./sync/mutual_exclusion/locks/unique_lock/cons/try_to_lock_pass.cpp : mutual_exclusion__locks__unique_lock__cons__try_to_lock_pass ]
[ thread-run2 ./sync/mutual_exclusion/locks/unique_lock/locking/lock_pass.cpp : mutual_exclusion__locks__unique_lock__locking__lock_pass ]
[ thread-run2 ./sync/mutual_exclusion/locks/unique_lock/locking/try_lock_for_pass.cpp : mutual_exclusion__locks__unique_lock__locking__try_lock_for_pass ]
[ thread-run2 ./sync/mutual_exclusion/locks/unique_lock/locking/try_lock_pass.cpp : mutual_exclusion__locks__unique_lock__locking__try_lock_pass ]
[ thread-run2 ./sync/mutual_exclusion/locks/unique_lock/locking/try_lock_until_pass.cpp : mutual_exclusion__locks__unique_lock__locking__try_lock_until_pass ]
[ thread-run2 ./sync/mutual_exclusion/locks/unique_lock/locking/unlock_pass.cpp : mutual_exclusion__locks__unique_lock__locking__unlock_pass ]
[ thread-run2 ./sync/mutual_exclusion/locks/unique_lock/mod/member_swap_pass.cpp : mutual_exclusion__locks__unique_lock__mod__member_swap_pass ]
[ thread-run2 ./sync/mutual_exclusion/locks/unique_lock/mod/non_member_swap_pass.cpp : mutual_exclusion__locks__unique_lock__mod__non_member_swap_pass ]
[ thread-run2 ./sync/mutual_exclusion/locks/unique_lock/mod/release_pass.cpp : mutual_exclusion__locks__unique_lock__mod__release_pass ]
[ thread-run2 ./sync/mutual_exclusion/locks/unique_lock/obs/mutex_pass.cpp : mutual_exclusion__locks__unique_lock__obs__mutex_pass ]
[ thread-run2 ./sync/mutual_exclusion/locks/unique_lock/obs/op_bool_pass.cpp : mutual_exclusion__locks__unique_lock__obs__op_bool_pass ]
[ thread-run2 ./sync/mutual_exclusion/locks/unique_lock/obs/owns_lock_pass.cpp : mutual_exclusion__locks__unique_lock__obs__owns_lock_pass ]
[ thread-run2 ./sync/mutual_exclusion/locks/unique_lock/types_pass.cpp : mutual_exclusion__locks__unique_lock__types_pass ]
#uncomment the following once these works on windows
[ thread-run2 ./sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_upgrade_lock_pass.cpp : unique_lock__cons__move_ctor_upgrade_lock_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_upgrade_lock_try_pass.cpp : unique_lock__cons__move_ctor_upgrade_lock_try_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_upgrade_lock_for_pass.cpp : unique_lock__cons__move_ctor_upgrade_lock_for_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_upgrade_lock_until_pass.cpp : unique_lock__cons__move_ctor_upgrade_lock_until_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/unique_lock/cons/mutex_pass.cpp : unique_lock__cons__mutex_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/unique_lock/cons/time_point_pass.cpp : unique_lock__cons__time_point_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/unique_lock/cons/try_to_lock_pass.cpp : unique_lock__cons__try_to_lock_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/unique_lock/locking/lock_pass.cpp : unique_lock__lock_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/unique_lock/locking/try_lock_for_pass.cpp : unique_lock__try_lock_for_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/unique_lock/locking/try_lock_pass.cpp : unique_lock__try_lock_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/unique_lock/locking/try_lock_until_pass.cpp : unique_lock__try_lock_until_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/unique_lock/locking/unlock_pass.cpp : unique_lock__unlock_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/unique_lock/mod/member_swap_pass.cpp : unique_lock__member_swap_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/unique_lock/mod/non_member_swap_pass.cpp : unique_lock__non_member_swap_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/unique_lock/mod/release_pass.cpp : unique_lock__release_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/unique_lock/obs/mutex_pass.cpp : unique_lock__mutex_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/unique_lock/obs/op_bool_pass.cpp : unique_lock__op_bool_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/unique_lock/obs/owns_lock_pass.cpp : unique_lock__owns_lock_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/unique_lock/types_pass.cpp : unique_lock__types_p ]
#[ thread-compile-fail-V2 ./sync/mutual_exclusion/locks/shared_lock/cons/copy_assign_fail.cpp : : mutual_exclusion__locks__shared_lock__cons__copy_assign_fail ]
#[ thread-compile-fail-V2 ./sync/mutual_exclusion/locks/shared_lock/cons/copy_ctor_fail.cpp : : mutual_exclusion__locks__shared_lock__cons__copy_ctor_fail ]
#[ thread-run2 ./sync/mutual_exclusion/locks/shared_lock/cons/adopt_lock_pass.cpp : mutual_exclusion__locks__shared_lock__cons__adopt_lock_pass ]
#[ thread-run2 ./sync/mutual_exclusion/locks/shared_lock/cons/default_pass.cpp : mutual_exclusion__locks__shared_lock__cons__default_pass ]
#[ thread-run2 ./sync/mutual_exclusion/locks/shared_lock/cons/defer_lock_pass.cpp : mutual_exclusion__locks__shared_lock__cons__defer_lock_pass ]
#[ thread-run2 ./sync/mutual_exclusion/locks/shared_lock/cons/duration_pass.cpp : mutual_exclusion__locks__shared_lock__cons__duration_pass ]
#[ thread-run2 ./sync/mutual_exclusion/locks/shared_lock/cons/move_assign_pass.cpp : mutual_exclusion__locks__shared_lock__cons__move_assign_pass ]
#[ thread-run2 ./sync/mutual_exclusion/locks/shared_lock/cons/move_ctor_pass.cpp : mutual_exclusion__locks__shared_lock__cons__move_ctor_pass ]
#[ thread-run2 ./sync/mutual_exclusion/locks/shared_lock/cons/mutex_pass.cpp : mutual_exclusion__locks__shared_lock__cons__mutex_pass ]
#[ thread-run2 ./sync/mutual_exclusion/locks/shared_lock/cons/time_point_pass.cpp : mutual_exclusion__locks__shared_lock__cons__time_point_pass ]
#[ thread-run2 ./sync/mutual_exclusion/locks/shared_lock/cons/try_to_lock_pass.cpp : mutual_exclusion__locks__shared_lock__cons__try_to_lock_pass ]
#[ thread-run2 ./sync/mutual_exclusion/locks/shared_lock/locking/lock_pass.cpp : mutual_exclusion__locks__shared_lock__locking__lock_pass ]
#[ thread-run2 ./sync/mutual_exclusion/locks/shared_lock/locking/try_lock_for_pass.cpp : mutual_exclusion__locks__shared_lock__locking__try_lock_for_pass ]
#[ thread-run2 ./sync/mutual_exclusion/locks/shared_lock/locking/try_lock_pass.cpp : mutual_exclusion__locks__shared_lock__locking__try_lock_pass ]
#[ thread-run2 ./sync/mutual_exclusion/locks/shared_lock/locking/try_lock_until_pass.cpp : mutual_exclusion__locks__shared_lock__locking__try_lock_until_pass ]
#[ thread-run2 ./sync/mutual_exclusion/locks/shared_lock/locking/unlock_pass.cpp : mutual_exclusion__locks__shared_lock__locking__unlock_pass ]
#[ thread-run2 ./sync/mutual_exclusion/locks/shared_lock/mod/member_swap_pass.cpp : mutual_exclusion__locks__shared_lock__mod__member_swap_pass ]
#[ thread-run2 ./sync/mutual_exclusion/locks/shared_lock/mod/non_member_swap_pass.cpp : mutual_exclusion__locks__shared_lock__mod__non_member_swap_pass ]
#[ thread-run2 ./sync/mutual_exclusion/locks/shared_lock/mod/release_pass.cpp : mutual_exclusion__locks__shared_lock__mod__release_pass ]
#[ thread-run2 ./sync/mutual_exclusion/locks/shared_lock/obs/mutex_pass.cpp : mutual_exclusion__locks__shared_lock__obs__mutex_pass ]
#[ thread-run2 ./sync/mutual_exclusion/locks/shared_lock/obs/op_bool_pass.cpp : mutual_exclusion__locks__shared_lock__obs__op_bool_pass ]
#[ thread-run2 ./sync/mutual_exclusion/locks/shared_lock/obs/owns_lock_pass.cpp : mutual_exclusion__locks__shared_lock__obs__owns_lock_pass ]
[ thread-compile-fail-V2 ./sync/mutual_exclusion/locks/shared_lock/cons/copy_assign_fail.cpp : : shared_lock__cons__copy_assign_f ]
[ thread-compile-fail-V2 ./sync/mutual_exclusion/locks/shared_lock/cons/copy_ctor_fail.cpp : : shared_lock__cons__copy_ctor_f ]
[ thread-run2 ./sync/mutual_exclusion/locks/shared_lock/cons/adopt_lock_pass.cpp : shared_lock__cons__adopt_lock_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/shared_lock/cons/default_pass.cpp : shared_lock__cons__default_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/shared_lock/cons/defer_lock_pass.cpp : shared_lock__cons__defer_lock_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/shared_lock/cons/duration_pass.cpp : shared_lock__cons__duration_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/shared_lock/cons/move_assign_pass.cpp : shared_lock__cons__move_assign_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/shared_lock/cons/move_ctor_pass.cpp : shared_lock__cons__move_ctor_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/shared_lock/cons/move_ctor_unique_lock_pass.cpp : shared_lock__cons__move_ctor_unique_lock_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/shared_lock/cons/move_ctor_upgrade_lock_pass.cpp : shared_lock__cons__move_ctor_upgrade_lock_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/shared_lock/cons/mutex_pass.cpp : shared_lock__cons__mutex_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/shared_lock/cons/time_point_pass.cpp : shared_lock__cons__time_point_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/shared_lock/cons/try_to_lock_pass.cpp : shared_lock__cons__try_to_lock_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/shared_lock/locking/lock_pass.cpp : shared_lock__lock_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/shared_lock/locking/try_lock_for_pass.cpp : shared_lock__try_lock_for_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/shared_lock/locking/try_lock_pass.cpp : shared_lock__try_lock_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/shared_lock/locking/try_lock_until_pass.cpp : shared_lock__try_lock_until_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/shared_lock/locking/unlock_pass.cpp : shared_lock__unlock_p ]
[ thread-compile-fail-V2 ./sync/mutual_exclusion/mutex/assign_fail.cpp : : mutual_exclusion__mutex__assign_fail ]
[ thread-compile-fail-V2 ./sync/mutual_exclusion/mutex/copy_fail.cpp : : mutual_exclusion__mutex__copy_fail ]
[ thread-run2 ./sync/mutual_exclusion/mutex/default_pass.cpp : mutual_exclusion__mutex__default_pass ]
[ thread-run2 ./sync/mutual_exclusion/mutex/lock_pass.cpp : mutual_exclusion__mutex__lock_pass ]
[ thread-run2 ./sync/mutual_exclusion/mutex/native_handle_pass.cpp : mutual_exclusion__mutex__native_handle_pass ]
[ thread-run2 ./sync/mutual_exclusion/mutex/try_lock_pass.cpp : mutual_exclusion__mutex__try_lock_pass ]
[ thread-compile-fail-V2 ./sync/mutual_exclusion/recursive_mutex/assign_fail.cpp : : mutual_exclusion__recursive_mutex__assign_fail ]
[ thread-compile-fail-V2 ./sync/mutual_exclusion/recursive_mutex/copy_fail.cpp : : mutual_exclusion__recursive_mutex__copy_fail ]
[ thread-run2 ./sync/mutual_exclusion/recursive_mutex/default_pass.cpp : mutual_exclusion__recursive_mutex__default_pass ]
[ thread-run2 ./sync/mutual_exclusion/recursive_mutex/lock_pass.cpp : mutual_exclusion__recursive_mutex__lock_pass ]
[ thread-run2 ./sync/mutual_exclusion/recursive_mutex/native_handle_pass.cpp : mutual_exclusion__recursive_mutex__native_handle_pass ]
[ thread-run2 ./sync/mutual_exclusion/recursive_mutex/try_lock_pass.cpp : mutual_exclusion__recursive_mutex__try_lock_pass ]
[ thread-run2 ./sync/mutual_exclusion/locks/shared_lock/mod/member_swap_pass.cpp : shared_lock__member_swap_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/shared_lock/mod/non_member_swap_pass.cpp : shared_lock__non_member_swap_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/shared_lock/mod/release_pass.cpp : shared_lock__release_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/shared_lock/obs/mutex_pass.cpp : shared_lock__mutex_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/shared_lock/obs/op_bool_pass.cpp : shared_lock__op_bool_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/shared_lock/obs/owns_lock_pass.cpp : shared_lock__owns_lock_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/shared_lock/types_pass.cpp : shared_lock__types_p ]
[ thread-compile-fail-V2 ./sync/mutual_exclusion/recursive_timed_mutex/assign_fail.cpp : : mutual_exclusion__recursive_timed_mutex__assign_fail ]
[ thread-compile-fail-V2 ./sync/mutual_exclusion/recursive_timed_mutex/copy_fail.cpp : : mutual_exclusion__recursive_timed_mutex__copy_fail ]
[ thread-run2 ./sync/mutual_exclusion/recursive_timed_mutex/default_pass.cpp : mutual_exclusion__recursive_timed_mutex__default_pass ]
[ thread-run2 ./sync/mutual_exclusion/recursive_timed_mutex/lock_pass.cpp : mutual_exclusion__recursive_timed_mutex__lock_pass ]
[ thread-run2 ./sync/mutual_exclusion/recursive_timed_mutex/native_handle_pass.cpp : mutual_exclusion__recursive_timed_mutex__native_handle_pass ]
[ thread-run2 ./sync/mutual_exclusion/recursive_timed_mutex/try_lock_for_pass.cpp : mutual_exclusion__recursive_timed_mutex__try_lock_for_pass ]
[ thread-run2 ./sync/mutual_exclusion/recursive_timed_mutex/try_lock_pass.cpp : mutual_exclusion__recursive_timed_mutex__try_lock_pass ]
[ thread-run2 ./sync/mutual_exclusion/recursive_timed_mutex/try_lock_until_pass.cpp : mutual_exclusion__recursive_timed_mutex__try_lock_until_pass ]
[ thread-compile-fail-V2 ./sync/mutual_exclusion/locks/upgrade_lock/cons/copy_assign_fail.cpp : : upgrade_lock__cons__copy_assign_f ]
[ thread-compile-fail-V2 ./sync/mutual_exclusion/locks/upgrade_lock/cons/copy_ctor_fail.cpp : : upgrade_lock__cons__copy_ctor_f ]
[ thread-run2 ./sync/mutual_exclusion/locks/upgrade_lock/cons/adopt_lock_pass.cpp : upgrade_lock__cons__adopt_lock_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/upgrade_lock/cons/default_pass.cpp : upgrade_lock__cons__default_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/upgrade_lock/cons/defer_lock_pass.cpp : upgrade_lock__cons__defer_lock_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/upgrade_lock/cons/duration_pass.cpp : upgrade_lock__cons__duration_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/upgrade_lock/cons/move_assign_pass.cpp : upgrade_lock__cons__move_assign_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/upgrade_lock/cons/move_ctor_pass.cpp : upgrade_lock__cons__move_ctor_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/upgrade_lock/cons/move_ctor_unique_lock_pass.cpp : upgrade_lock__cons__move_ctor_unique_lock_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/upgrade_lock/cons/mutex_pass.cpp : upgrade_lock__cons__mutex_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/upgrade_lock/cons/time_point_pass.cpp : upgrade_lock__cons__time_point_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/upgrade_lock/cons/try_to_lock_pass.cpp : upgrade_lock__cons__try_to_lock_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/upgrade_lock/locking/lock_pass.cpp : upgrade_lock__lock_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/upgrade_lock/locking/try_lock_for_pass.cpp : upgrade_lock__try_lock_for_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/upgrade_lock/locking/try_lock_pass.cpp : upgrade_lock__try_lock_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/upgrade_lock/locking/try_lock_until_pass.cpp : upgrade_lock__try_lock_until_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/upgrade_lock/locking/unlock_pass.cpp : upgrade_lock__unlock_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/upgrade_lock/mod/member_swap_pass.cpp : upgrade_lock__member_swap_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/upgrade_lock/mod/non_member_swap_pass.cpp : upgrade_lock__non_member_swap_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/upgrade_lock/mod/release_pass.cpp : upgrade_lock__release_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/upgrade_lock/obs/mutex_pass.cpp : upgrade_lock__mutex_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/upgrade_lock/obs/op_bool_pass.cpp : upgrade_lock__op_bool_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/upgrade_lock/obs/owns_lock_pass.cpp : upgrade_lock__owns_lock_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/upgrade_lock/types_pass.cpp : upgrade_lock__types_p ]
[ thread-compile-fail-V2 ./sync/mutual_exclusion/timed_mutex/assign_fail.cpp : : mutual_exclusion__timed_mutex__assign_fail ]
[ thread-compile-fail-V2 ./sync/mutual_exclusion/timed_mutex/copy_fail.cpp : : mutual_exclusion__timed_mutex__copy_fail ]
[ thread-run2 ./sync/mutual_exclusion/timed_mutex/default_pass.cpp : mutual_exclusion__timed_mutex__default_pass ]
[ thread-run2 ./sync/mutual_exclusion/timed_mutex/lock_pass.cpp : mutual_exclusion__timed_mutex__lock_pass ]
[ thread-run2 ./sync/mutual_exclusion/timed_mutex/native_handle_pass.cpp : mutual_exclusion__timed_mutex__native_handle_pass ]
[ thread-run2 ./sync/mutual_exclusion/timed_mutex/try_lock_for_pass.cpp : mutual_exclusion__timed_mutex__try_lock_for_pass ]
[ thread-run2 ./sync/mutual_exclusion/timed_mutex/try_lock_pass.cpp : mutual_exclusion__timed_mutex__try_lock_pass ]
[ thread-run2 ./sync/mutual_exclusion/timed_mutex/try_lock_until_pass.cpp : mutual_exclusion__timed_mutex__try_lock_until_pass ]
[ thread-compile-fail-V2 ./sync/mutual_exclusion/mutex/assign_fail.cpp : : mutex__assign_f ]
[ thread-compile-fail-V2 ./sync/mutual_exclusion/mutex/copy_fail.cpp : : mutex__copy_f ]
[ thread-run2 ./sync/mutual_exclusion/mutex/default_pass.cpp : mutex__default_p ]
[ thread-run2 ./sync/mutual_exclusion/mutex/lock_pass.cpp : mutex__lock_p ]
[ thread-run2 ./sync/mutual_exclusion/mutex/native_handle_pass.cpp : mutex__native_handle_p ]
[ thread-run2 ./sync/mutual_exclusion/mutex/try_lock_pass.cpp : mutex__try_lock_p ]
[ thread-compile-fail-V2 ./sync/mutual_exclusion/recursive_mutex/assign_fail.cpp : : recursive_mutex__assign_f ]
[ thread-compile-fail-V2 ./sync/mutual_exclusion/recursive_mutex/copy_fail.cpp : : recursive_mutex__copy_f ]
[ thread-run2 ./sync/mutual_exclusion/recursive_mutex/default_pass.cpp : recursive_mutex__default_p ]
[ thread-run2 ./sync/mutual_exclusion/recursive_mutex/lock_pass.cpp : recursive_mutex__lock_p ]
[ thread-run2 ./sync/mutual_exclusion/recursive_mutex/native_handle_pass.cpp : recursive_mutex__native_handle_p ]
[ thread-run2 ./sync/mutual_exclusion/recursive_mutex/try_lock_pass.cpp : recursive_mutex__try_lock_p ]
[ thread-compile-fail-V2 ./sync/mutual_exclusion/recursive_timed_mutex/assign_fail.cpp : : recursive_timed_mutex__assign_f ]
[ thread-compile-fail-V2 ./sync/mutual_exclusion/recursive_timed_mutex/copy_fail.cpp : : recursive_timed_mutex__copy_f ]
[ thread-run2 ./sync/mutual_exclusion/recursive_timed_mutex/default_pass.cpp : recursive_timed_mutex__default_p ]
[ thread-run2 ./sync/mutual_exclusion/recursive_timed_mutex/lock_pass.cpp : recursive_timed_mutex__lock_p ]
[ thread-run2 ./sync/mutual_exclusion/recursive_timed_mutex/native_handle_pass.cpp : recursive_timed_mutex__native_handle_p ]
[ thread-run2 ./sync/mutual_exclusion/recursive_timed_mutex/try_lock_for_pass.cpp : recursive_timed_mutex__try_lock_for_p ]
[ thread-run2 ./sync/mutual_exclusion/recursive_timed_mutex/try_lock_pass.cpp : recursive_timed_mutex__try_lock_p ]
[ thread-run2 ./sync/mutual_exclusion/recursive_timed_mutex/try_lock_until_pass.cpp : recursive_timed_mutex__try_lock_until_p ]
[ thread-compile-fail-V2 ./sync/mutual_exclusion/timed_mutex/assign_fail.cpp : : timed_mutex__assign_f ]
[ thread-compile-fail-V2 ./sync/mutual_exclusion/timed_mutex/copy_fail.cpp : : timed_mutex__copy_f ]
[ thread-run2 ./sync/mutual_exclusion/timed_mutex/default_pass.cpp : timed_mutex__default_p ]
[ thread-run2 ./sync/mutual_exclusion/timed_mutex/lock_pass.cpp : timed_mutex__lock_p ]
[ thread-run2 ./sync/mutual_exclusion/timed_mutex/native_handle_pass.cpp : timed_mutex__native_handle_p ]
[ thread-run2 ./sync/mutual_exclusion/timed_mutex/try_lock_for_pass.cpp : timed_mutex__try_lock_for_p ]
[ thread-run2 ./sync/mutual_exclusion/timed_mutex/try_lock_pass.cpp : timed_mutex__try_lock_p ]
[ thread-run2 ./sync/mutual_exclusion/timed_mutex/try_lock_until_pass.cpp : timed_mutex__try_lock_until_p ]
[ thread-compile-fail-V2 ./sync/mutual_exclusion/shared_mutex/assign_fail.cpp : : shared_mutex__assign_f ]
[ thread-compile-fail-V2 ./sync/mutual_exclusion/shared_mutex/copy_fail.cpp : : shared_mutex__copy_f ]
[ thread-run2 ./sync/mutual_exclusion/shared_mutex/default_pass.cpp : shared_mutex__default_p ]
[ thread-run2 ./sync/mutual_exclusion/shared_mutex/lock_pass.cpp : shared_mutex__lock_p ]
[ thread-run2 ./sync/mutual_exclusion/shared_mutex/try_lock_for_pass.cpp : shared_mutex__try_lock_for_p ]
[ thread-run2 ./sync/mutual_exclusion/shared_mutex/try_lock_pass.cpp : shared_mutex__try_lock_p ]
[ thread-run2 ./sync/mutual_exclusion/shared_mutex/try_lock_until_pass.cpp : shared_mutex__try_lock_until_p ]
[ thread-compile-fail-V2 ./sync/mutual_exclusion/shared_mutex/assign_fail.cpp : : mutual_exclusion__shared_mutex__assign_fail ]
[ thread-compile-fail-V2 ./sync/mutual_exclusion/shared_mutex/copy_fail.cpp : : mutual_exclusion__shared_mutex__copy_fail ]
[ thread-run2 ./sync/mutual_exclusion/shared_mutex/default_pass.cpp : mutual_exclusion__shared_mutex__default_pass ]
[ thread-run2 ./sync/mutual_exclusion/shared_mutex/lock_pass.cpp : mutual_exclusion__shared_mutex__lock_pass ]
#[ thread-run2 ./sync/mutual_exclusion/shared_mutex/try_lock_for_pass.cpp : mutual_exclusion__shared_mutex__try_lock_for_pass ]
[ thread-run2 ./sync/mutual_exclusion/shared_mutex/try_lock_pass.cpp : mutual_exclusion__shared_mutex__try_lock_pass ]
#[ thread-run2 ./sync/mutual_exclusion/shared_mutex/try_lock_until_pass.cpp : mutual_exclusion__shared_mutex__try_lock_until_pass ]
;
#explicit this_thread ;
test-suite this_thread
:
[ thread-run2 ./threads/this_thread/get_id/get_id_pass.cpp : this_thread__get_id_p ]
[ thread-run2 ./threads/this_thread/sleep_for/sleep_for_pass.cpp : this_thread__sleep_for_p ]
[ thread-run2 ./threads/this_thread/sleep_until/sleep_until_pass.cpp : this_thread__sleep_until_p ]
[ thread-run2 ./threads/this_thread/get_id/get_id_pass.cpp : this_thread__get_id__get_id_pass ]
[ thread-run2 ./threads/this_thread/sleep_for/sleep_for_pass.cpp : this_thread__sleep_for__sleep_for_pass ]
[ thread-run2 ./threads/this_thread/sleep_until/sleep_until_pass.cpp : this_thread__sleep_until__sleep_until_pass ]
;
#explicit thread ;
test-suite thread
:
[ thread-compile-fail-V2 ./threads/thread/assign/copy_fail.cpp : : thread__assign__copy_f ]
[ thread-run2 ./threads/thread/assign/move_pass.cpp : thread__assign__move_p ]
[ thread-compile-fail-V2 ./threads/thread/constr/copy_fail.cpp : : thread__constr__copy_f ]
[ thread-run2 ./threads/thread/constr/default_pass.cpp : thread__constr__default_p ]
[ thread-run2 ./threads/thread/constr/F_pass.cpp : thread__constr__F_p ]
[ thread-run2 ./threads/thread/constr/Frvalue_pass.cpp : thread__constr__Frvalue_p ]
#[ thread-run2 ./threads/thread/constr/FrvalueArgs_pass.cpp : thread__constr__FrvalueArgs_p ]
[ thread-run2 ./threads/thread/constr/move_pass.cpp : thread__constr__move_p ]
[ thread-run2 ./threads/thread/destr/dtor_pass.cpp : thread__destr__dtor_p ]
[ thread-run2 ./threads/thread/id/hash_pass.cpp : thread__id__hash_p ]
[ thread-run2 ./threads/thread/members/detach_pass.cpp : thread__detach_p ]
[ thread-run2 ./threads/thread/members/get_id_pass.cpp : thread__get_id_p ]
[ thread-run2 ./threads/thread/members/join_pass.cpp : thread__join_p ]
[ thread-run2 ./threads/thread/members/joinable_pass.cpp : thread__joinable_p ]
[ thread-run2 ./threads/thread/members/native_handle_pass.cpp : thread__native_handle_p ]
[ thread-run2 ./threads/thread/members/swap_pass.cpp : thread__swap_p ]
[ thread-run2 ./threads/thread/non_members/swap_pass.cpp : swap_threads_p ]
[ thread-run2 ./threads/thread/static/hardware_concurrency_pass.cpp : thread__hardware_concurrency_p ]
[ thread-compile-fail-V2 ./threads/thread/assign/copy_fail.cpp : : thread__assign__copy_fail ]
[ thread-run2 ./threads/thread/assign/move_pass.cpp : thread__assign__move_pass ]
[ thread-compile-fail-V2 ./threads/thread/constr/copy_fail.cpp : : thread__constr__copy_fail ]
[ thread-run2 ./threads/thread/constr/default_pass.cpp : thread__constr__default_pass ]
[ thread-run2 ./threads/thread/constr/F_pass.cpp : thread__constr__F_pass ]
[ thread-run2 ./threads/thread/constr/Frvalue_pass.cpp : thread__constr__Frvalue_pass ]
#[ thread-run2 ./threads/thread/constr/FrvalueArgs_pass.cpp : thread__constr__FrvalueArgs_pass ]
[ thread-run2 ./threads/thread/constr/move_pass.cpp : thread__constr__move_pass ]
[ thread-run2 ./threads/thread/destr/dtor_pass.cpp : thread__destr__dtor_pass ]
[ thread-run2 ./threads/thread/id/hash_pass.cpp : thread__id__hash_pass ]
[ thread-run2 ./threads/thread/members/detach_pass.cpp : thread__members__detach_pass ]
[ thread-run2 ./threads/thread/members/get_id_pass.cpp : thread__members__get_id_pass ]
[ thread-run2 ./threads/thread/members/join_pass.cpp : thread__members__join_pass ]
[ thread-run2 ./threads/thread/members/joinable_pass.cpp : thread__members__joinable_pass ]
[ thread-run2 ./threads/thread/members/native_handle_pass.cpp : thread__members__native_handle_pass ]
[ thread-run2 ./threads/thread/members/swap_pass.cpp : thread__members__swap_pass ]
[ thread-run2 ./threads/thread/non_members/swap_pass.cpp : thread__non_members__swap_pass ]
[ thread-run2 ./threads/thread/static/hardware_concurrency_pass.cpp : thread__static__hardware_concurrency_pass ]
;
explicit examples ;
test-suite examples
:
[ thread-run ../example/monitor.cpp ]
#[ thread-run ../example/starvephil.cpp ]
#[ thread-run ../example/tennis.cpp ]
#[ thread-run ../example/condition.cpp ]
[ thread-run ../example/mutex.cpp ]
[ thread-run ../example/once.cpp ]
[ thread-run ../example/recursive_mutex.cpp ]
[ thread-run2 ../example/thread.cpp : ex_thread ]
[ thread-run ../example/thread_group.cpp ]
[ thread-run ../example/tss.cpp ]
[ thread-run ../example/xtime.cpp ]
[ thread-run ../example/shared_monitor.cpp ]
#[ thread-run ../example/shared_mutex.cpp ]
#[ thread-run ../example/v2_shared_monitor.cpp ]
#[ thread-run ../example/v2_shared_mutex.cpp ]
;
#explicit shared_upwards ;
#test-suite shared_upwards
#:
# [ thread-run2 ./sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_shared_lock_try_pass.cpp : unique_lock__cons__move_ctor_shared_lock_try_p ]
# [ thread-run2 ./sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_shared_lock_for_pass.cpp : unique_lock__cons__move_ctor_shared_lock_for_p ]
# [ thread-run2 ./sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_shared_lock_until_pass.cpp : unique_lock__cons__move_ctor_shared_lock_until_p ]
#
# [ thread-run2 ./sync/mutual_exclusion/locks/upgrade_lock/cons/move_ctor_shared_lock_try_pass.cpp : upgrade_lock__cons__move_ctor_shared_lock_try_p ]
# [ thread-run2 ./sync/mutual_exclusion/locks/upgrade_lock/cons/move_ctor_shared_lock_for_pass.cpp : upgrade_lock__cons__move_ctor_shared_lock_for_p ]
# [ thread-run2 ./sync/mutual_exclusion/locks/upgrade_lock/cons/move_ctor_shared_lock_until_pass.cpp : upgrade_lock__cons__move_ctor_shared_lock_until_p ]
#;
}

View File

@@ -1,84 +0,0 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// Copyright (C) 2011 Vicente J. Botet Escriba
//
// 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)
// <boost/thread/future.hpp>
// class future<R>
// shared_future<R> share() &&;
#define BOOST_THREAD_VERSION 2
#include <boost/thread/future.hpp>
#include <boost/detail/lightweight_test.hpp>
int main()
{
{
typedef int T;
boost::promise<T> p;
boost::future<T> f0 = p.get_future();
boost::shared_future<T> sf = f0.share();
boost::shared_future<T> f = sf;
BOOST_TEST(!f0.valid());
BOOST_TEST(f.valid());
}
{
typedef int T;
boost::future<T> f0;
boost::shared_future<T> sf = f0.share();
boost::shared_future<T> f = sf;
BOOST_TEST(!f0.valid());
BOOST_TEST(!f.valid());
}
{
typedef int& T;
boost::promise<T> p;
boost::future<T> f0 = p.get_future();
boost::shared_future<T> sf = f0.share();
boost::shared_future<T> f = sf;
BOOST_TEST(!f0.valid());
BOOST_TEST(f.valid());
}
{
typedef int& T;
boost::future<T> f0;
boost::shared_future<T> sf = f0.share();
boost::shared_future<T> f = sf;
BOOST_TEST(!f0.valid());
BOOST_TEST(!f.valid());
}
{
typedef void T;
boost::promise<T> p;
boost::future<T> f0 = p.get_future();
boost::shared_future<T> sf = f0.share();
boost::shared_future<T> f = sf;
BOOST_TEST(!f0.valid());
BOOST_TEST(f.valid());
}
{
typedef void T;
boost::future<T> f0;
boost::shared_future<T> sf = f0.share();
boost::shared_future<T> f = sf;
BOOST_TEST(!f0.valid());
BOOST_TEST(!f.valid());
}
return boost::report_errors();
}

View File

@@ -12,25 +12,30 @@
// 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)
// <boost/thread/locks.hpp>
// <boost/thread/future.hpp>
// template <class Mutex> class upgrade_lock;
// upgrade_lock(mutex_type& m, adopt_lock_t);
#include <boost/thread/locks.hpp>
#include <boost/thread/shared_mutex.hpp>
#include <boost/thread/future.hpp>
#include <boost/detail/lightweight_test.hpp>
int main()
{
boost::shared_mutex m;
m.lock();
boost::upgrade_lock<boost::shared_mutex> lk(m, boost::adopt_lock);
BOOST_TEST(lk.mutex() == &m);
BOOST_TEST(lk.owns_lock() == true);
{
boost::promise<int> p;
boost::future<int> f = p.get_future();
BOOST_TEST(f.valid());
}
{
boost::promise<int&> p;
boost::future<int&> f = p.get_future();
BOOST_TEST(f.valid());
}
{
boost::promise<void> p;
boost::future<void> f = p.get_future();
BOOST_TEST(f.valid());
}
return boost::report_errors();
}

View File

@@ -1,100 +0,0 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// Copyright (C) 2011 Vicente J. Botet Escriba
//
// 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)
// <boost/thread/future.hpp>
// class promise<R>
// promise& operator=(const promise& rhs) = delete;
#define BOOST_THREAD_VERSION 2
#include <boost/thread/future.hpp>
#include <boost/detail/lightweight_test.hpp>
int main()
{
//BOOST_TEST(test_alloc_base::count == 0);
{
//boost::promise<int> p0(boost::allocator_arg, test_allocator<int>());
//boost::promise<int> p(boost::allocator_arg, test_allocator<int>());
boost::promise<int> p0;
boost::promise<int> p;
//BOOST_TEST(test_alloc_base::count == 2);
p = p0;
//BOOST_TEST(test_alloc_base::count == 1);
boost::future<int> f = p.get_future();
//BOOST_TEST(test_alloc_base::count == 1);
BOOST_TEST(f.valid());
try
{
f = p0.get_future();
BOOST_TEST(false);
}
catch (const boost::future_error& e)
{
BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::no_state));
}
//BOOST_TEST(test_alloc_base::count == 1);
}
//BOOST_TEST(test_alloc_base::count == 0);
// {
// //boost::promise<int&> p0(boost::allocator_arg, test_allocator<int>());
// //boost::promise<int&> p(boost::allocator_arg, test_allocator<int>());
// boost::promise<int&> p0;
// boost::promise<int&> p;
// //BOOST_TEST(test_alloc_base::count == 2);
// p = p0;
// //BOOST_TEST(test_alloc_base::count == 1);
// boost::future<int&> f = p.get_future();
// //BOOST_TEST(test_alloc_base::count == 1);
// BOOST_TEST(f.valid());
// try
// {
// f = p0.get_future();
// BOOST_TEST(false);
// }
// catch (const boost::future_error& e)
// {
// BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::no_state));
// }
// //BOOST_TEST(test_alloc_base::count == 1);
// }
// //BOOST_TEST(test_alloc_base::count == 0);
// {
// //boost::promise<void> p0(boost::allocator_arg, test_allocator<void>());
// //boost::promise<void> p(boost::allocator_arg, test_allocator<void>());
// boost::promise<void> p0;
// boost::promise<void> p;
// //BOOST_TEST(test_alloc_base::count == 2);
// p = p0;
// //BOOST_TEST(test_alloc_base::count == 1);
// boost::future<void> f = p.get_future();
// //BOOST_TEST(test_alloc_base::count == 1);
// BOOST_TEST(f.valid());
// try
// {
// f = p0.get_future();
// BOOST_TEST(false);
// }
// catch (const boost::future_error& e)
// {
// BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::no_state));
// }
// //BOOST_TEST(test_alloc_base::count == 1);
// }
//BOOST_TEST(test_alloc_base::count == 0);
return boost::report_errors();
}

View File

@@ -25,25 +25,20 @@
int main()
{
std::cout << __LINE__ << std::endl;
{
boost::promise<int> p;
boost::future<int> f = p.get_future();
BOOST_TEST(f.valid());
}
std::cout << __LINE__ << std::endl;
{
boost::promise<int&> p;
boost::future<int&> f = p.get_future();
BOOST_TEST(f.valid());
}
std::cout << __LINE__ << std::endl;
{
boost::promise<void> p;
std::cout << __LINE__ << std::endl;
boost::future<void> f = p.get_future();
std::cout << __LINE__ << std::endl;
BOOST_TEST(f.valid());
}

View File

@@ -25,7 +25,6 @@
int main()
{
std::cout << __LINE__ << std::endl;
{
typedef int T;
boost::future<T> f;
@@ -36,7 +35,6 @@ int main()
}
BOOST_TEST(f.get() == 3);
}
std::cout << __LINE__ << std::endl;
{
typedef int T;
boost::future<T> f;
@@ -55,7 +53,6 @@ int main()
}
}
std::cout << __LINE__ << std::endl;
{
typedef int& T;
int i = 4;
@@ -67,7 +64,6 @@ int main()
}
BOOST_TEST(&f.get() == &i);
}
std::cout << __LINE__ << std::endl;
{
typedef int& T;
boost::future<T> f;
@@ -86,7 +82,6 @@ int main()
}
}
std::cout << __LINE__ << std::endl;
{
typedef void T;
boost::future<T> f;
@@ -98,7 +93,6 @@ int main()
f.get();
BOOST_TEST(true);
}
std::cout << __LINE__ << std::endl;
{
typedef void T;
boost::future<T> f;

View File

@@ -1,105 +0,0 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// Copyright (C) 2011 Vicente J. Botet Escriba
//
// 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)
// <future>
// class promise<R>
// promise& operator=(promise&& rhs);
#define BOOST_THREAD_VERSION 2
#include <boost/thread/future.hpp>
#include <boost/detail/lightweight_test.hpp>
boost::mutex m0;
boost::mutex m1;
int main()
{
//BOOST_TEST(test_alloc_base::count == 0);
{
//boost::promise<int> p0(boost::allocator_arg, test_allocator<int>());
//boost::promise<int> p(boost::allocator_arg, test_allocator<int>());
boost::promise<int> p0;
boost::promise<int> p;
//BOOST_TEST(test_alloc_base::count == 2);
p = boost::move(p0);
//BOOST_TEST(test_alloc_base::count == 1);
boost::future<int> f = p.get_future();
//BOOST_TEST(test_alloc_base::count == 1);
BOOST_TEST(f.valid());
try
{
f = p0.get_future();
BOOST_TEST(false);
}
catch (const boost::future_error& e)
{
BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::no_state));
}
//BOOST_TEST(test_alloc_base::count == 1);
}
//BOOST_TEST(test_alloc_base::count == 0);
{
//boost::promise<int&> p0(boost::allocator_arg, test_allocator<int>());
//boost::promise<int&> p(boost::allocator_arg, test_allocator<int>());
boost::promise<int&> p0;
boost::promise<int&> p;
//BOOST_TEST(test_alloc_base::count == 2);
p = boost::move(p0);
//BOOST_TEST(test_alloc_base::count == 1);
boost::future<int&> f = p.get_future();
//BOOST_TEST(test_alloc_base::count == 1);
BOOST_TEST(f.valid());
try
{
f = p0.get_future();
BOOST_TEST(false);
}
catch (const boost::future_error& e)
{
BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::no_state));
}
//BOOST_TEST(test_alloc_base::count == 1);
}
//BOOST_TEST(test_alloc_base::count == 0);
{
//boost::promise<void> p0(boost::allocator_arg, test_allocator<void>());
//boost::promise<void> p(boost::allocator_arg, test_allocator<void>());
boost::promise<void> p0;
boost::promise<void> p;
//BOOST_TEST(test_alloc_base::count == 2);
p = boost::move(p0);
//BOOST_TEST(test_alloc_base::count == 1);
boost::future<void> f = p.get_future();
//BOOST_TEST(test_alloc_base::count == 1);
BOOST_TEST(f.valid());
try
{
f = p0.get_future();
BOOST_TEST(false);
}
catch (const boost::future_error& e)
{
BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::no_state));
}
//BOOST_TEST(test_alloc_base::count == 1);
}
//BOOST_TEST(test_alloc_base::count == 0);
return boost::report_errors();
}

View File

@@ -1,104 +0,0 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// Copyright (C) 2011 Vicente J. Botet Escriba
//
// 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)
// <future>
// class promise<R>
// promise(promise&& rhs);
#define BOOST_THREAD_VERSION 2
#include <boost/thread/future.hpp>
#include <boost/detail/lightweight_test.hpp>
boost::mutex m;
int main()
{
std::cout << __LINE__ << std::endl;
//BOOST_TEST(test_alloc_base::count == 0);
{
//boost::promise<int> p0(boost::allocator_arg, test_allocator<int>());
//boost::promise<int> p(boost::move(p0));
boost::promise<int> p0;
boost::promise<int> p(boost::move(p0));
//BOOST_TEST(test_alloc_base::count == 1);
std::cout << __LINE__ << std::endl;
boost::future<int> f = p.get_future();
std::cout << __LINE__ << std::endl;
//BOOST_TEST(test_alloc_base::count == 1);
BOOST_TEST(f.valid());
std::cout << __LINE__ << std::endl;
try
{
f = p0.get_future();
BOOST_TEST(false);
}
catch (const boost::future_error& e)
{
BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::no_state));
}
std::cout << __LINE__ << std::endl;
//BOOST_TEST(test_alloc_base::count == 1);
}
std::cout << __LINE__ << std::endl;
//BOOST_TEST(test_alloc_base::count == 0);
{
//boost::promise<int&> p0(boost::allocator_arg, test_allocator<int>());
//boost::promise<int&> p(boost::move(p0));
boost::promise<int&> p0;
boost::promise<int&> p(boost::move(p0));
//BOOST_TEST(test_alloc_base::count == 1);
boost::future<int&> f = p.get_future();
//BOOST_TEST(test_alloc_base::count == 1);
BOOST_TEST(f.valid());
try
{
f = p0.get_future();
BOOST_TEST(false);
}
catch (const boost::future_error& e)
{
BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::no_state));
}
//BOOST_TEST(test_alloc_base::count == 1);
}
//BOOST_TEST(test_alloc_base::count == 0);
{
//boost::promise<void> p0(boost::allocator_arg, test_allocator<void>());
//boost::promise<void> p(boost::move(p0));
boost::promise<void> p0;
boost::promise<void> p(boost::move(p0));
//BOOST_TEST(test_alloc_base::count == 1);
boost::future<void> f = p.get_future();
//BOOST_TEST(test_alloc_base::count == 1);
BOOST_TEST(f.valid());
try
{
f = p0.get_future();
BOOST_TEST(false);
}
catch (const boost::future_error& e)
{
BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::no_state));
}
//BOOST_TEST(test_alloc_base::count == 1);
}
//BOOST_TEST(test_alloc_base::count == 0);
return boost::report_errors();
}

View File

@@ -1,57 +0,0 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// Copyright (C) 2012 Vicente J. Botet Escriba
//
// 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)
// <boost/thread/locks.hpp>
// template <class Mutex> class lock_guard;
// lock_guard(mutex_type& m, adopt_lock_t);
#include <boost/thread/locks.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/thread/thread.hpp>
#include <boost/detail/lightweight_test.hpp>
typedef boost::chrono::high_resolution_clock Clock;
typedef Clock::time_point time_point;
typedef Clock::duration duration;
typedef boost::chrono::milliseconds ms;
typedef boost::chrono::nanoseconds ns;
boost::mutex m;
void f()
{
time_point t0 = Clock::now();
time_point t1;
{
m.lock();
boost::lock_guard<boost::mutex> lg(m, boost::adopt_lock);
t1 = Clock::now();
}
ns d = t1 - t0 - ms(250);
BOOST_TEST(d < ns(2500000)+ms(1000)); // within 2.5ms
}
int main()
{
m.lock();
boost::thread t(f);
boost::this_thread::sleep_for(ms(250));
m.unlock();
t.join();
return boost::report_errors();
}

View File

@@ -1,35 +0,0 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// Copyright (C) 2011 Vicente J. Botet Escriba
//
// 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)
// <boost/thread/locks.hpp>
// template <class Mutex> class lock_guard;
// lock_guard& operator=(lock_guard const&) = delete;
#include <boost/thread/locks.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/detail/lightweight_test.hpp>
boost::mutex m0;
boost::mutex m1;
int main()
{
boost::lock_guard<boost::mutex> lk0(m0);
boost::lock_guard<boost::mutex> lk1(m1);
lk1 = lk0;
}

View File

@@ -1,34 +0,0 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// Copyright (C) 2011 Vicente J. Botet Escriba
//
// 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)
// <boost/thread/locks.hpp>
// template <class Mutex> class lock_guard;
// lock_guard(lock_guard const&) = delete;
#include <boost/thread/locks.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/detail/lightweight_test.hpp>
boost::mutex m0;
boost::mutex m1;
int main()
{
boost::lock_guard<boost::mutex> lk0(m0);
boost::lock_guard<boost::mutex> lk1 = lk0;
}

View File

@@ -1,56 +0,0 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// Copyright (C) 2011 Vicente J. Botet Escriba
//
// 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)
// <boost/thread/locks.hpp>
// template <class Mutex> class lock_guard;
// lock_guard(lock_guard const&) = delete;
#include <boost/thread/locks.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/thread/thread.hpp>
#include <boost/detail/lightweight_test.hpp>
typedef boost::chrono::high_resolution_clock Clock;
typedef Clock::time_point time_point;
typedef Clock::duration duration;
typedef boost::chrono::milliseconds ms;
typedef boost::chrono::nanoseconds ns;
boost::mutex m;
void f()
{
time_point t0 = Clock::now();
time_point t1;
{
boost::lock_guard<boost::mutex> lg(m);
t1 = Clock::now();
}
ns d = t1 - t0 - ms(250);
// This test is spurious as it depends on the time the thread system switches the threads
BOOST_TEST(d < ns(2500000)+ms(1000)); // within 2.5ms
}
int main()
{
m.lock();
boost::thread t(f);
boost::this_thread::sleep_for(ms(250));
m.unlock();
t.join();
return boost::report_errors();
}

View File

@@ -1,39 +0,0 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// Copyright (C) 2012 Vicente J. Botet Escriba
//
// 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)
// <boost/thread/mutex.hpp>
// <mutex>
// template <class Mutex>
// class lock_guard
// {
// public:
// typedef Mutex mutex_type;
// ...
// };
#include <boost/thread/mutex.hpp>
#include <boost/static_assert.hpp>
#include <boost/detail/lightweight_test.hpp>
int main()
{
BOOST_STATIC_ASSERT_MSG((boost::is_same<boost::lock_guard<boost::mutex>::mutex_type,
boost::mutex>::value), "");
return boost::report_errors();
}

View File

@@ -40,8 +40,7 @@ void f1()
BOOST_TEST(lk.owns_lock() == true);
time_point t1 = Clock::now();
ns d = t1 - t0 - ms(250);
// This test is spurious as it depends on the time the thread system switches the threads
BOOST_TEST(d < ns(5000000)+ms(1000)); // within 5ms
BOOST_TEST(d < ns(5000000)); // within 5ms
}
void f2()

View File

@@ -37,6 +37,8 @@ int main()
BOOST_TEST(lk0.mutex() == 0);
BOOST_TEST(lk0.owns_lock() == false);
}
{
boost::shared_lock<boost::shared_mutex> lk1;
@@ -44,38 +46,6 @@ int main()
BOOST_TEST(lk1.mutex() == &m0);
BOOST_TEST(lk1.owns_lock() == true);
}
{
boost::unique_lock<boost::shared_mutex> lk0(m0);
boost::shared_lock<boost::shared_mutex> lk1(m1);
lk1 = boost::shared_lock<boost::shared_mutex>(boost::move(lk0));
BOOST_TEST(lk1.mutex() == &m0);
BOOST_TEST(lk1.owns_lock() == true);
BOOST_TEST(lk0.mutex() == 0);
BOOST_TEST(lk0.owns_lock() == false);
}
{
boost::shared_lock<boost::shared_mutex> lk1;
lk1 = boost::shared_lock<boost::shared_mutex>(boost::unique_lock<boost::shared_mutex>(m0));
BOOST_TEST(lk1.mutex() == &m0);
BOOST_TEST(lk1.owns_lock() == true);
}
{
boost::upgrade_lock<boost::shared_mutex> lk0(m0);
boost::shared_lock<boost::shared_mutex> lk1(m1);
lk1 = boost::shared_lock<boost::shared_mutex>(boost::move(lk0));
BOOST_TEST(lk1.mutex() == &m0);
BOOST_TEST(lk1.owns_lock() == true);
BOOST_TEST(lk0.mutex() == 0);
BOOST_TEST(lk0.owns_lock() == false);
}
{
boost::shared_lock<boost::shared_mutex> lk1;
lk1 = boost::shared_lock<boost::shared_mutex>(boost::upgrade_lock<boost::shared_mutex>(m0));
BOOST_TEST(lk1.mutex() == &m0);
BOOST_TEST(lk1.owns_lock() == true);
}
return boost::report_errors();
}

View File

@@ -41,7 +41,6 @@ int main()
BOOST_TEST(lk.owns_lock() == true);
}
return boost::report_errors();
}

View File

@@ -1,65 +0,0 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// Copyright (C) 2011 Vicente J. Botet Escriba
//
// 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)
// <boost/thread/locks.hpp>
// template <class Mutex> class shared_lock;
// shared_lock& operator=(shared_lock&& u);
#include <boost/thread/locks.hpp>
#include <boost/thread/shared_mutex.hpp>
#include <boost/detail/lightweight_test.hpp>
boost::shared_mutex m;
int main()
{
{
boost::unique_lock<boost::shared_mutex> lk0(m);
boost::shared_lock<boost::shared_mutex> lk( (boost::move(lk0)));
BOOST_TEST(lk.mutex() == &m);
BOOST_TEST(lk.owns_lock() == true);
BOOST_TEST(lk0.mutex() == 0);
BOOST_TEST(lk0.owns_lock() == false);
}
{
boost::shared_lock<boost::shared_mutex> lk( (boost::unique_lock<boost::shared_mutex>(m)));
BOOST_TEST(lk.mutex() == &m);
BOOST_TEST(lk.owns_lock() == true);
}
{
boost::unique_lock<boost::shared_mutex> lk0(m, boost::defer_lock);
boost::shared_lock<boost::shared_mutex> lk( (boost::move(lk0)));
BOOST_TEST(lk.mutex() == &m);
BOOST_TEST(lk.owns_lock() == false);
BOOST_TEST(lk0.mutex() == 0);
BOOST_TEST(lk0.owns_lock() == false);
}
{
boost::unique_lock<boost::shared_mutex> lk0(m, boost::defer_lock);
lk0.release();
boost::shared_lock<boost::shared_mutex> lk( (boost::move(lk0)));
BOOST_TEST(lk.mutex() == 0);
BOOST_TEST(lk.owns_lock() == false);
BOOST_TEST(lk0.mutex() == 0);
BOOST_TEST(lk0.owns_lock() == false);
}
return boost::report_errors();
}

View File

@@ -1,64 +0,0 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// Copyright (C) 2011 Vicente J. Botet Escriba
//
// 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)
// <boost/thread/locks.hpp>
// template <class Mutex> class shared_lock;
// shared_lock& operator=(shared_lock&& u);
#include <boost/thread/locks.hpp>
#include <boost/thread/shared_mutex.hpp>
#include <boost/detail/lightweight_test.hpp>
boost::shared_mutex m;
int main()
{
{
boost::upgrade_lock<boost::shared_mutex> lk0(m);
boost::shared_lock<boost::shared_mutex> lk( (boost::move(lk0)));
BOOST_TEST(lk.mutex() == &m);
BOOST_TEST(lk.owns_lock() == true);
BOOST_TEST(lk0.mutex() == 0);
BOOST_TEST(lk0.owns_lock() == false);
}
{
boost::shared_lock<boost::shared_mutex> lk( (boost::upgrade_lock<boost::shared_mutex>(m)));
BOOST_TEST(lk.mutex() == &m);
BOOST_TEST(lk.owns_lock() == true);
}
{
boost::upgrade_lock<boost::shared_mutex> lk0(m, boost::defer_lock);
boost::shared_lock<boost::shared_mutex> lk( (boost::move(lk0)));
BOOST_TEST(lk.mutex() == &m);
BOOST_TEST(lk.owns_lock() == false);
BOOST_TEST(lk0.mutex() == 0);
BOOST_TEST(lk0.owns_lock() == false);
}
{
boost::upgrade_lock<boost::shared_mutex> lk0(m, boost::defer_lock);
lk0.release();
boost::shared_lock<boost::shared_mutex> lk( (boost::move(lk0)));
BOOST_TEST(lk.mutex() == 0);
BOOST_TEST(lk.owns_lock() == false);
BOOST_TEST(lk0.mutex() == 0);
BOOST_TEST(lk0.owns_lock() == false);
}
return boost::report_errors();
}

View File

@@ -1,40 +0,0 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// Copyright (C) 2011 Vicente J. Botet Escriba
//
// 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)
// <boost/thread/mutex.hpp>
// <mutex>
// template <class Mutex>
// class shared_lock
// {
// public:
// typedef Mutex mutex_type;
// ...
// };
#include <boost/thread/locks.hpp>
#include <boost/thread/shared_mutex.hpp>
#include <boost/static_assert.hpp>
#include <boost/detail/lightweight_test.hpp>
int main()
{
BOOST_STATIC_ASSERT_MSG((boost::is_same<boost::shared_lock<boost::shared_mutex>::mutex_type,
boost::shared_mutex>::value), "");
return boost::report_errors();
}

View File

@@ -16,7 +16,7 @@
// template <class Mutex> class unique_lock;
// unique_lock(unique_lock&& u);
// unique_lock& operator=(unique_lock&& u);
#include <boost/thread/locks.hpp>
@@ -40,23 +40,6 @@ int main()
BOOST_TEST(lk.mutex() == &m);
BOOST_TEST(lk.owns_lock() == true);
}
{
boost::unique_lock<boost::mutex> lk0(m, boost::defer_lock);
boost::unique_lock<boost::mutex> lk( (boost::move(lk0)));
BOOST_TEST(lk.mutex() == &m);
BOOST_TEST(lk.owns_lock() == false);
BOOST_TEST(lk0.mutex() == 0);
BOOST_TEST(lk0.owns_lock() == false);
}
{
boost::unique_lock<boost::mutex> lk0(m, boost::defer_lock);
lk0.release();
boost::unique_lock<boost::mutex> lk( (boost::move(lk0)));
BOOST_TEST(lk.mutex() == 0);
BOOST_TEST(lk.owns_lock() == false);
BOOST_TEST(lk0.mutex() == 0);
BOOST_TEST(lk0.owns_lock() == false);
}
return boost::report_errors();
}

View File

@@ -1,65 +0,0 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// Copyright (C) 2011 Vicente J. Botet Escriba
//
// 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)
// <boost/thread/locks.hpp>
// template <class Mutex> class unique_lock;
// template <class Clock, class Duration>
// unique_lock(shared_lock<mutex_type>&&,
// const chrono::duration<Rep, Period>&);
#include <boost/thread/locks.hpp>
#include <boost/thread/shared_mutex.hpp>
#include <boost/detail/lightweight_test.hpp>
boost::upgrade_mutex m;
int main()
{
{
boost::upgrade_lock<boost::upgrade_mutex> lk0(m);
boost::unique_lock<boost::upgrade_mutex> lk(boost::move(lk0), boost::chrono::milliseconds(1));
BOOST_TEST(lk.mutex() == &m);
BOOST_TEST(lk.owns_lock() == true);
BOOST_TEST(lk0.mutex() == 0);
BOOST_TEST(lk0.owns_lock() == false);
}
{
boost::unique_lock<boost::upgrade_mutex>
lk(boost::upgrade_lock<boost::upgrade_mutex>(m), boost::chrono::milliseconds(1));
BOOST_TEST(lk.mutex() == &m);
BOOST_TEST(lk.owns_lock() == true);
}
{
boost::upgrade_lock<boost::upgrade_mutex> lk0(m, boost::defer_lock);
boost::unique_lock<boost::upgrade_mutex> lk(boost::move(lk0), boost::chrono::milliseconds(1));
BOOST_TEST(lk.mutex() == &m);
BOOST_TEST(lk.owns_lock() == false);
BOOST_TEST(lk0.mutex() == 0);
BOOST_TEST(lk0.owns_lock() == false);
}
{
boost::upgrade_lock<boost::upgrade_mutex> lk0(m, boost::defer_lock);
lk0.release();
boost::unique_lock<boost::upgrade_mutex> lk(boost::move(lk0), boost::chrono::milliseconds(1));
BOOST_TEST(lk.mutex() == 0);
BOOST_TEST(lk.owns_lock() == false);
BOOST_TEST(lk0.mutex() == 0);
BOOST_TEST(lk0.owns_lock() == false);
}
return boost::report_errors();
}

View File

@@ -1,63 +0,0 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// Copyright (C) 2011 Vicente J. Botet Escriba
//
// 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)
// <boost/thread/locks.hpp>
// template <class Mutex> class unique_lock;
// unique_lock(upgrade_lock&& u);
#include <boost/thread/locks.hpp>
#include <boost/thread/shared_mutex.hpp>
#include <boost/detail/lightweight_test.hpp>
boost::upgrade_mutex m;
int main()
{
{
boost::upgrade_lock<boost::upgrade_mutex> lk0(m);
boost::unique_lock<boost::upgrade_mutex> lk( (boost::move(lk0)));
BOOST_TEST(lk.mutex() == &m);
BOOST_TEST(lk.owns_lock() == true);
BOOST_TEST(lk0.mutex() == 0);
BOOST_TEST(lk0.owns_lock() == false);
}
{
boost::unique_lock<boost::upgrade_mutex> lk( (boost::upgrade_lock<boost::upgrade_mutex>(m)));
BOOST_TEST(lk.mutex() == &m);
BOOST_TEST(lk.owns_lock() == true);
}
{
boost::upgrade_lock<boost::upgrade_mutex> lk0(m, boost::defer_lock);
boost::unique_lock<boost::upgrade_mutex> lk( (boost::move(lk0)));
BOOST_TEST(lk.mutex() == &m);
BOOST_TEST(lk.owns_lock() == false);
BOOST_TEST(lk0.mutex() == 0);
BOOST_TEST(lk0.owns_lock() == false);
}
{
boost::upgrade_lock<boost::upgrade_mutex> lk0(m, boost::defer_lock);
lk0.release();
boost::unique_lock<boost::upgrade_mutex> lk( (boost::move(lk0)));
BOOST_TEST(lk.mutex() == 0);
BOOST_TEST(lk.owns_lock() == false);
BOOST_TEST(lk0.mutex() == 0);
BOOST_TEST(lk0.owns_lock() == false);
}
return boost::report_errors();
}

View File

@@ -1,63 +0,0 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// Copyright (C) 2011 Vicente J. Botet Escriba
//
// 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)
// <boost/thread/locks.hpp>
// template <class Mutex> class unique_lock;
// unique_lock(upgrade_lock&& u, try_to_lock);
#include <boost/thread/locks.hpp>
#include <boost/thread/shared_mutex.hpp>
#include <boost/detail/lightweight_test.hpp>
boost::upgrade_mutex m;
int main()
{
{
boost::upgrade_lock<boost::upgrade_mutex> lk0(m);
boost::unique_lock<boost::upgrade_mutex> lk(boost::move(lk0), boost::try_to_lock );
BOOST_TEST(lk.mutex() == &m);
BOOST_TEST(lk.owns_lock() == true);
BOOST_TEST(lk0.mutex() == 0);
BOOST_TEST(lk0.owns_lock() == false);
}
{
boost::unique_lock<boost::upgrade_mutex> lk(boost::upgrade_lock<boost::upgrade_mutex>(m), boost::try_to_lock);
BOOST_TEST(lk.mutex() == &m);
BOOST_TEST(lk.owns_lock() == true);
}
{
boost::upgrade_lock<boost::upgrade_mutex> lk0(m, boost::defer_lock);
boost::unique_lock<boost::upgrade_mutex> lk(boost::move(lk0), boost::try_to_lock);
BOOST_TEST(lk.mutex() == &m);
BOOST_TEST(lk.owns_lock() == false);
BOOST_TEST(lk0.mutex() == 0);
BOOST_TEST(lk0.owns_lock() == false);
}
{
boost::upgrade_lock<boost::upgrade_mutex> lk0(m, boost::defer_lock);
lk0.release();
boost::unique_lock<boost::upgrade_mutex> lk(boost::move(lk0), boost::try_to_lock);
BOOST_TEST(lk.mutex() == 0);
BOOST_TEST(lk.owns_lock() == false);
BOOST_TEST(lk0.mutex() == 0);
BOOST_TEST(lk0.owns_lock() == false);
}
return boost::report_errors();
}

View File

@@ -1,66 +0,0 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// Copyright (C) 2011 Vicente J. Botet Escriba
//
// 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)
// <boost/thread/locks.hpp>
// template <class Mutex> class unique_lock;
// template <class Clock, class Duration>
// unique_lock(shared_lock<mutex_type>&&,
// const chrono::time_point<Clock, Duration>&);
#include <boost/thread/locks.hpp>
#include <boost/thread/shared_mutex.hpp>
#include <boost/detail/lightweight_test.hpp>
boost::upgrade_mutex m;
int main()
{
{
boost::upgrade_lock<boost::upgrade_mutex> lk0(m);
boost::unique_lock<boost::upgrade_mutex> lk( boost::move(lk0), boost::chrono::steady_clock::now()+boost::chrono::milliseconds(1));
BOOST_TEST(lk.mutex() == &m);
BOOST_TEST(lk.owns_lock() == true);
BOOST_TEST(lk0.mutex() == 0);
BOOST_TEST(lk0.owns_lock() == false);
}
{
boost::unique_lock<boost::upgrade_mutex>
lk( boost::upgrade_lock<boost::upgrade_mutex>(m), boost::chrono::steady_clock::now()+boost::chrono::milliseconds(1));
BOOST_TEST(lk.mutex() == &m);
BOOST_TEST(lk.owns_lock() == true);
}
{
boost::upgrade_lock<boost::upgrade_mutex> lk0(m, boost::defer_lock);
boost::unique_lock<boost::upgrade_mutex> lk( boost::move(lk0), boost::chrono::steady_clock::now()+boost::chrono::milliseconds(1));
BOOST_TEST(lk.mutex() == &m);
BOOST_TEST(lk.owns_lock() == false);
BOOST_TEST(lk0.mutex() == 0);
BOOST_TEST(lk0.owns_lock() == false);
}
{
boost::upgrade_lock<boost::upgrade_mutex> lk0(m, boost::defer_lock);
lk0.release();
boost::unique_lock<boost::upgrade_mutex> lk( boost::move(lk0), boost::chrono::steady_clock::now()+boost::chrono::milliseconds(1));
BOOST_TEST(lk.mutex() == 0);
BOOST_TEST(lk.owns_lock() == false);
BOOST_TEST(lk0.mutex() == 0);
BOOST_TEST(lk0.owns_lock() == false);
}
return boost::report_errors();
}

View File

@@ -16,23 +16,26 @@
// <mutex>
// template <class Mutex>
// class unique_lock
// {
// public:
// typedef Mutex mutex_type;
// ...
// };
// struct defer_lock_t {};
// struct try_to_lock_t {};
// struct adopt_lock_t {};
//
// constexpr defer_lock_t defer_lock{};
// constexpr try_to_lock_t try_to_lock{};
// constexpr adopt_lock_t adopt_lock{};
#include <boost/thread/mutex.hpp>
#include <boost/static_assert.hpp>
#include <boost/detail/lightweight_test.hpp>
int main()
{
BOOST_STATIC_ASSERT_MSG((boost::is_same<boost::unique_lock<boost::mutex>::mutex_type,
boost::mutex>::value), "");
typedef boost::defer_lock_t T1;
typedef boost::try_to_lock_t T2;
typedef boost::adopt_lock_t T3;
T1 t1 = boost::defer_lock;
T2 t2 = boost::try_to_lock;
T3 t3 = boost::adopt_lock;
return boost::report_errors();
}

View File

@@ -1,39 +0,0 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// Copyright (C) 2011 Vicente J. Botet Escriba
//
// 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)
// <boost/thread/locks.hpp>
// template <class Mutex> class upgrade_lock;
// upgrade_lock& operator=(upgrade_lock const&) = delete;
#include <boost/thread/locks.hpp>
#include <boost/thread/shared_mutex.hpp>
#include <boost/detail/lightweight_test.hpp>
boost::shared_mutex m0;
boost::shared_mutex m1;
int main()
{
boost::upgrade_lock<boost::shared_mutex> lk0(m0);
boost::upgrade_lock<boost::shared_mutex> lk1(m1);
lk1 = lk0;
BOOST_TEST(lk1.mutex() == &m0);
BOOST_TEST(lk1.owns_lock() == true);
BOOST_TEST(lk0.mutex() == 0);
BOOST_TEST(lk0.owns_lock() == false);
}

View File

@@ -1,38 +0,0 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// Copyright (C) 2011 Vicente J. Botet Escriba
//
// 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)
// <boost/thread/locks.hpp>
// template <class Mutex> class upgrade_lock;
// upgrade_lock(upgrade_lock const&) = delete;
#include <boost/thread/locks.hpp>
#include <boost/thread/shared_mutex.hpp>
#include <boost/detail/lightweight_test.hpp>
boost::shared_mutex m0;
boost::shared_mutex m1;
int main()
{
boost::upgrade_lock<boost::shared_mutex> lk0(m0);
boost::upgrade_lock<boost::shared_mutex> lk1(lk0);
BOOST_TEST(lk1.mutex() == &m1);
BOOST_TEST(lk1.owns_lock() == true);
BOOST_TEST(lk0.mutex() == 0);
BOOST_TEST(lk0.owns_lock() == false);
}

View File

@@ -1,33 +0,0 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// Copyright (C) 2011 Vicente J. Botet Escriba
//
// 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)
// <boost/thread/locks.hpp>
// template <class Mutex> class upgrade_lock;
// upgrade_lock(upgrade_lock const&) = delete;
#include <boost/thread/locks.hpp>
#include <boost/thread/shared_mutex.hpp>
#include <boost/detail/lightweight_test.hpp>
int main()
{
boost::upgrade_lock<boost::shared_mutex> ul;
BOOST_TEST(!ul.owns_lock());
BOOST_TEST(ul.mutex() == 0);
return boost::report_errors();
}

View File

@@ -1,35 +0,0 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// Copyright (C) 2011 Vicente J. Botet Escriba
//
// 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)
// <boost/thread/locks.hpp>
// template <class Mutex> class upgrade_lock;
// upgrade_lock(mutex_type& m, adopt_lock_t);
#include <boost/thread/locks.hpp>
#include <boost/thread/shared_mutex.hpp>
#include <boost/detail/lightweight_test.hpp>
int main()
{
boost::shared_mutex m;
m.lock();
boost::upgrade_lock<boost::shared_mutex> lk(m, boost::defer_lock);
BOOST_TEST(lk.mutex() == &m);
BOOST_TEST(lk.owns_lock() == false);
return boost::report_errors();
}

View File

@@ -1,77 +0,0 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// Copyright (C) 2011 Vicente J. Botet Escriba
//
// 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)
// <boost/thread/locks.hpp>
// template <class Mutex> class upgrade_lock;
// template <class Rep, class Period>
// upgrade_lock(mutex_type& m, const chrono::duration<Rep, Period>& rel_time);
#include <boost/thread/locks.hpp>
#include <boost/thread/shared_mutex.hpp>
#include <boost/thread/thread.hpp>
#include <boost/detail/lightweight_test.hpp>
#include <boost/chrono/chrono_io.hpp>
boost::shared_mutex m;
typedef boost::chrono::steady_clock Clock;
typedef Clock::time_point time_point;
typedef Clock::duration duration;
typedef boost::chrono::milliseconds ms;
typedef boost::chrono::nanoseconds ns;
void f1()
{
time_point t0 = Clock::now();
boost::upgrade_lock<boost::shared_mutex> lk(m, ms(300));
BOOST_TEST(lk.owns_lock() == true);
time_point t1 = Clock::now();
ns d = t1 - t0 - ms(250);
// This test is spurious as it depends on the time the thread system switches the threads
BOOST_TEST(d < ns(5000000)+ms(1000)); // within 5ms
}
void f2()
{
time_point t0 = Clock::now();
boost::upgrade_lock<boost::shared_mutex> lk(m, ms(250));
BOOST_TEST(lk.owns_lock() == false);
time_point t1 = Clock::now();
ns d = t1 - t0 - ms(250);
// This test is spurious as it depends on the time the thread system switches the threads
BOOST_TEST(d < ns(5000000)+ms(1000)); // within 5ms
}
int main()
{
{
m.lock();
boost::thread t(f1);
boost::this_thread::sleep_for(ms(250));
m.unlock();
t.join();
}
{
m.lock();
boost::thread t(f2);
boost::this_thread::sleep_for(ms(300));
m.unlock();
t.join();
}
return boost::report_errors();
}

View File

@@ -1,66 +0,0 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// Copyright (C) 2011 Vicente J. Botet Escriba
//
// 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)
// <boost/thread/shared_mutex.hpp>
// template <class Mutex> class upgrade_lock;
// upgrade_lock(upgrade_lock const&) = delete;
#include <boost/thread/locks.hpp>
#include <boost/thread/shared_mutex.hpp>
#include <boost/detail/lightweight_test.hpp>
boost::shared_mutex m0;
boost::shared_mutex m1;
int main()
{
{
boost::upgrade_lock<boost::shared_mutex> lk0(m0);
boost::upgrade_lock<boost::shared_mutex> lk1(m1);
lk1 = boost::move(lk0);
BOOST_TEST(lk1.mutex() == &m0);
BOOST_TEST(lk1.owns_lock() == true);
BOOST_TEST(lk0.mutex() == 0);
BOOST_TEST(lk0.owns_lock() == false);
}
{
boost::upgrade_lock<boost::shared_mutex> lk1;
lk1 = boost::upgrade_lock<boost::shared_mutex>(m0);
BOOST_TEST(lk1.mutex() == &m0);
BOOST_TEST(lk1.owns_lock() == true);
}
{
boost::unique_lock<boost::shared_mutex> lk0(m0);
boost::upgrade_lock<boost::shared_mutex> lk1(m1);
lk1 = boost::upgrade_lock<boost::shared_mutex>(boost::move(lk0));
BOOST_TEST(lk1.mutex() == &m0);
BOOST_TEST(lk1.owns_lock() == true);
BOOST_TEST(lk0.mutex() == 0);
BOOST_TEST(lk0.owns_lock() == false);
}
{
boost::upgrade_lock<boost::shared_mutex> lk1;
lk1 = boost::upgrade_lock<boost::shared_mutex>(boost::unique_lock<boost::shared_mutex>(m0));
BOOST_TEST(lk1.mutex() == &m0);
BOOST_TEST(lk1.owns_lock() == true);
}
return boost::report_errors();
}

View File

@@ -1,46 +0,0 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// Copyright (C) 2011 Vicente J. Botet Escriba
//
// 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)
// <boost/thread/locks.hpp>
// template <class Mutex> class upgrade_lock;
// upgrade_lock& operator=(upgrade_lock&& u);
#include <boost/thread/locks.hpp>
#include <boost/thread/shared_mutex.hpp>
#include <boost/detail/lightweight_test.hpp>
boost::shared_mutex m;
int main()
{
{
boost::upgrade_lock<boost::shared_mutex> lk0(m);
boost::upgrade_lock<boost::shared_mutex> lk( (boost::move(lk0)));
BOOST_TEST(lk.mutex() == &m);
BOOST_TEST(lk.owns_lock() == true);
BOOST_TEST(lk0.mutex() == 0);
BOOST_TEST(lk0.owns_lock() == false);
}
{
boost::upgrade_lock<boost::shared_mutex> lk( (boost::upgrade_lock<boost::shared_mutex>(m)));
BOOST_TEST(lk.mutex() == &m);
BOOST_TEST(lk.owns_lock() == true);
}
return boost::report_errors();
}

View File

@@ -1,46 +0,0 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// Copyright (C) 2011 Vicente J. Botet Escriba
//
// 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)
// <boost/thread/locks.hpp>
// template <class Mutex> class upgrade_lock;
// upgrade_lock& operator=(unique_lock&& u);
#include <boost/thread/locks.hpp>
#include <boost/thread/shared_mutex.hpp>
#include <boost/detail/lightweight_test.hpp>
boost::shared_mutex m;
int main()
{
{
boost::unique_lock<boost::shared_mutex> lk0(m);
boost::upgrade_lock<boost::shared_mutex> lk( (boost::move(lk0)));
BOOST_TEST(lk.mutex() == &m);
BOOST_TEST(lk.owns_lock() == true);
BOOST_TEST(lk0.mutex() == 0);
BOOST_TEST(lk0.owns_lock() == false);
}
{
boost::upgrade_lock<boost::shared_mutex> lk( (boost::unique_lock<boost::shared_mutex>(m)));
BOOST_TEST(lk.mutex() == &m);
BOOST_TEST(lk.owns_lock() == true);
}
return boost::report_errors();
}

View File

@@ -1,58 +0,0 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// Copyright (C) 2011 Vicente J. Botet Escriba
//
// 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)
// <boost/thread/locks.hpp>
// template <class Mutex> class upgrade_lock;
// explicit upgrade_lock(Mutex& m);
#include <boost/thread/locks.hpp>
#include <boost/thread/shared_mutex.hpp>
#include <boost/thread/thread.hpp>
#include <boost/detail/lightweight_test.hpp>
boost::shared_mutex m;
typedef boost::chrono::system_clock Clock;
typedef Clock::time_point time_point;
typedef Clock::duration duration;
typedef boost::chrono::milliseconds ms;
typedef boost::chrono::nanoseconds ns;
void f()
{
time_point t0 = Clock::now();
time_point t1;
{
boost::upgrade_lock<boost::shared_mutex> ul(m);
t1 = Clock::now();
}
ns d = t1 - t0 - ms(250);
// This test is spurious as it depends on the time the thread system switches the threads
BOOST_TEST(d < ns(2500000)+ms(1000)); // within 2.5ms
}
int main()
{
m.lock();
boost::thread t(f);
boost::this_thread::sleep_for(ms(250));
m.unlock();
t.join();
return boost::report_errors();
}

View File

@@ -1,75 +0,0 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// Copyright (C) 2011 Vicente J. Botet Escriba
//
// 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)
// <boost/thread/locks.hpp>
// template <class Mutex> class upgrade_lock;
// template <class Clock, class Duration>
// upgrade_lock(mutex_type& m, const chrono::time_point<Clock, Duration>& abs_time);
#include <boost/thread/locks.hpp>
#include <boost/thread/shared_mutex.hpp>
#include <boost/thread/thread.hpp>
#include <boost/detail/lightweight_test.hpp>
boost::shared_mutex m;
typedef boost::chrono::steady_clock Clock;
typedef Clock::time_point time_point;
typedef Clock::duration duration;
typedef boost::chrono::milliseconds ms;
typedef boost::chrono::nanoseconds ns;
void f1()
{
time_point t0 = Clock::now();
boost::upgrade_lock<boost::shared_mutex> lk(m, Clock::now() + ms(300));
BOOST_TEST(lk.owns_lock() == true);
time_point t1 = Clock::now();
ns d = t1 - t0 - ms(250);
BOOST_TEST(d < ns(50000000)); // within 50ms
}
void f2()
{
time_point t0 = Clock::now();
boost::upgrade_lock<boost::shared_mutex> lk(m, Clock::now() + ms(250));
BOOST_TEST(lk.owns_lock() == false);
time_point t1 = Clock::now();
ns d = t1 - t0 - ms(250);
// This test is spurious as it depends on the time the thread system switches the threads
BOOST_TEST(d < ns(5000000)+ms(1000)); // within 5ms
}
int main()
{
{
m.lock();
boost::thread t(f1);
boost::this_thread::sleep_for(ms(250));
m.unlock();
t.join();
}
{
m.lock();
boost::thread t(f2);
boost::this_thread::sleep_for(ms(300));
m.unlock();
t.join();
}
return boost::report_errors();
}

View File

@@ -1,72 +0,0 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// Copyright (C) 2011 Vicente J. Botet Escriba
//
// 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)
// <boost/thread/locks.hpp>
// template <class Mutex> class upgrade_lock;
// upgrade_lock(mutex_type& m, try_to_lock_t);
#include <boost/thread/locks.hpp>
#include <boost/thread/shared_mutex.hpp>
#include <boost/thread/thread.hpp>
#include <boost/detail/lightweight_test.hpp>
boost::shared_mutex m;
typedef boost::chrono::system_clock Clock;
typedef Clock::time_point time_point;
typedef Clock::duration duration;
typedef boost::chrono::milliseconds ms;
typedef boost::chrono::nanoseconds ns;
void f()
{
time_point t0 = Clock::now();
{
boost::upgrade_lock<boost::shared_mutex> lk(m, boost::try_to_lock);
BOOST_TEST(lk.owns_lock() == false);
}
{
boost::upgrade_lock<boost::shared_mutex> lk(m, boost::try_to_lock);
BOOST_TEST(lk.owns_lock() == false);
}
{
boost::upgrade_lock<boost::shared_mutex> lk(m, boost::try_to_lock);
BOOST_TEST(lk.owns_lock() == false);
}
while (true)
{
boost::upgrade_lock<boost::shared_mutex> lk(m, boost::try_to_lock);
if (lk.owns_lock()) break;
}
time_point t1 = Clock::now();
//m.unlock();
ns d = t1 - t0 - ms(250);
// This test is spurious as it depends on the time the thread system switches the threads
BOOST_TEST(d < ns(50000000)+ms(1000)); // within 50ms
}
int main()
{
m.lock();
boost::thread t(f);
boost::this_thread::sleep_for(ms(250));
m.unlock();
t.join();
return boost::report_errors();
}

View File

@@ -1,77 +0,0 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// Copyright (C) 2011 Vicente J. Botet Escriba
//
// 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)
// <boost/thread/locks.hpp>
// template <class Mutex> class upgrade_lock;
// void lock();
#include <boost/thread/locks.hpp>
#include <boost/thread/shared_mutex.hpp>
#include <boost/thread/thread.hpp>
#include <boost/detail/lightweight_test.hpp>
#include <iostream>
boost::shared_mutex m;
typedef boost::chrono::system_clock Clock;
typedef Clock::time_point time_point;
typedef Clock::duration duration;
typedef boost::chrono::milliseconds ms;
typedef boost::chrono::nanoseconds ns;
void f()
{
boost::upgrade_lock < boost::shared_mutex > lk(m, boost::defer_lock);
time_point t0 = Clock::now();
lk.lock();
time_point t1 = Clock::now();
BOOST_TEST(lk.owns_lock() == true);
ns d = t1 - t0 - ms(250);
// This test is spurious as it depends on the time the thread system switches the threads
BOOST_TEST(d < ns(2500000)+ms(1000)); // within 2.5ms
try
{
lk.lock();
BOOST_TEST(false);
}
catch (boost::system::system_error& e)
{
BOOST_TEST(e.code().value() == boost::system::errc::resource_deadlock_would_occur);
}
lk.unlock();
lk.release();
try
{
lk.lock();
BOOST_TEST(false);
}
catch (boost::system::system_error& e)
{
BOOST_TEST(e.code().value() == boost::system::errc::operation_not_permitted);
}
}
int main()
{
m.lock();
boost::thread t(f);
boost::this_thread::sleep_for(ms(250));
m.unlock();
t.join();
return boost::report_errors();
}

View File

@@ -1,78 +0,0 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// Copyright (C) 2011 Vicente J. Botet Escriba
//
// 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)
// <boost/thread/locks.hpp>
// template <class Mutex> class upgrade_lock;
// template <class Rep, class Period>
// bool try_lock_for(const chrono::duration<Rep, Period>& rel_time);
#include <boost/thread/locks.hpp>
//#include <boost/thread/shared_mutex.hpp>
#include <boost/detail/lightweight_test.hpp>
bool try_lock_for_called = false;
typedef boost::chrono::milliseconds ms;
struct shared_mutex
{
template <class Rep, class Period>
bool try_lock_upgrade_for(const boost::chrono::duration<Rep, Period>& rel_time)
{
BOOST_TEST(rel_time == ms(5));
try_lock_for_called = !try_lock_for_called;
return try_lock_for_called;
}
void unlock_upgrade()
{
}
};
shared_mutex m;
int main()
{
boost::upgrade_lock<shared_mutex> lk(m, boost::defer_lock);
BOOST_TEST(lk.try_lock_for(ms(5)) == true);
BOOST_TEST(try_lock_for_called == true);
BOOST_TEST(lk.owns_lock() == true);
try
{
lk.try_lock_for(ms(5));
BOOST_TEST(false);
}
catch (boost::system::system_error& e)
{
BOOST_TEST(e.code().value() == boost::system::errc::resource_deadlock_would_occur);
}
lk.unlock();
BOOST_TEST(lk.try_lock_for(ms(5)) == false);
BOOST_TEST(try_lock_for_called == false);
BOOST_TEST(lk.owns_lock() == false);
lk.release();
try
{
lk.try_lock_for(ms(5));
BOOST_TEST(false);
}
catch (boost::system::system_error& e)
{
BOOST_TEST(e.code().value() == boost::system::errc::operation_not_permitted);
}
return boost::report_errors();
}

View File

@@ -1,74 +0,0 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// Copyright (C) 2011 Vicente J. Botet Escriba
//
// 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)
// <boost/thread/locks.hpp>
// template <class Mutex> class upgrade_lock;
// template <class Rep, class Period>
// bool try_lock_for(const chrono::duration<Rep, Period>& rel_time);
#include <boost/thread/locks.hpp>
//#include <boost/thread/shared_mutex.hpp>
#include <boost/detail/lightweight_test.hpp>
bool try_lock_called = false;
struct shared_mutex
{
bool try_lock_upgrade()
{
try_lock_called = !try_lock_called;
return try_lock_called;
}
void unlock_upgrade()
{
}
};
shared_mutex m;
int main()
{
boost::upgrade_lock<shared_mutex> lk(m, boost::defer_lock);
BOOST_TEST(lk.try_lock() == true);
BOOST_TEST(try_lock_called == true);
BOOST_TEST(lk.owns_lock() == true);
try
{
lk.try_lock();
BOOST_TEST(false);
}
catch (boost::system::system_error& e)
{
BOOST_TEST(e.code().value() == boost::system::errc::resource_deadlock_would_occur);
}
lk.unlock();
BOOST_TEST(lk.try_lock() == false);
BOOST_TEST(try_lock_called == false);
BOOST_TEST(lk.owns_lock() == false);
lk.release();
try
{
lk.try_lock();
BOOST_TEST(false);
}
catch (boost::system::system_error& e)
{
BOOST_TEST(e.code().value() == boost::system::errc::operation_not_permitted);
}
return boost::report_errors();
}

View File

@@ -1,76 +0,0 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// Copyright (C) 2011 Vicente J. Botet Escriba
//
// 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)
// <boost/thread/locks.hpp>
// template <class Mutex> class upgrade_lock;
// template <class Clock, class Duration>
// bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time);
#include <boost/thread/locks.hpp>
#include <boost/thread/shared_mutex.hpp>
#include <boost/detail/lightweight_test.hpp>
bool try_lock_until_called = false;
struct shared_mutex
{
template <class Clock, class Duration>
bool try_lock_upgrade_until(const boost::chrono::time_point<Clock, Duration>& abs_time)
{
typedef boost::chrono::milliseconds ms;
BOOST_TEST(Clock::now() - abs_time < ms(5));
try_lock_until_called = !try_lock_until_called;
return try_lock_until_called;
}
void unlock_upgrade()
{
}
};
shared_mutex m;
int main()
{
typedef boost::chrono::steady_clock Clock;
boost::upgrade_lock<shared_mutex> lk(m, boost::defer_lock);
BOOST_TEST(lk.try_lock_until(Clock::now()) == true);
BOOST_TEST(try_lock_until_called == true);
BOOST_TEST(lk.owns_lock() == true);
try
{
lk.try_lock_until(Clock::now());
BOOST_TEST(false);
}
catch (boost::system::system_error& e)
{
BOOST_TEST(e.code().value() == boost::system::errc::resource_deadlock_would_occur);
}
lk.unlock();
BOOST_TEST(lk.try_lock_until(Clock::now()) == false);
BOOST_TEST(try_lock_until_called == false);
BOOST_TEST(lk.owns_lock() == false);
lk.release();
try
{
lk.try_lock_until(Clock::now());
BOOST_TEST(false);
}
catch (boost::system::system_error& e)
{
BOOST_TEST(e.code().value() == boost::system::errc::operation_not_permitted);
}
return boost::report_errors();
}

View File

@@ -1,69 +0,0 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// Copyright (C) 2011 Vicente J. Botet Escriba
//
// 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)
// <boost/thread/locks.hpp>
// template <class Mutex> class upgrade_lock;
// template <class Rep, class Period>
// bool try_lock_for(const chrono::duration<Rep, Period>& rel_time);
#include <boost/thread/locks.hpp>
//#include <boost/thread/shared_mutex.hpp>
#include <boost/detail/lightweight_test.hpp>
bool unlock_called = false;
struct shared_mutex
{
void lock_upgrade()
{
}
void unlock_upgrade()
{
unlock_called = true;
}
};
shared_mutex m;
int main()
{
boost::upgrade_lock<shared_mutex> lk(m);
lk.unlock();
BOOST_TEST(unlock_called == true);
BOOST_TEST(lk.owns_lock() == false);
try
{
lk.unlock();
BOOST_TEST(false);
}
catch (boost::system::system_error& e)
{
BOOST_TEST(e.code().value() == boost::system::errc::operation_not_permitted);
}
lk.release();
try
{
lk.unlock();
BOOST_TEST(false);
}
catch (boost::system::system_error& e)
{
BOOST_TEST(e.code().value() == boost::system::errc::operation_not_permitted);
}
return boost::report_errors();
}

View File

@@ -1,48 +0,0 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// Copyright (C) 2011 Vicente J. Botet Escriba
//
// 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)
// <boost/thread/locks.hpp>
// template <class Mutex> class upgrade_lock;
// void swap(upgrade_lock& u);
#include <boost/thread/locks.hpp>
#include <boost/detail/lightweight_test.hpp>
struct shared_mutex
{
void lock_upgrade()
{
}
void unlock_upgrade()
{
}
};
shared_mutex m;
int main()
{
boost::upgrade_lock<shared_mutex> lk1(m);
boost::upgrade_lock<shared_mutex> lk2;
lk1.swap(lk2);
BOOST_TEST(lk1.mutex() == 0);
BOOST_TEST(lk1.owns_lock() == false);
BOOST_TEST(lk2.mutex() == &m);
BOOST_TEST(lk2.owns_lock() == true);
return boost::report_errors();
}

View File

@@ -1,47 +0,0 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// Copyright (C) 2011 Vicente J. Botet Escriba
//
// 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)
// <boost/thread/locks.hpp>
// template <class Mutex>
// void swap(upgrade_lock<Mutex>& x, upgrade_lock<Mutex>& y);
#include <boost/thread/locks.hpp>
#include <boost/detail/lightweight_test.hpp>
struct shared_mutex
{
void lock_upgrade()
{
}
void unlock_upgrade()
{
}
};
shared_mutex m;
int main()
{
boost::upgrade_lock<shared_mutex> lk1(m);
boost::upgrade_lock<shared_mutex> lk2;
swap(lk1, lk2);
BOOST_TEST(lk1.mutex() == 0);
BOOST_TEST(lk1.owns_lock() == false);
BOOST_TEST(lk2.mutex() == &m);
BOOST_TEST(lk2.owns_lock() == true);
return boost::report_errors();
}

View File

@@ -1,58 +0,0 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// Copyright (C) 2011 Vicente J. Botet Escriba
//
// 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)
// <boost/thread/locks.hpp>
// template <class Mutex> class upgrade_lock;
// void Mutex* release();
#include <boost/thread/locks.hpp>
#include <boost/detail/lightweight_test.hpp>
struct shared_mutex
{
static int lock_count;
static int unlock_count;
void lock_upgrade()
{
++lock_count;
}
void unlock_upgrade()
{
++unlock_count;
}
};
int shared_mutex::lock_count = 0;
int shared_mutex::unlock_count = 0;
shared_mutex m;
int main()
{
boost::upgrade_lock<shared_mutex> lk(m);
BOOST_TEST(lk.mutex() == &m);
BOOST_TEST(lk.owns_lock() == true);
BOOST_TEST(shared_mutex::lock_count == 1);
BOOST_TEST(shared_mutex::unlock_count == 0);
BOOST_TEST(lk.release() == &m);
BOOST_TEST(lk.mutex() == 0);
BOOST_TEST(lk.owns_lock() == false);
BOOST_TEST(shared_mutex::lock_count == 1);
BOOST_TEST(shared_mutex::unlock_count == 0);
return boost::report_errors();
}

View File

@@ -1,38 +0,0 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// Copyright (C) 2011 Vicente J. Botet Escriba
//
// 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)
// <boost/thread/locks.hpp>
// template <class Mutex> class upgrade_lock;
// Mutex *mutex() const;
#include <boost/thread/locks.hpp>
#include <boost/thread/shared_mutex.hpp>
#include <boost/detail/lightweight_test.hpp>
boost::shared_mutex m;
int main()
{
boost::upgrade_lock<boost::shared_mutex> lk0;
BOOST_TEST(lk0.mutex() == 0);
boost::upgrade_lock<boost::shared_mutex> lk1(m);
BOOST_TEST(lk1.mutex() == &m);
lk1.unlock();
BOOST_TEST(lk1.mutex() == &m);
return boost::report_errors();
}

View File

@@ -1,38 +0,0 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// Copyright (C) 2011 Vicente J. Botet Escriba
//
// 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)
// <boost/thread/locks.hpp>
// template <class Mutex> class upgrade_lock;
// explicit operator bool() const;
#include <boost/thread/locks.hpp>
#include <boost/thread/shared_mutex.hpp>
#include <boost/detail/lightweight_test.hpp>
boost::shared_mutex m;
int main()
{
boost::upgrade_lock < boost::shared_mutex > lk0;
BOOST_TEST(bool(lk0) == false);
boost::upgrade_lock < boost::shared_mutex > lk1(m);
BOOST_TEST(bool(lk1) == true);
lk1.unlock();
BOOST_TEST(bool(lk1) == false);
return boost::report_errors();
}

View File

@@ -1,39 +0,0 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// Copyright (C) 2011 Vicente J. Botet Escriba
//
// 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)
// <boost/thread/locks.hpp>
// template <class Mutex> class upgrade_lock;
// bool owns_lock() const;
#include <boost/thread/locks.hpp>
#include <boost/thread/shared_mutex.hpp>
#include <boost/detail/lightweight_test.hpp>
boost::shared_mutex m;
int main()
{
boost::upgrade_lock<boost::shared_mutex> lk0;
BOOST_TEST(lk0.owns_lock() == false);
boost::upgrade_lock<boost::shared_mutex> lk1(m);
BOOST_TEST(lk1.owns_lock() == true);
lk1.unlock();
BOOST_TEST(lk1.owns_lock() == false);
return boost::report_errors();
}

View File

@@ -1,40 +0,0 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// Copyright (C) 2011 Vicente J. Botet Escriba
//
// 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)
// <boost/thread/mutex.hpp>
// <mutex>
// template <class Mutex>
// class upgrade_lock
// {
// public:
// typedef Mutex mutex_type;
// ...
// };
#include <boost/thread/locks.hpp>
#include <boost/thread/shared_mutex.hpp>
#include <boost/static_assert.hpp>
#include <boost/detail/lightweight_test.hpp>
int main()
{
BOOST_STATIC_ASSERT_MSG((boost::is_same<boost::upgrade_lock<boost::upgrade_mutex>::mutex_type,
boost::upgrade_mutex>::value), "");
return boost::report_errors();
}

View File

@@ -6,6 +6,7 @@
#include <boost/test/unit_test.hpp>
#include <boost/thread/thread.hpp>
#include <boost/thread/shared_mutex.hpp>
//#include <boost/thread/xtime.hpp>
#include "util.inl"
#include "shared_mutex_locking_thread.hpp"

View File

@@ -145,10 +145,8 @@ void test_thread_callable_object_multiple_arguments()
}
callable_multiple_arg func;
// Avoid
// boost/bind/bind.hpp(392) : warning C4244: 'argument' : conversion from 'double' to 'int', possible loss of data
boost::thread callable3(func,"hello",x,1);
boost::thread callable3(func,"hello",x,1.2);
callable3.join();
BOOST_CHECK(callable_multiple_arg::called_three);
BOOST_CHECK_EQUAL(callable_multiple_arg::called_three_arg1,"hello");