|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r82838 - in branches/release: boost/thread boost/thread/detail boost/thread/pthread boost/thread/v2 boost/thread/win32 libs/thread libs/thread/build libs/thread/example libs/thread/src/pthread libs/thread/src/win32 libs/thread/test libs/thread/test/sync/futures/async libs/thread/test/sync/mutual_exclusion/null_mutex libs/thread/test/sync/mutual_exclusion/once/call_once
From: vicente.botet_at_[hidden]
Date: 2013-02-12 13:32:05
Author: viboes
Date: 2013-02-12 13:32:00 EST (Tue, 12 Feb 2013)
New Revision: 82838
URL: http://svn.boost.org/trac/boost/changeset/82838
Log:
Thread: merge from trunk 1.54 - once_atomic; null_mutex
Added:
branches/release/boost/thread/pthread/once_atomic.hpp
- copied, changed from r82540, /trunk/boost/thread/pthread/once_atomic.hpp
branches/release/boost/thread/thread_only.hpp
- copied unchanged from r82827, /trunk/boost/thread/thread_only.hpp
branches/release/boost/thread/v2/shared_mutex.hpp
- copied, changed from r82644, /trunk/boost/thread/v2/shared_mutex.hpp
branches/release/libs/thread/example/perf_shared_mutex.cpp
- copied, changed from r82644, /trunk/libs/thread/example/perf_shared_mutex.cpp
branches/release/libs/thread/src/pthread/once_atomic.cpp
- copied unchanged from r82540, /trunk/libs/thread/src/pthread/once_atomic.cpp
branches/release/libs/thread/test/sync/mutual_exclusion/null_mutex/assign_fail.cpp
- copied unchanged from r82827, /trunk/libs/thread/test/sync/mutual_exclusion/null_mutex/assign_fail.cpp
branches/release/libs/thread/test/sync/mutual_exclusion/null_mutex/copy_fail.cpp
- copied unchanged from r82827, /trunk/libs/thread/test/sync/mutual_exclusion/null_mutex/copy_fail.cpp
branches/release/libs/thread/test/sync/mutual_exclusion/null_mutex/default_pass.cpp
- copied unchanged from r82827, /trunk/libs/thread/test/sync/mutual_exclusion/null_mutex/default_pass.cpp
branches/release/libs/thread/test/sync/mutual_exclusion/null_mutex/lock_pass.cpp
- copied unchanged from r82827, /trunk/libs/thread/test/sync/mutual_exclusion/null_mutex/lock_pass.cpp
branches/release/libs/thread/test/sync/mutual_exclusion/null_mutex/try_lock_for_pass.cpp
- copied unchanged from r82827, /trunk/libs/thread/test/sync/mutual_exclusion/null_mutex/try_lock_for_pass.cpp
branches/release/libs/thread/test/sync/mutual_exclusion/null_mutex/try_lock_pass.cpp
- copied unchanged from r82827, /trunk/libs/thread/test/sync/mutual_exclusion/null_mutex/try_lock_pass.cpp
branches/release/libs/thread/test/sync/mutual_exclusion/null_mutex/try_lock_until_pass.cpp
- copied unchanged from r82827, /trunk/libs/thread/test/sync/mutual_exclusion/null_mutex/try_lock_until_pass.cpp
branches/release/libs/thread/test/sync/mutual_exclusion/once/call_once/call_once_pass.cpp
- copied, changed from r82540, /trunk/libs/thread/test/sync/mutual_exclusion/once/call_once/call_once_pass.cpp
Properties modified:
branches/release/boost/thread/ (props changed)
branches/release/libs/thread/ (props changed)
Text files modified:
branches/release/boost/thread/detail/config.hpp | 27 +
branches/release/boost/thread/detail/invoke.hpp | 21 +
branches/release/boost/thread/future.hpp | 328 +++++++++++++++--
branches/release/boost/thread/null_mutex.hpp | 3
branches/release/boost/thread/once.hpp | 11
branches/release/boost/thread/pthread/once.hpp | 556 +++++++++++++++++++++++++++--
branches/release/boost/thread/pthread/once_atomic.hpp | 152 ++++++++
branches/release/boost/thread/synchronized_value.hpp | 2
branches/release/boost/thread/thread.hpp | 16
branches/release/boost/thread/v2/shared_mutex.hpp | 542 ++++++++++++++++++++++++++++-
branches/release/boost/thread/win32/once.hpp | 723 +++++++++++++++++++++++++++++++++++++--
branches/release/boost/thread/win32/shared_mutex.hpp | 13
branches/release/libs/thread/build/Jamfile.v2 | 9
branches/release/libs/thread/example/future_then.cpp | 5
branches/release/libs/thread/example/once.cpp | 7
branches/release/libs/thread/example/perf_shared_mutex.cpp | 3
branches/release/libs/thread/src/pthread/once.cpp | 11
branches/release/libs/thread/src/pthread/thread.cpp | 7
branches/release/libs/thread/src/win32/thread.cpp | 2
branches/release/libs/thread/test/Jamfile.v2 | 23 +
branches/release/libs/thread/test/sync/futures/async/async_pass.cpp | 135 ++++++
branches/release/libs/thread/test/sync/mutual_exclusion/once/call_once/call_once_pass.cpp | 70 +++
branches/release/libs/thread/test/test_2309.cpp | 11
branches/release/libs/thread/test/test_2741.cpp | 11
branches/release/libs/thread/test/test_4882.cpp | 2
branches/release/libs/thread/test/test_barrier.cpp | 12
branches/release/libs/thread/test/test_condition.cpp | 11
branches/release/libs/thread/test/test_condition_notify_all.cpp | 11
branches/release/libs/thread/test/test_condition_notify_one.cpp | 12
branches/release/libs/thread/test/test_condition_timed_wait_times_out.cpp | 11
branches/release/libs/thread/test/test_futures.cpp | 14
branches/release/libs/thread/test/test_generic_locks.cpp | 11
branches/release/libs/thread/test/test_hardware_concurrency.cpp | 11
branches/release/libs/thread/test/test_lock_concept.cpp | 12
branches/release/libs/thread/test/test_move_function.cpp | 11
branches/release/libs/thread/test/test_mutex.cpp | 11
branches/release/libs/thread/test/test_once.cpp | 11
branches/release/libs/thread/test/test_shared_mutex.cpp | 11
branches/release/libs/thread/test/test_shared_mutex_part_2.cpp | 12
branches/release/libs/thread/test/test_shared_mutex_timed_locks.cpp | 11
branches/release/libs/thread/test/test_shared_mutex_timed_locks_chrono.cpp | 12
branches/release/libs/thread/test/test_thread.cpp | 13
branches/release/libs/thread/test/test_thread_exit.cpp | 11
branches/release/libs/thread/test/test_thread_id.cpp | 11
branches/release/libs/thread/test/test_thread_launching.cpp | 12
branches/release/libs/thread/test/test_thread_move.cpp | 12
branches/release/libs/thread/test/test_thread_move_return.cpp | 12
branches/release/libs/thread/test/test_thread_return_local.cpp | 12
branches/release/libs/thread/test/test_tss.cpp | 14
branches/release/libs/thread/test/test_xtime.cpp | 14
50 files changed, 2447 insertions(+), 538 deletions(-)
Modified: branches/release/boost/thread/detail/config.hpp
==============================================================================
--- branches/release/boost/thread/detail/config.hpp (original)
+++ branches/release/boost/thread/detail/config.hpp 2013-02-12 13:32:00 EST (Tue, 12 Feb 2013)
@@ -109,6 +109,22 @@
#define BOOST_THREAD_USES_CHRONO
#endif
+#if ! defined BOOST_THREAD_DONT_USE_ATOMIC \
+ && ! defined BOOST_THREAD_USES_ATOMIC
+//#if ! defined __PGIC__
+#define BOOST_THREAD_USES_ATOMIC
+//#endif
+//#define BOOST_THREAD_DONT_USE_ATOMIC
+#endif
+
+#if defined BOOST_THREAD_USES_ATOMIC
+// Andrey Semashev
+#define BOOST_THREAD_ONCE_ATOMIC
+#else
+//#elif ! defined BOOST_NO_CXX11_THREAD_LOCAL && ! defined BOOST_NO_THREAD_LOCAL && ! defined BOOST_THREAD_NO_UINT32_PSEUDO_ATOMIC
+// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2444.html#Appendix
+#define BOOST_THREAD_ONCE_FAST_EPOCH
+#endif
#if BOOST_THREAD_VERSION==2
// PROVIDE_PROMISE_LAZY
@@ -131,7 +147,7 @@
// fixme BOOST_THREAD_PROVIDES_ONCE_CXX11 doesn't works when thread.cpp is compiled BOOST_THREAD_VERSION 3
#if ! defined BOOST_THREAD_DONT_PROVIDE_ONCE_CXX11 \
&& ! defined BOOST_THREAD_PROVIDES_ONCE_CXX11
-#define BOOST_THREAD_DONT_PROVIDE_ONCE_CXX11
+#define BOOST_THREAD_PROVIDES_ONCE_CXX11
#endif
// THREAD_DESTRUCTOR_CALLS_TERMINATE_IF_JOINABLE
@@ -277,6 +293,15 @@
#define BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN
#endif
+// For C++11 call_once interface the compiler MUST support constexpr.
+// Otherwise once_flag would be initialized during dynamic initialization stage, which is not thread-safe.
+#if defined(BOOST_THREAD_PROVIDES_ONCE_CXX11)
+#if defined(BOOST_NO_CXX11_CONSTEXPR)
+#undef BOOST_THREAD_PROVIDES_ONCE_CXX11
+#endif
+#endif
+
+
// BOOST_THREAD_PROVIDES_DEPRECATED_FEATURES_SINCE_V3_0_0 defined by default up to Boost 1.52
// BOOST_THREAD_DONT_PROVIDE_DEPRECATED_FEATURES_SINCE_V3_0_0 defined by default up to Boost 1.55
#if defined BOOST_THREAD_PROVIDES_DEPRECATED_FEATURES_SINCE_V3_0_0
Modified: branches/release/boost/thread/detail/invoke.hpp
==============================================================================
--- branches/release/boost/thread/detail/invoke.hpp (original)
+++ branches/release/boost/thread/detail/invoke.hpp 2013-02-12 13:32:00 EST (Tue, 12 Feb 2013)
@@ -18,6 +18,9 @@
#include <boost/config.hpp>
#include <boost/static_assert.hpp>
+#ifndef BOOST_NO_CXX11_HDR_FUNCTIONAL
+#include <functional>
+#endif
namespace boost
{
@@ -31,6 +34,8 @@
! defined(BOOST_NO_CXX11_AUTO) && \
! defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+#define BOOST_THREAD_PROVIDES_INVOKE
+
// // bullets 1 and 2
template <class Fp, class A0, class ...Args>
@@ -80,6 +85,22 @@
{
return boost::forward<Fp>(f)(boost::forward<Args>(args)...);
}
+#else
+#if ! defined(BOOST_NO_SFINAE_EXPR) && \
+ ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && \
+ ! defined BOOST_NO_CXX11_HDR_FUNCTIONAL && \
+ ! defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+
+ template <class Ret, class Fp, class ...Args>
+ inline
+ Ret invoke(Fp&& f, Args&& ...args)
+ {
+ return std::bind(boost::forward<Fp>(f), boost::forward<Args>(args)...)();
+ }
+
+#define BOOST_THREAD_PROVIDES_INVOKE_RET
+
+#endif
#endif
}
Modified: branches/release/boost/thread/future.hpp
==============================================================================
--- branches/release/boost/thread/future.hpp (original)
+++ branches/release/boost/thread/future.hpp 2013-02-12 13:32:00 EST (Tue, 12 Feb 2013)
@@ -56,7 +56,7 @@
#endif
#include <boost/utility/result_of.hpp>
-#include <boost/thread/thread.hpp>
+#include <boost/thread/thread_only.hpp>
#if defined BOOST_THREAD_PROVIDES_FUTURE
#define BOOST_THREAD_FUTURE future
@@ -505,15 +505,19 @@
struct future_traits
{
typedef boost::scoped_ptr<T> storage_type;
+ struct dummy;
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
typedef T const& source_reference_type;
- struct dummy;
- typedef typename boost::mpl::if_<boost::is_fundamental<T>,dummy&,BOOST_THREAD_RV_REF(T)>::type rvalue_source_type;
- typedef typename boost::mpl::if_<boost::is_fundamental<T>,T,BOOST_THREAD_RV_REF(T)>::type move_dest_type;
+ //typedef typename boost::mpl::if_<boost::is_fundamental<T>,dummy&,BOOST_THREAD_RV_REF(T)>::type rvalue_source_type;
+ typedef BOOST_THREAD_RV_REF(T) rvalue_source_type;
+ //typedef typename boost::mpl::if_<boost::is_fundamental<T>,T,BOOST_THREAD_RV_REF(T)>::type move_dest_type;
+ typedef T move_dest_type;
#elif defined BOOST_THREAD_USES_MOVE
- typedef T& source_reference_type;
- typedef typename boost::mpl::if_<boost::has_move_emulation_enabled<T>,BOOST_THREAD_RV_REF(T),T const&>::type rvalue_source_type;
- typedef typename boost::mpl::if_<boost::has_move_emulation_enabled<T>,BOOST_THREAD_RV_REF(T),T>::type move_dest_type;
+ typedef typename boost::mpl::if_c<boost::is_fundamental<T>::value,T,T&>::type source_reference_type;
+ //typedef typename boost::mpl::if_c<boost::is_fundamental<T>::value,T,BOOST_THREAD_RV_REF(T)>::type rvalue_source_type;
+ //typedef typename boost::mpl::if_c<boost::enable_move_utility_emulation<T>::value,BOOST_THREAD_RV_REF(T),T>::type move_dest_type;
+ typedef BOOST_THREAD_RV_REF(T) rvalue_source_type;
+ typedef T move_dest_type;
#else
typedef T& source_reference_type;
typedef typename boost::mpl::if_<boost::thread_detail::is_convertible<T&,BOOST_THREAD_RV_REF(T) >,BOOST_THREAD_RV_REF(T),T const&>::type rvalue_source_type;
@@ -529,7 +533,11 @@
static void init(storage_type& storage,rvalue_source_type t)
{
+#if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
+ storage.reset(new T(boost::forward<T>(t)));
+#else
storage.reset(new T(static_cast<rvalue_source_type>(t)));
+#endif
}
static void cleanup(storage_type& storage)
@@ -607,7 +615,11 @@
void mark_finished_with_result_internal(rvalue_source_type result_, boost::unique_lock<boost::mutex>& lock)
{
+#if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
+ future_traits<T>::init(result,boost::forward<T>(result_));
+#else
future_traits<T>::init(result,static_cast<rvalue_source_type>(result_));
+#endif
mark_finished_internal(lock);
}
@@ -620,20 +632,27 @@
void mark_finished_with_result(rvalue_source_type result_)
{
boost::unique_lock<boost::mutex> lock(mutex);
+#if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
+ mark_finished_with_result_internal(boost::forward<T>(result_), lock);
+#else
mark_finished_with_result_internal(static_cast<rvalue_source_type>(result_), lock);
+#endif
+
}
move_dest_type get()
{
wait();
- return static_cast<move_dest_type>(*result);
+ //return static_cast<move_dest_type>(*result);
+ return boost::move(*result);
}
shared_future_get_result_type get_sh()
{
wait();
- return static_cast<shared_future_get_result_type>(*result);
+ //return static_cast<shared_future_get_result_type>(*result);
+ return *result;
}
// todo move this to detail::future_object_base
@@ -651,23 +670,26 @@
}
- void set_value_at_thread_exit(const T & result_)
+ void set_value_at_thread_exit(source_reference_type result_)
{
unique_lock<boost::mutex> lk(this->mutex);
if (this->has_value(lk))
{
throw_exception(promise_already_satisfied());
}
- future_traits<T>::init(result,result_);
+ //future_traits<T>::init(result,result_);
+ result.reset(new T(result_));
+
this->is_constructed = true;
get_current_thread_data()->make_ready_at_thread_exit(shared_from_this());
}
- void set_value_at_thread_exit(BOOST_THREAD_RV_REF(T) result_)
+ void set_value_at_thread_exit(rvalue_source_type result_)
{
unique_lock<boost::mutex> lk(this->mutex);
if (this->has_value(lk))
throw_exception(promise_already_satisfied());
result.reset(new T(boost::move(result_)));
+ //result.reset(new T(boost::forward<T>(result_)));
//future_traits<T>::init(result,static_cast<rvalue_source_type>(result_));
this->is_constructed = true;
get_current_thread_data()->make_ready_at_thread_exit(shared_from_this());
@@ -683,11 +705,11 @@
struct future_object<T&>:
detail::future_object_base
{
- typedef typename future_traits<T>::storage_type storage_type;
- typedef typename future_traits<T>::source_reference_type source_reference_type;
- typedef typename future_traits<T>::rvalue_source_type rvalue_source_type;
- typedef typename future_traits<T>::move_dest_type move_dest_type;
- typedef typename future_traits<T>::shared_future_get_result_type shared_future_get_result_type;
+ typedef typename future_traits<T&>::storage_type storage_type;
+ typedef typename future_traits<T&>::source_reference_type source_reference_type;
+ typedef typename future_traits<T&>::rvalue_source_type rvalue_source_type;
+ typedef typename future_traits<T&>::move_dest_type move_dest_type;
+ typedef typename future_traits<T&>::shared_future_get_result_type shared_future_get_result_type;
T* result;
@@ -699,7 +721,7 @@
{
}
- void mark_finished_with_result_internal(T& result_, boost::unique_lock<boost::mutex>& lock)
+ void mark_finished_with_result_internal(source_reference_type result_, boost::unique_lock<boost::mutex>& lock)
{
//future_traits<T>::init(result,result_);
result= &result_;
@@ -708,11 +730,11 @@
// void mark_finished_with_result_internal(rvalue_source_type result_, boost::unique_lock<boost::mutex>& lock)
// {
-// future_traits<T>::init(result,static_cast<rvalue_source_type>(result_));
+// future_traits<T&>::init(result,static_cast<rvalue_source_type>(result_));
// mark_finished_internal(lock);
// }
- void mark_finished_with_result(T& result_)
+ void mark_finished_with_result(source_reference_type result_)
{
boost::unique_lock<boost::mutex> lock(mutex);
mark_finished_with_result_internal(result_, lock);
@@ -866,7 +888,9 @@
boost::unique_lock<boost::mutex> lock(this->mutex);
this->wait_internal(lock);
- return static_cast<move_dest_type>(*(this->result));
+ //return static_cast<move_dest_type>(*(this->result));
+ return boost::move<Rp>(*(this->result));
+
}
static void run(future_async_object* that, BOOST_THREAD_FWD_REF(Fp) f)
@@ -1417,7 +1441,7 @@
BOOST_THREAD_FUTURE& operator=(BOOST_THREAD_RV_REF(BOOST_THREAD_FUTURE) other) BOOST_NOEXCEPT
{
- base_type::operator=(boost::move(static_cast<base_type&>(BOOST_THREAD_RV(other))));
+ this->base_type::operator=(boost::move(static_cast<base_type&>(BOOST_THREAD_RV(other))));
return *this;
}
@@ -1676,7 +1700,11 @@
{
boost::throw_exception(promise_already_satisfied());
}
+#if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
+ future_->mark_finished_with_result_internal(boost::forward<R>(r), lock);
+#else
future_->mark_finished_with_result_internal(static_cast<typename detail::future_traits<R>::rvalue_source_type>(r), lock);
+#endif
}
void set_exception(boost::exception_ptr p)
@@ -2077,6 +2105,7 @@
#endif
}
+
#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
virtual void do_apply(BOOST_THREAD_RV_REF(ArgTypes) ... args)=0;
void apply(BOOST_THREAD_RV_REF(ArgTypes) ... args)
@@ -2186,7 +2215,102 @@
{
try
{
- this->mark_finished_with_result(f());
+#if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
+ R res((f()));
+ this->mark_finished_with_result(boost::move(res));
+#else
+ this->mark_finished_with_result(f());
+#endif
+
+ }
+#endif
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
+ catch(thread_interrupted& )
+ {
+ this->mark_interrupted_finish();
+ }
+#endif
+ catch(...)
+ {
+ this->mark_exceptional_finish();
+ }
+ }
+ };
+
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
+#if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ template<typename F, typename R, typename ...ArgTypes>
+ struct task_object<F, R&(ArgTypes...)>:
+ task_base<R&(ArgTypes...)>
+#else
+ template<typename F, typename R>
+ struct task_object<F, R&()>:
+ task_base<R&()>
+#endif
+#else
+ template<typename F, typename R>
+ struct task_object<F,R&>:
+ task_base<R&>
+#endif
+ {
+ private:
+ task_object(task_object&);
+ public:
+ F f;
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+ task_object(BOOST_THREAD_RV_REF(F) f_):
+ f(boost::forward<F>(f_))
+ {}
+#else
+ task_object(F const& f_):
+ f(f_)
+ {}
+ task_object(BOOST_THREAD_RV_REF(F) f_):
+ f(boost::move(f_)) // TODO forward
+ {}
+#endif
+
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ void do_apply(BOOST_THREAD_RV_REF(ArgTypes) ... args)
+ {
+ try
+ {
+ this->set_value_at_thread_exit(f(boost::forward<ArgTypes>(args)...));
+ }
+#else
+ void do_apply()
+ {
+ try
+ {
+ this->set_value_at_thread_exit(f());
+ }
+#endif
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
+ catch(thread_interrupted& )
+ {
+ this->set_interrupted_at_thread_exit();
+ }
+#endif
+ catch(...)
+ {
+ this->set_exception_at_thread_exit(current_exception());
+ }
+ }
+
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ void do_run(BOOST_THREAD_RV_REF(ArgTypes) ... args)
+ {
+ try
+ {
+ this->mark_finished_with_result(f(boost::forward<ArgTypes>(args)...));
+ }
+#else
+ void do_run()
+ {
+ try
+ {
+ R& res((f()));
+ this->mark_finished_with_result(res);
}
#endif
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
@@ -2202,6 +2326,7 @@
}
};
+
#if defined(BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR)
#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
@@ -2241,7 +2366,91 @@
{
try
{
- this->set_value_at_thread_exit(f());
+ //this->set_value_at_thread_exit(f());
+ R r((f()));
+ this->set_value_at_thread_exit(boost::move(r));
+ }
+#endif
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
+ catch(thread_interrupted& )
+ {
+ this->set_interrupted_at_thread_exit();
+ }
+#endif
+ catch(...)
+ {
+ this->set_exception_at_thread_exit(current_exception());
+ }
+ }
+
+
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ void do_run(BOOST_THREAD_RV_REF(ArgTypes) ... args)
+ {
+ try
+ {
+ this->mark_finished_with_result(f(boost::forward<ArgTypes>(args)...));
+ }
+#else
+ void do_run()
+ {
+ try
+ {
+ //this->set_value_at_thread_exit(f());
+ R res((f()));
+ this->mark_finished_with_result(boost::move(res));
+ }
+#endif
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
+ catch(thread_interrupted& )
+ {
+ this->mark_interrupted_finish();
+ }
+#endif
+ catch(...)
+ {
+ this->mark_exceptional_finish();
+ }
+ }
+ };
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
+#if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ template<typename R, typename ...ArgTypes>
+ struct task_object<R& (*)(ArgTypes...), R&(ArgTypes...)>:
+ task_base<R&(ArgTypes...)>
+#else
+ template<typename R>
+ struct task_object<R& (*)(), R&()>:
+ task_base<R&()>
+#endif
+#else
+ template<typename R>
+ struct task_object<R& (*)(), R&> :
+ task_base<R&>
+#endif
+ {
+ private:
+ task_object(task_object&);
+ public:
+ R& (*f)();
+ task_object(R& (*f_)()):
+ f(f_)
+ {}
+
+
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ void do_apply(BOOST_THREAD_RV_REF(ArgTypes) ... args)
+ {
+ try
+ {
+ this->set_value_at_thread_exit(f(boost::forward<ArgTypes>(args)...));
+ }
+#else
+ void do_apply()
+ {
+ try
+ {
+ this->set_value_at_thread_exit(f());
}
#endif
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
@@ -2691,7 +2900,11 @@
{
// todo use forward
+#if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
+ packaged_task temp(boost::move(other));
+#else
packaged_task temp(static_cast<BOOST_THREAD_RV_REF(packaged_task)>(other));
+#endif
swap(temp);
return *this;
}
@@ -2725,6 +2938,7 @@
else if(!future_obtained)
{
future_obtained=true;
+ //return BOOST_THREAD_MAKE_RV_REF(BOOST_THREAD_FUTURE<R>(task));
return BOOST_THREAD_FUTURE<R>(task);
}
else
@@ -2827,6 +3041,11 @@
////////////////////////////////
// template <class F, class... ArgTypes>
+ // future<R> async(launch policy, F&&, ArgTypes&&...);
+ ////////////////////////////////
+
+ ////////////////////////////////
+ // template <class F, class... ArgTypes>
// future<R> async(F&&, ArgTypes&&...);
////////////////////////////////
@@ -2858,7 +3077,7 @@
{
packaged_task_type pt( f );
- BOOST_THREAD_FUTURE<R> ret = pt.get_future();
+ BOOST_THREAD_FUTURE<R> ret = BOOST_THREAD_MAKE_RV_REF(pt.get_future());
#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
boost::thread( boost::move(pt), boost::forward<ArgTypes>(args)... ).detach();
#else
@@ -2878,12 +3097,6 @@
}
}
- template <class R>
- BOOST_THREAD_FUTURE<R>
- async(R(*f)())
- {
- return BOOST_THREAD_MAKE_RV_REF(async(launch(launch::any), f));
- }
#endif
#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
@@ -2912,9 +3125,6 @@
typedef typename boost::result_of<typename decay<F>::type()>::type R;
typedef packaged_task<R()> packaged_task_type;
- typedef detail::async_func<typename decay<F>::type> BF;
- typedef typename BF::result_type Rp;
-
#endif
#else
template <class F>
@@ -2924,8 +3134,6 @@
typedef typename boost::result_of<typename decay<F>::type()>::type R;
typedef packaged_task<R> packaged_task_type;
- typedef detail::async_func<typename decay<F>::type> BF;
- typedef typename BF::result_type Rp;
#endif
if (int(policy) & int(launch::async))
@@ -2973,12 +3181,48 @@
return ::boost::move(ret);
}
}
- template <class F>
- BOOST_THREAD_FUTURE<typename boost::result_of<F()>::type>
- async(BOOST_THREAD_RV_REF(F) f)
- {
- return async(launch(launch::any), boost::forward<F>(f));
- }
+
+ ////////////////////////////////
+ // template <class F, class... ArgTypes>
+ // future<R> async(F&&, ArgTypes&&...);
+ ////////////////////////////////
+
+#if defined BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR
+
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ template <class R, class... ArgTypes>
+ BOOST_THREAD_FUTURE<R>
+ async(R(*f)(BOOST_THREAD_FWD_REF(ArgTypes)...), BOOST_THREAD_FWD_REF(ArgTypes)... args)
+ {
+ return async(launch(launch::any), f, boost::forward<ArgTypes>(args)...);
+ }
+#else
+ template <class R>
+ BOOST_THREAD_FUTURE<R>
+ async(R(*f)())
+ {
+ return async(launch(launch::any), f);
+ }
+#endif
+#endif
+
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ template <class F, class ...ArgTypes>
+ BOOST_THREAD_FUTURE<typename boost::result_of<typename decay<F>::type(
+ typename decay<ArgTypes>::type...
+ )>::type>
+ async(BOOST_THREAD_FWD_REF(F) f, BOOST_THREAD_FWD_REF(ArgTypes)... args)
+ {
+ return async(launch(launch::any), boost::forward<F>(f), boost::forward<ArgTypes>(args)...);
+ }
+#else
+ template <class F>
+ BOOST_THREAD_FUTURE<typename boost::result_of<F()>::type>
+ async(BOOST_THREAD_RV_REF(F) f)
+ {
+ return async(launch(launch::any), boost::forward<F>(f));
+ }
+#endif
////////////////////////////////
Modified: branches/release/boost/thread/null_mutex.hpp
==============================================================================
--- branches/release/boost/thread/null_mutex.hpp (original)
+++ branches/release/boost/thread/null_mutex.hpp 2013-02-12 13:32:00 EST (Tue, 12 Feb 2013)
@@ -11,6 +11,7 @@
#ifndef BOOST_THREAD_NULL_MUTEX_HPP
#define BOOST_THREAD_NULL_MUTEX_HPP
+#include <boost/thread/detail/config.hpp>
#include <boost/thread/detail/delete.hpp>
#include <boost/chrono/chrono.hpp>
@@ -28,6 +29,8 @@
BOOST_THREAD_NO_COPYABLE( null_mutex) /*< no copyable >*/
+ null_mutex() {}
+
/// Simulates a mutex lock() operation. Empty function.
void lock()
{
Modified: branches/release/boost/thread/once.hpp
==============================================================================
--- branches/release/boost/thread/once.hpp (original)
+++ branches/release/boost/thread/once.hpp 2013-02-12 13:32:00 EST (Tue, 12 Feb 2013)
@@ -9,11 +9,18 @@
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
+#include <boost/thread/detail/config.hpp>
#include <boost/thread/detail/platform.hpp>
#if defined(BOOST_THREAD_PLATFORM_WIN32)
#include <boost/thread/win32/once.hpp>
#elif defined(BOOST_THREAD_PLATFORM_PTHREAD)
+#if defined BOOST_THREAD_ONCE_FAST_EPOCH
#include <boost/thread/pthread/once.hpp>
+#elif defined BOOST_THREAD_ONCE_ATOMIC
+#include <boost/thread/pthread/once_atomic.hpp>
+#else
+#error "Once Not Implemented"
+#endif
#else
#error "Boost threads unavailable on this platform"
#endif
@@ -24,7 +31,9 @@
{
// template<class Callable, class ...Args> void
// call_once(once_flag& flag, Callable&& func, Args&&... args);
- inline void call_once(void (*func)(),once_flag& flag)
+template<typename Function>
+inline void call_once(Function func,once_flag& flag)
+//inline void call_once(void (*func)(),once_flag& flag)
{
call_once(flag,func);
}
Modified: branches/release/boost/thread/pthread/once.hpp
==============================================================================
--- branches/release/boost/thread/pthread/once.hpp (original)
+++ branches/release/boost/thread/pthread/once.hpp 2013-02-12 13:32:00 EST (Tue, 12 Feb 2013)
@@ -11,11 +11,14 @@
// http://www.boost.org/LICENSE_1_0.txt)
#include <boost/thread/detail/config.hpp>
+#include <boost/thread/detail/move.hpp>
+#include <boost/thread/detail/invoke.hpp>
#include <boost/thread/pthread/pthread_mutex_scoped_lock.hpp>
#include <boost/thread/detail/delete.hpp>
#include <boost/detail/no_exceptions_support.hpp>
+#include <boost/bind.hpp>
#include <boost/assert.hpp>
#include <boost/config/abi_prefix.hpp>
@@ -26,21 +29,32 @@
namespace boost
{
-#define BOOST_ONCE_INITIAL_FLAG_VALUE 0
+ struct once_flag;
+
+ #define BOOST_ONCE_INITIAL_FLAG_VALUE 0
namespace thread_detail
{
-//#ifdef SIG_ATOMIC_MAX
-// typedef sig_atomic_t uintmax_atomic_t;
-// #define BOOST_THREAD_DETAIL_UINTMAX_ATOMIC_MAX_C SIG_ATOMIC_MAX
-//#else
- typedef unsigned long uintmax_atomic_t;
- #define BOOST_THREAD_DETAIL_UINTMAX_ATOMIC_C2(value) value##ul
+ typedef boost::uint32_t uintmax_atomic_t;
+ #define BOOST_THREAD_DETAIL_UINTMAX_ATOMIC_C2(value) value##u
#define BOOST_THREAD_DETAIL_UINTMAX_ATOMIC_MAX_C BOOST_THREAD_DETAIL_UINTMAX_ATOMIC_C2(~0)
-//#endif
+
}
#ifdef BOOST_THREAD_PROVIDES_ONCE_CXX11
+#ifndef BOOST_NO_CXX11_VARIADIC_TEMPLATES
+ template<typename Function, class ...ArgTypes>
+ inline void call_once(once_flag& flag, BOOST_THREAD_RV_REF(Function) f, BOOST_THREAD_RV_REF(ArgTypes)... args);
+#else
+ template<typename Function>
+ inline void call_once(once_flag& flag, Function f);
+ template<typename Function, typename T1>
+ inline void call_once(once_flag& flag, Function f, T1 p1);
+ template<typename Function, typename T1, typename T2>
+ inline void call_once(once_flag& flag, Function f, T1 p1, T2 p2);
+ template<typename Function, typename T1, typename T2, typename T3>
+ inline void call_once(once_flag& flag, Function f, T1 p1, T2 p2, T3 p3);
+#endif
struct once_flag
{
@@ -50,11 +64,26 @@
{}
private:
volatile thread_detail::uintmax_atomic_t epoch;
+
+#ifndef BOOST_NO_CXX11_VARIADIC_TEMPLATES
+ template<typename Function, class ...ArgTypes>
+ friend void call_once(once_flag& flag, BOOST_THREAD_RV_REF(Function) f, BOOST_THREAD_RV_REF(ArgTypes)... args);
+#else
template<typename Function>
- friend
- void call_once(once_flag& flag,Function f);
+ friend void call_once(once_flag& flag, Function f);
+ template<typename Function, typename T1>
+ friend void call_once(once_flag& flag, Function f, T1 p1);
+ template<typename Function, typename T1, typename T2>
+ friend void call_once(once_flag& flag, Function f, T1 p1, T2 p2);
+ template<typename Function, typename T1, typename T2, typename T3>
+ friend void call_once(once_flag& flag, Function f, T1 p1, T2 p2, T3 p3);
+
+#endif
+
};
+#define BOOST_ONCE_INIT once_flag()
+
#else // BOOST_THREAD_PROVIDES_ONCE_CXX11
struct once_flag
@@ -65,59 +94,484 @@
#define BOOST_ONCE_INIT {BOOST_ONCE_INITIAL_FLAG_VALUE}
#endif // BOOST_THREAD_PROVIDES_ONCE_CXX11
- namespace detail
+ namespace thread_detail
{
- BOOST_THREAD_DECL thread_detail::uintmax_atomic_t& get_once_per_thread_epoch();
- BOOST_THREAD_DECL extern thread_detail::uintmax_atomic_t once_global_epoch;
+ BOOST_THREAD_DECL uintmax_atomic_t& get_once_per_thread_epoch();
+ BOOST_THREAD_DECL extern uintmax_atomic_t once_global_epoch;
BOOST_THREAD_DECL extern pthread_mutex_t once_epoch_mutex;
BOOST_THREAD_DECL extern pthread_cond_t once_epoch_cv;
}
// Based on Mike Burrows fast_pthread_once algorithm as described in
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2444.html
- template<typename Function>
- void call_once(once_flag& flag,Function f)
+
+
+#ifndef BOOST_NO_CXX11_VARIADIC_TEMPLATES
+
+
+ template<typename Function, class ...ArgTypes>
+ inline void call_once(once_flag& flag, BOOST_THREAD_RV_REF(Function) f, BOOST_THREAD_RV_REF(ArgTypes)... args)
+ {
+ static thread_detail::uintmax_atomic_t const uninitialized_flag=BOOST_ONCE_INITIAL_FLAG_VALUE;
+ static thread_detail::uintmax_atomic_t const being_initialized=uninitialized_flag+1;
+ thread_detail::uintmax_atomic_t const epoch=flag.epoch;
+ thread_detail::uintmax_atomic_t& this_thread_epoch=thread_detail::get_once_per_thread_epoch();
+
+ if(epoch<this_thread_epoch)
+ {
+ pthread::pthread_mutex_scoped_lock lk(&thread_detail::once_epoch_mutex);
+
+ while(flag.epoch<=being_initialized)
+ {
+ if(flag.epoch==uninitialized_flag)
+ {
+ flag.epoch=being_initialized;
+ BOOST_TRY
+ {
+ pthread::pthread_mutex_scoped_unlock relocker(&thread_detail::once_epoch_mutex);
+#if defined BOOST_THREAD_PROVIDES_ONCE_CXX11
+#if defined BOOST_THREAD_PROVIDES_INVOKE
+ detail::invoke(
+ thread_detail::decay_copy(boost::forward<Function>(f)),
+ thread_detail::decay_copy(boost::forward<ArgTypes>(args))...
+ );
+#elif defined BOOST_THREAD_PROVIDES_INVOKE_RET
+ detail::invoke<void>(
+ thread_detail::decay_copy(boost::forward<Function>(f)),
+ thread_detail::decay_copy(boost::forward<ArgTypes>(args))...
+ );
+#else
+ boost::bind(
+ thread_detail::decay_copy(boost::forward<Function>(f)),
+ thread_detail::decay_copy(boost::forward<ArgTypes>(args))...
+ )();
+#endif
+#else
+ f(
+ thread_detail::decay_copy(boost::forward<ArgTypes>(args))...
+ );
+#endif
+ }
+ BOOST_CATCH (...)
+ {
+ flag.epoch=uninitialized_flag;
+ BOOST_VERIFY(!pthread_cond_broadcast(&thread_detail::once_epoch_cv));
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+ flag.epoch=--thread_detail::once_global_epoch;
+ BOOST_VERIFY(!pthread_cond_broadcast(&thread_detail::once_epoch_cv));
+ }
+ else
+ {
+ while(flag.epoch==being_initialized)
+ {
+ BOOST_VERIFY(!pthread_cond_wait(&thread_detail::once_epoch_cv,&thread_detail::once_epoch_mutex));
+ }
+ }
+ }
+ this_thread_epoch=thread_detail::once_global_epoch;
+
+ }
+ }
+#else
+ template<typename Function>
+ inline void call_once(once_flag& flag, Function f)
+ {
+ static thread_detail::uintmax_atomic_t const uninitialized_flag=BOOST_ONCE_INITIAL_FLAG_VALUE;
+ static thread_detail::uintmax_atomic_t const being_initialized=uninitialized_flag+1;
+ thread_detail::uintmax_atomic_t const epoch=flag.epoch;
+ thread_detail::uintmax_atomic_t& this_thread_epoch=thread_detail::get_once_per_thread_epoch();
+
+ if(epoch<this_thread_epoch)
+ {
+ pthread::pthread_mutex_scoped_lock lk(&thread_detail::once_epoch_mutex);
+
+ while(flag.epoch<=being_initialized)
+ {
+ if(flag.epoch==uninitialized_flag)
+ {
+ flag.epoch=being_initialized;
+ BOOST_TRY
+ {
+ pthread::pthread_mutex_scoped_unlock relocker(&thread_detail::once_epoch_mutex);
+ f();
+ }
+ BOOST_CATCH (...)
+ {
+ flag.epoch=uninitialized_flag;
+ BOOST_VERIFY(!pthread_cond_broadcast(&thread_detail::once_epoch_cv));
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+ flag.epoch=--thread_detail::once_global_epoch;
+ BOOST_VERIFY(!pthread_cond_broadcast(&thread_detail::once_epoch_cv));
+ }
+ else
+ {
+ while(flag.epoch==being_initialized)
+ {
+ BOOST_VERIFY(!pthread_cond_wait(&thread_detail::once_epoch_cv,&thread_detail::once_epoch_mutex));
+ }
+ }
+ }
+ this_thread_epoch=thread_detail::once_global_epoch;
+ }
+ }
+
+ template<typename Function, typename T1>
+ inline void call_once(once_flag& flag, Function f, T1 p1)
+ {
+ static thread_detail::uintmax_atomic_t const uninitialized_flag=BOOST_ONCE_INITIAL_FLAG_VALUE;
+ static thread_detail::uintmax_atomic_t const being_initialized=uninitialized_flag+1;
+ thread_detail::uintmax_atomic_t const epoch=flag.epoch;
+ thread_detail::uintmax_atomic_t& this_thread_epoch=thread_detail::get_once_per_thread_epoch();
+
+ if(epoch<this_thread_epoch)
+ {
+ pthread::pthread_mutex_scoped_lock lk(&thread_detail::once_epoch_mutex);
+
+ while(flag.epoch<=being_initialized)
+ {
+ if(flag.epoch==uninitialized_flag)
+ {
+ flag.epoch=being_initialized;
+ BOOST_TRY
+ {
+ pthread::pthread_mutex_scoped_unlock relocker(&thread_detail::once_epoch_mutex);
+#if defined BOOST_THREAD_PROVIDES_ONCE_CXX11
+ boost::bind(f,p1)();
+#else
+ f(p1);
+#endif
+ }
+ BOOST_CATCH (...)
+ {
+ flag.epoch=uninitialized_flag;
+ BOOST_VERIFY(!pthread_cond_broadcast(&thread_detail::once_epoch_cv));
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+ flag.epoch=--thread_detail::once_global_epoch;
+ BOOST_VERIFY(!pthread_cond_broadcast(&thread_detail::once_epoch_cv));
+ }
+ else
+ {
+ while(flag.epoch==being_initialized)
+ {
+ BOOST_VERIFY(!pthread_cond_wait(&thread_detail::once_epoch_cv,&thread_detail::once_epoch_mutex));
+ }
+ }
+ }
+ this_thread_epoch=thread_detail::once_global_epoch;
+ }
+ }
+ template<typename Function, typename T1, typename T2>
+ inline void call_once(once_flag& flag, Function f, T1 p1, T2 p2)
+ {
+ static thread_detail::uintmax_atomic_t const uninitialized_flag=BOOST_ONCE_INITIAL_FLAG_VALUE;
+ static thread_detail::uintmax_atomic_t const being_initialized=uninitialized_flag+1;
+ thread_detail::uintmax_atomic_t const epoch=flag.epoch;
+ thread_detail::uintmax_atomic_t& this_thread_epoch=thread_detail::get_once_per_thread_epoch();
+
+ if(epoch<this_thread_epoch)
+ {
+ pthread::pthread_mutex_scoped_lock lk(&thread_detail::once_epoch_mutex);
+
+ while(flag.epoch<=being_initialized)
+ {
+ if(flag.epoch==uninitialized_flag)
+ {
+ flag.epoch=being_initialized;
+ BOOST_TRY
+ {
+ pthread::pthread_mutex_scoped_unlock relocker(&thread_detail::once_epoch_mutex);
+#if defined BOOST_THREAD_PROVIDES_ONCE_CXX11
+ boost::bind(f,p1,p2)();
+#else
+ f(p1,p2);
+#endif
+ }
+ BOOST_CATCH (...)
+ {
+ flag.epoch=uninitialized_flag;
+ BOOST_VERIFY(!pthread_cond_broadcast(&thread_detail::once_epoch_cv));
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+ flag.epoch=--thread_detail::once_global_epoch;
+ BOOST_VERIFY(!pthread_cond_broadcast(&thread_detail::once_epoch_cv));
+ }
+ else
+ {
+ while(flag.epoch==being_initialized)
+ {
+ BOOST_VERIFY(!pthread_cond_wait(&thread_detail::once_epoch_cv,&thread_detail::once_epoch_mutex));
+ }
+ }
+ }
+ this_thread_epoch=thread_detail::once_global_epoch;
+ }
+ }
+
+ template<typename Function, typename T1, typename T2, typename T3>
+ inline void call_once(once_flag& flag, Function f, T1 p1, T2 p2, T3 p3)
+ {
+ static thread_detail::uintmax_atomic_t const uninitialized_flag=BOOST_ONCE_INITIAL_FLAG_VALUE;
+ static thread_detail::uintmax_atomic_t const being_initialized=uninitialized_flag+1;
+ thread_detail::uintmax_atomic_t const epoch=flag.epoch;
+ thread_detail::uintmax_atomic_t& this_thread_epoch=thread_detail::get_once_per_thread_epoch();
+
+ if(epoch<this_thread_epoch)
+ {
+ pthread::pthread_mutex_scoped_lock lk(&thread_detail::once_epoch_mutex);
+
+ while(flag.epoch<=being_initialized)
+ {
+ if(flag.epoch==uninitialized_flag)
+ {
+ flag.epoch=being_initialized;
+ BOOST_TRY
+ {
+ pthread::pthread_mutex_scoped_unlock relocker(&thread_detail::once_epoch_mutex);
+#if defined BOOST_THREAD_PROVIDES_ONCE_CXX11
+ boost::bind(f,p1,p2,p3)();
+#else
+ f(p1,p2,p3);
+#endif
+ }
+ BOOST_CATCH (...)
+ {
+ flag.epoch=uninitialized_flag;
+ BOOST_VERIFY(!pthread_cond_broadcast(&thread_detail::once_epoch_cv));
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+ flag.epoch=--thread_detail::once_global_epoch;
+ BOOST_VERIFY(!pthread_cond_broadcast(&thread_detail::once_epoch_cv));
+ }
+ else
+ {
+ while(flag.epoch==being_initialized)
+ {
+ BOOST_VERIFY(!pthread_cond_wait(&thread_detail::once_epoch_cv,&thread_detail::once_epoch_mutex));
+ }
+ }
+ }
+ this_thread_epoch=thread_detail::once_global_epoch;
+ }
+ }
+
+ template<typename Function>
+ inline void call_once(once_flag& flag, BOOST_THREAD_RV_REF(Function) f)
+ {
+ static thread_detail::uintmax_atomic_t const uninitialized_flag=BOOST_ONCE_INITIAL_FLAG_VALUE;
+ static thread_detail::uintmax_atomic_t const being_initialized=uninitialized_flag+1;
+ thread_detail::uintmax_atomic_t const epoch=flag.epoch;
+ thread_detail::uintmax_atomic_t& this_thread_epoch=thread_detail::get_once_per_thread_epoch();
+
+ if(epoch<this_thread_epoch)
+ {
+ pthread::pthread_mutex_scoped_lock lk(&thread_detail::once_epoch_mutex);
+
+ while(flag.epoch<=being_initialized)
+ {
+ if(flag.epoch==uninitialized_flag)
+ {
+ flag.epoch=being_initialized;
+ BOOST_TRY
+ {
+ pthread::pthread_mutex_scoped_unlock relocker(&thread_detail::once_epoch_mutex);
+ f();
+ }
+ BOOST_CATCH (...)
+ {
+ flag.epoch=uninitialized_flag;
+ BOOST_VERIFY(!pthread_cond_broadcast(&thread_detail::once_epoch_cv));
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+ flag.epoch=--thread_detail::once_global_epoch;
+ BOOST_VERIFY(!pthread_cond_broadcast(&thread_detail::once_epoch_cv));
+ }
+ else
+ {
+ while(flag.epoch==being_initialized)
+ {
+ BOOST_VERIFY(!pthread_cond_wait(&thread_detail::once_epoch_cv,&thread_detail::once_epoch_mutex));
+ }
+ }
+ }
+ this_thread_epoch=thread_detail::once_global_epoch;
+ }
+ }
+
+ template<typename Function, typename T1>
+ inline void call_once(once_flag& flag, BOOST_THREAD_RV_REF(Function) f, BOOST_THREAD_RV_REF(T1) p1)
+ {
+ static thread_detail::uintmax_atomic_t const uninitialized_flag=BOOST_ONCE_INITIAL_FLAG_VALUE;
+ static thread_detail::uintmax_atomic_t const being_initialized=uninitialized_flag+1;
+ thread_detail::uintmax_atomic_t const epoch=flag.epoch;
+ thread_detail::uintmax_atomic_t& this_thread_epoch=thread_detail::get_once_per_thread_epoch();
+
+ if(epoch<this_thread_epoch)
+ {
+ pthread::pthread_mutex_scoped_lock lk(&thread_detail::once_epoch_mutex);
+
+ while(flag.epoch<=being_initialized)
+ {
+ if(flag.epoch==uninitialized_flag)
+ {
+ flag.epoch=being_initialized;
+ BOOST_TRY
+ {
+ pthread::pthread_mutex_scoped_unlock relocker(&thread_detail::once_epoch_mutex);
+#if defined BOOST_THREAD_PROVIDES_ONCE_CXX11
+ boost::bind(
+ thread_detail::decay_copy(boost::forward<Function>(f)),
+ thread_detail::decay_copy(boost::forward<T1>(p1))
+ )();
+#else
+ f(
+ thread_detail::decay_copy(boost::forward<T1>(p1))
+ );
+#endif
+ }
+ BOOST_CATCH (...)
+ {
+ flag.epoch=uninitialized_flag;
+ BOOST_VERIFY(!pthread_cond_broadcast(&thread_detail::once_epoch_cv));
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+ flag.epoch=--thread_detail::once_global_epoch;
+ BOOST_VERIFY(!pthread_cond_broadcast(&thread_detail::once_epoch_cv));
+ }
+ else
+ {
+ while(flag.epoch==being_initialized)
+ {
+ BOOST_VERIFY(!pthread_cond_wait(&thread_detail::once_epoch_cv,&thread_detail::once_epoch_mutex));
+ }
+ }
+ }
+ this_thread_epoch=thread_detail::once_global_epoch;
+ }
+ }
+ template<typename Function, typename T1, typename T2>
+ inline void call_once(once_flag& flag, BOOST_THREAD_RV_REF(Function) f, BOOST_THREAD_RV_REF(T1) p1, BOOST_THREAD_RV_REF(T2) p2)
+ {
+ static thread_detail::uintmax_atomic_t const uninitialized_flag=BOOST_ONCE_INITIAL_FLAG_VALUE;
+ static thread_detail::uintmax_atomic_t const being_initialized=uninitialized_flag+1;
+ thread_detail::uintmax_atomic_t const epoch=flag.epoch;
+ thread_detail::uintmax_atomic_t& this_thread_epoch=thread_detail::get_once_per_thread_epoch();
+
+ if(epoch<this_thread_epoch)
{
- static thread_detail::uintmax_atomic_t const uninitialized_flag=BOOST_ONCE_INITIAL_FLAG_VALUE;
- static thread_detail::uintmax_atomic_t const being_initialized=uninitialized_flag+1;
- thread_detail::uintmax_atomic_t const epoch=flag.epoch;
- thread_detail::uintmax_atomic_t& this_thread_epoch=detail::get_once_per_thread_epoch();
-
- if(epoch<this_thread_epoch)
- {
- pthread::pthread_mutex_scoped_lock lk(&detail::once_epoch_mutex);
-
- while(flag.epoch<=being_initialized)
- {
- if(flag.epoch==uninitialized_flag)
- {
- flag.epoch=being_initialized;
- BOOST_TRY
- {
- pthread::pthread_mutex_scoped_unlock relocker(&detail::once_epoch_mutex);
- f();
- }
- BOOST_CATCH (...)
- {
- flag.epoch=uninitialized_flag;
- BOOST_VERIFY(!pthread_cond_broadcast(&detail::once_epoch_cv));
- BOOST_RETHROW
- }
- BOOST_CATCH_END
- flag.epoch=--detail::once_global_epoch;
- BOOST_VERIFY(!pthread_cond_broadcast(&detail::once_epoch_cv));
- }
- else
- {
- while(flag.epoch==being_initialized)
- {
- BOOST_VERIFY(!pthread_cond_wait(&detail::once_epoch_cv,&detail::once_epoch_mutex));
- }
+ pthread::pthread_mutex_scoped_lock lk(&thread_detail::once_epoch_mutex);
+
+ while(flag.epoch<=being_initialized)
+ {
+ if(flag.epoch==uninitialized_flag)
+ {
+ flag.epoch=being_initialized;
+ BOOST_TRY
+ {
+ pthread::pthread_mutex_scoped_unlock relocker(&thread_detail::once_epoch_mutex);
+#if defined BOOST_THREAD_PROVIDES_ONCE_CXX11
+ boost::bind(
+ thread_detail::decay_copy(boost::forward<Function>(f)),
+ thread_detail::decay_copy(boost::forward<T1>(p1)),
+ thread_detail::decay_copy(boost::forward<T1>(p2))
+ )();
+#else
+ f(
+ thread_detail::decay_copy(boost::forward<T1>(p1)),
+ thread_detail::decay_copy(boost::forward<T1>(p2))
+ );
+#endif
+ }
+ BOOST_CATCH (...)
+ {
+ flag.epoch=uninitialized_flag;
+ BOOST_VERIFY(!pthread_cond_broadcast(&thread_detail::once_epoch_cv));
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+ flag.epoch=--thread_detail::once_global_epoch;
+ BOOST_VERIFY(!pthread_cond_broadcast(&thread_detail::once_epoch_cv));
+ }
+ else
+ {
+ while(flag.epoch==being_initialized)
+ {
+ BOOST_VERIFY(!pthread_cond_wait(&thread_detail::once_epoch_cv,&thread_detail::once_epoch_mutex));
}
}
- this_thread_epoch=detail::once_global_epoch;
}
+ this_thread_epoch=thread_detail::once_global_epoch;
}
+ }
+
+ template<typename Function, typename T1, typename T2, typename T3>
+ inline void call_once(once_flag& flag, BOOST_THREAD_RV_REF(Function) f, BOOST_THREAD_RV_REF(T1) p1, BOOST_THREAD_RV_REF(T2) p2, BOOST_THREAD_RV_REF(T3) p3)
+ {
+ static thread_detail::uintmax_atomic_t const uninitialized_flag=BOOST_ONCE_INITIAL_FLAG_VALUE;
+ static thread_detail::uintmax_atomic_t const being_initialized=uninitialized_flag+1;
+ thread_detail::uintmax_atomic_t const epoch=flag.epoch;
+ thread_detail::uintmax_atomic_t& this_thread_epoch=thread_detail::get_once_per_thread_epoch();
+
+ if(epoch<this_thread_epoch)
+ {
+ pthread::pthread_mutex_scoped_lock lk(&thread_detail::once_epoch_mutex);
+
+ while(flag.epoch<=being_initialized)
+ {
+ if(flag.epoch==uninitialized_flag)
+ {
+ flag.epoch=being_initialized;
+ BOOST_TRY
+ {
+ pthread::pthread_mutex_scoped_unlock relocker(&thread_detail::once_epoch_mutex);
+#if defined BOOST_THREAD_PROVIDES_ONCE_CXX11
+ boost::bind(
+ thread_detail::decay_copy(boost::forward<Function>(f)),
+ thread_detail::decay_copy(boost::forward<T1>(p1)),
+ thread_detail::decay_copy(boost::forward<T1>(p2)),
+ thread_detail::decay_copy(boost::forward<T1>(p3))
+ )();
+#else
+ f(
+ thread_detail::decay_copy(boost::forward<T1>(p1)),
+ thread_detail::decay_copy(boost::forward<T1>(p2)),
+ thread_detail::decay_copy(boost::forward<T1>(p3))
+ );
+#endif
+ }
+ BOOST_CATCH (...)
+ {
+ flag.epoch=uninitialized_flag;
+ BOOST_VERIFY(!pthread_cond_broadcast(&thread_detail::once_epoch_cv));
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+ flag.epoch=--thread_detail::once_global_epoch;
+ BOOST_VERIFY(!pthread_cond_broadcast(&thread_detail::once_epoch_cv));
+ }
+ else
+ {
+ while(flag.epoch==being_initialized)
+ {
+ BOOST_VERIFY(!pthread_cond_wait(&thread_detail::once_epoch_cv,&thread_detail::once_epoch_mutex));
+ }
+ }
+ }
+ this_thread_epoch=thread_detail::once_global_epoch;
+ }
+ }
+
+#endif
+
}
#include <boost/config/abi_suffix.hpp>
Copied: branches/release/boost/thread/pthread/once_atomic.hpp (from r82540, /trunk/boost/thread/pthread/once_atomic.hpp)
==============================================================================
--- /trunk/boost/thread/pthread/once_atomic.hpp (original)
+++ branches/release/boost/thread/pthread/once_atomic.hpp 2013-02-12 13:32:00 EST (Tue, 12 Feb 2013)
@@ -14,7 +14,9 @@
#include <boost/cstdint.hpp>
#include <boost/thread/detail/move.hpp>
+#include <boost/thread/detail/invoke.hpp>
#include <boost/detail/no_exceptions_support.hpp>
+#include <boost/bind.hpp>
#include <boost/config/abi_prefix.hpp>
@@ -74,7 +76,28 @@
{
BOOST_TRY
{
- f(boost::forward<ArgTypes>(args)...);
+#if defined BOOST_THREAD_PROVIDES_ONCE_CXX11
+#if defined BOOST_THREAD_PROVIDES_INVOKE
+ detail::invoke(
+ thread_detail::decay_copy(boost::forward<Function>(f)),
+ thread_detail::decay_copy(boost::forward<ArgTypes>(args))...
+ );
+#elif defined BOOST_THREAD_PROVIDES_INVOKE_RET
+ detail::invoke<void>(
+ thread_detail::decay_copy(boost::forward<Function>(f)),
+ thread_detail::decay_copy(boost::forward<ArgTypes>(args))...
+ );
+#else
+ boost::bind(
+ thread_detail::decay_copy(boost::forward<Function>(f)),
+ thread_detail::decay_copy(boost::forward<ArgTypes>(args))...
+ )();
+#endif
+#else
+ f(
+ thread_detail::decay_copy(boost::forward<ArgTypes>(args))...
+ );
+#endif
}
BOOST_CATCH (...)
{
@@ -112,7 +135,11 @@
{
BOOST_TRY
{
+#if defined BOOST_THREAD_PROVIDES_ONCE_CXX11
+ boost::bind(f,p1)();
+#else
f(p1);
+#endif
}
BOOST_CATCH (...)
{
@@ -131,7 +158,11 @@
{
BOOST_TRY
{
- f(p1, p2);
+#if defined BOOST_THREAD_PROVIDES_ONCE_CXX11
+ boost::bind(f,p1,p2)();
+#else
+ f(p1,p2);
+#endif
}
BOOST_CATCH (...)
{
@@ -150,7 +181,30 @@
{
BOOST_TRY
{
- f(p1, p2, p3);
+#if defined BOOST_THREAD_PROVIDES_ONCE_CXX11
+ boost::bind(f,p1,p2,p3)();
+#else
+ f(p1,p2,p3);
+#endif
+ }
+ BOOST_CATCH (...)
+ {
+ thread_detail::rollback_once_region(flag);
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+ thread_detail::commit_once_region(flag);
+ }
+ }
+
+ template<typename Function>
+ inline void call_once(once_flag& flag, BOOST_THREAD_RV_REF(Function) f)
+ {
+ if (thread_detail::enter_once_region(flag))
+ {
+ BOOST_TRY
+ {
+ f();
}
BOOST_CATCH (...)
{
@@ -162,6 +216,98 @@
}
}
+ template<typename Function, typename T1>
+ inline void call_once(once_flag& flag, BOOST_THREAD_RV_REF(Function) f, BOOST_THREAD_RV_REF(T1) p1)
+ {
+ if (thread_detail::enter_once_region(flag))
+ {
+ BOOST_TRY
+ {
+#if defined BOOST_THREAD_PROVIDES_ONCE_CXX11
+ boost::bind(
+ thread_detail::decay_copy(boost::forward<Function>(f)),
+ thread_detail::decay_copy(boost::forward<T1>(p1))
+ )();
+#else
+ f(
+ thread_detail::decay_copy(boost::forward<T1>(p1))
+ );
+#endif
+
+ }
+ BOOST_CATCH (...)
+ {
+ thread_detail::rollback_once_region(flag);
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+ thread_detail::commit_once_region(flag);
+ }
+ }
+ template<typename Function, typename T1, typename T2>
+ inline void call_once(once_flag& flag, BOOST_THREAD_RV_REF(Function) f, BOOST_THREAD_RV_REF(T1) p1, BOOST_THREAD_RV_REF(T2) p2)
+ {
+ if (thread_detail::enter_once_region(flag))
+ {
+ BOOST_TRY
+ {
+#if defined BOOST_THREAD_PROVIDES_ONCE_CXX11
+ boost::bind(
+ thread_detail::decay_copy(boost::forward<Function>(f)),
+ thread_detail::decay_copy(boost::forward<T1>(p1)),
+ thread_detail::decay_copy(boost::forward<T1>(p2))
+ )();
+#else
+ f(
+ thread_detail::decay_copy(boost::forward<T1>(p1)),
+ thread_detail::decay_copy(boost::forward<T1>(p2))
+ );
+#endif
+ }
+ BOOST_CATCH (...)
+ {
+ thread_detail::rollback_once_region(flag);
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+ thread_detail::commit_once_region(flag);
+ }
+ }
+ template<typename Function, typename T1, typename T2, typename T3>
+ inline void call_once(once_flag& flag, BOOST_THREAD_RV_REF(Function) f, BOOST_THREAD_RV_REF(T1) p1, BOOST_THREAD_RV_REF(T2) p2, BOOST_THREAD_RV_REF(T3) p3)
+ {
+ if (thread_detail::enter_once_region(flag))
+ {
+ BOOST_TRY
+ {
+#if defined BOOST_THREAD_PROVIDES_ONCE_CXX11
+ boost::bind(
+ thread_detail::decay_copy(boost::forward<Function>(f)),
+ thread_detail::decay_copy(boost::forward<T1>(p1)),
+ thread_detail::decay_copy(boost::forward<T1>(p2)),
+ thread_detail::decay_copy(boost::forward<T1>(p3))
+ )();
+#else
+ f(
+ thread_detail::decay_copy(boost::forward<T1>(p1)),
+ thread_detail::decay_copy(boost::forward<T1>(p2)),
+ thread_detail::decay_copy(boost::forward<T1>(p3))
+ );
+#endif
+
+ }
+ BOOST_CATCH (...)
+ {
+ thread_detail::rollback_once_region(flag);
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+ thread_detail::commit_once_region(flag);
+ }
+ }
+
+
+
#endif
}
Modified: branches/release/boost/thread/synchronized_value.hpp
==============================================================================
--- branches/release/boost/thread/synchronized_value.hpp (original)
+++ branches/release/boost/thread/synchronized_value.hpp 2013-02-12 13:32:00 EST (Tue, 12 Feb 2013)
@@ -274,7 +274,7 @@
synchronized_value(BOOST_THREAD_RV_REF(synchronized_value) other)
{
strict_lock<lockable_type> lk(other.mtx_);
- value_= boost::move(other);
+ value_= boost::move(other.value);
}
/**
Modified: branches/release/boost/thread/thread.hpp
==============================================================================
--- branches/release/boost/thread/thread.hpp (original)
+++ branches/release/boost/thread/thread.hpp 2013-02-12 13:32:00 EST (Tue, 12 Feb 2013)
@@ -9,22 +9,8 @@
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
-#include <boost/thread/detail/platform.hpp>
-
-#if defined(BOOST_THREAD_PLATFORM_WIN32)
-#include <boost/thread/win32/thread_data.hpp>
-#elif defined(BOOST_THREAD_PLATFORM_PTHREAD)
-#include <boost/thread/pthread/thread_data.hpp>
-#else
-#error "Boost threads unavailable on this platform"
-#endif
-
-#include <boost/thread/detail/thread.hpp>
-#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
-#include <boost/thread/detail/thread_interruption.hpp>
-#endif
+#include <boost/thread/thread_only.hpp>
#include <boost/thread/detail/thread_group.hpp>
-#include <boost/thread/v2/thread.hpp>
#endif
Copied: branches/release/boost/thread/v2/shared_mutex.hpp (from r82644, /trunk/boost/thread/v2/shared_mutex.hpp)
==============================================================================
--- /trunk/boost/thread/v2/shared_mutex.hpp (original)
+++ branches/release/boost/thread/v2/shared_mutex.hpp 2013-02-12 13:32:00 EST (Tue, 12 Feb 2013)
@@ -156,6 +156,7 @@
#include <boost/chrono.hpp>
#include <climits>
#include <boost/system/system_error.hpp>
+#define BOOST_THREAD_INLINE inline
namespace boost {
namespace thread_v2 {
@@ -175,8 +176,8 @@
static const count_t n_readers_ = ~write_entered_;
public:
- shared_mutex();
- ~shared_mutex();
+ BOOST_THREAD_INLINE shared_mutex();
+ BOOST_THREAD_INLINE ~shared_mutex();
#ifndef BOOST_NO_DELETED_FUNCTIONS
shared_mutex(shared_mutex const&) = delete;
@@ -190,8 +191,8 @@
// Exclusive ownership
- void lock();
- bool try_lock();
+ BOOST_THREAD_INLINE void lock();
+ BOOST_THREAD_INLINE bool try_lock();
template <class Rep, class Period>
bool try_lock_for(const boost::chrono::duration<Rep, Period>& rel_time)
{
@@ -201,12 +202,13 @@
bool
try_lock_until(
const boost::chrono::time_point<Clock, Duration>& abs_time);
- void unlock();
+ BOOST_THREAD_INLINE void unlock();
+
// Shared ownership
- void lock_shared();
- bool try_lock_shared();
+ BOOST_THREAD_INLINE void lock_shared();
+ BOOST_THREAD_INLINE bool try_lock_shared();
template <class Rep, class Period>
bool
try_lock_shared_for(const boost::chrono::duration<Rep, Period>& rel_time)
@@ -218,7 +220,22 @@
bool
try_lock_shared_until(
const boost::chrono::time_point<Clock, Duration>& abs_time);
- void unlock_shared();
+ BOOST_THREAD_INLINE void unlock_shared();
+
+#if defined BOOST_THREAD_USES_DATETIME
+ bool timed_lock(system_time const& timeout);
+ template<typename TimeDuration>
+ bool timed_lock(TimeDuration const & relative_time)
+ {
+ return timed_lock(get_system_time()+relative_time);
+ }
+ bool timed_lock_shared(system_time const& timeout);
+ template<typename TimeDuration>
+ bool timed_lock_shared(TimeDuration const & relative_time)
+ {
+ return timed_lock_shared(get_system_time()+relative_time);
+ }
+#endif
};
template <class Clock, class Duration>
@@ -280,6 +297,70 @@
return true;
}
+#if defined BOOST_THREAD_USES_DATETIME
+ bool shared_mutex::timed_lock(system_time const& abs_time)
+ {
+ boost::unique_lock<mutex_t> lk(mut_);
+ if (state_ & write_entered_)
+ {
+ while (true)
+ {
+ bool status = gate1_.timed_wait(lk, abs_time);
+ if ((state_ & write_entered_) == 0)
+ break;
+ if (!status)
+ return false;
+ }
+ }
+ state_ |= write_entered_;
+ if (state_ & n_readers_)
+ {
+ while (true)
+ {
+ bool status = gate2_.timed_wait(lk, abs_time);
+ if ((state_ & n_readers_) == 0)
+ break;
+ if (!status)
+ {
+ state_ &= ~write_entered_;
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+ bool shared_mutex::timed_lock_shared(system_time const& abs_time)
+ {
+ boost::unique_lock<mutex_t> lk(mut_);
+ if (state_ & write_entered_)
+ {
+ while (true)
+ {
+ bool status = gate1_.timed_wait(lk, abs_time);
+ if ((state_ & write_entered_) == 0)
+ break;
+ if (!status )
+ return false;
+ }
+ }
+ state_ |= write_entered_;
+ if (state_ & n_readers_)
+ {
+ while (true)
+ {
+ bool status = gate2_.timed_wait(lk, abs_time);
+ if ((state_ & n_readers_) == 0)
+ break;
+ if (!status)
+ {
+ state_ &= ~write_entered_;
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+#endif
class upgrade_mutex
{
typedef boost::mutex mutex_t;
@@ -297,8 +378,8 @@
public:
- upgrade_mutex();
- ~upgrade_mutex();
+ BOOST_THREAD_INLINE upgrade_mutex();
+ BOOST_THREAD_INLINE ~upgrade_mutex();
#ifndef BOOST_NO_DELETED_FUNCTIONS
upgrade_mutex(const upgrade_mutex&) = delete;
@@ -312,8 +393,8 @@
// Exclusive ownership
- void lock();
- bool try_lock();
+ BOOST_THREAD_INLINE void lock();
+ BOOST_THREAD_INLINE bool try_lock();
template <class Rep, class Period>
bool try_lock_for(const boost::chrono::duration<Rep, Period>& rel_time)
{
@@ -323,12 +404,12 @@
bool
try_lock_until(
const boost::chrono::time_point<Clock, Duration>& abs_time);
- void unlock();
+ BOOST_THREAD_INLINE void unlock();
// Shared ownership
- void lock_shared();
- bool try_lock_shared();
+ BOOST_THREAD_INLINE void lock_shared();
+ BOOST_THREAD_INLINE bool try_lock_shared();
template <class Rep, class Period>
bool
try_lock_shared_for(const boost::chrono::duration<Rep, Period>& rel_time)
@@ -340,12 +421,12 @@
bool
try_lock_shared_until(
const boost::chrono::time_point<Clock, Duration>& abs_time);
- void unlock_shared();
+ BOOST_THREAD_INLINE void unlock_shared();
// Upgrade ownership
- void lock_upgrade();
- bool try_lock_upgrade();
+ BOOST_THREAD_INLINE void lock_upgrade();
+ BOOST_THREAD_INLINE bool try_lock_upgrade();
template <class Rep, class Period>
bool
try_lock_upgrade_for(
@@ -358,11 +439,11 @@
bool
try_lock_upgrade_until(
const boost::chrono::time_point<Clock, Duration>& abs_time);
- void unlock_upgrade();
+ BOOST_THREAD_INLINE void unlock_upgrade();
// Shared <-> Exclusive
- bool try_unlock_shared_and_lock();
+ BOOST_THREAD_INLINE bool try_unlock_shared_and_lock();
template <class Rep, class Period>
bool
try_unlock_shared_and_lock_for(
@@ -375,11 +456,11 @@
bool
try_unlock_shared_and_lock_until(
const boost::chrono::time_point<Clock, Duration>& abs_time);
- void unlock_and_lock_shared();
+ BOOST_THREAD_INLINE void unlock_and_lock_shared();
// Shared <-> Upgrade
- bool try_unlock_shared_and_lock_upgrade();
+ BOOST_THREAD_INLINE bool try_unlock_shared_and_lock_upgrade();
template <class Rep, class Period>
bool
try_unlock_shared_and_lock_upgrade_for(
@@ -392,12 +473,12 @@
bool
try_unlock_shared_and_lock_upgrade_until(
const boost::chrono::time_point<Clock, Duration>& abs_time);
- void unlock_upgrade_and_lock_shared();
+ BOOST_THREAD_INLINE void unlock_upgrade_and_lock_shared();
// Upgrade <-> Exclusive
- void unlock_upgrade_and_lock();
- bool try_unlock_upgrade_and_lock();
+ BOOST_THREAD_INLINE void unlock_upgrade_and_lock();
+ BOOST_THREAD_INLINE bool try_unlock_upgrade_and_lock();
template <class Rep, class Period>
bool
try_unlock_upgrade_and_lock_for(
@@ -410,7 +491,29 @@
bool
try_unlock_upgrade_and_lock_until(
const boost::chrono::time_point<Clock, Duration>& abs_time);
- void unlock_and_lock_upgrade();
+ BOOST_THREAD_INLINE void unlock_and_lock_upgrade();
+
+#if defined BOOST_THREAD_USES_DATETIME
+ inline bool timed_lock(system_time const& abs_time);
+ template<typename TimeDuration>
+ bool timed_lock(TimeDuration const & relative_time)
+ {
+ return timed_lock(get_system_time()+relative_time);
+ }
+ inline bool timed_lock_shared(system_time const& abs_time);
+ template<typename TimeDuration>
+ bool timed_lock_shared(TimeDuration const & relative_time)
+ {
+ return timed_lock_shared(get_system_time()+relative_time);
+ }
+ inline bool timed_lock_upgrade(system_time const& abs_time);
+ template<typename TimeDuration>
+ bool timed_lock_upgrade(TimeDuration const & relative_time)
+ {
+ return timed_lock_upgrade(get_system_time()+relative_time);
+ }
+#endif
+
};
template <class Clock, class Duration>
@@ -497,6 +600,81 @@
return true;
}
+#if defined BOOST_THREAD_USES_DATETIME
+ bool upgrade_mutex::timed_lock(system_time const& abs_time)
+ {
+ boost::unique_lock<mutex_t> lk(mut_);
+ if (state_ & (write_entered_ | upgradable_entered_))
+ {
+ while (true)
+ {
+ bool status = gate1_.timed_wait(lk, abs_time);
+ if ((state_ & (write_entered_ | upgradable_entered_)) == 0)
+ break;
+ if (!status)
+ return false;
+ }
+ }
+ state_ |= write_entered_;
+ if (state_ & n_readers_)
+ {
+ while (true)
+ {
+ bool status = gate2_.timed_wait(lk, abs_time);
+ if ((state_ & n_readers_) == 0)
+ break;
+ if (!status)
+ {
+ state_ &= ~write_entered_;
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+ bool upgrade_mutex::timed_lock_shared(system_time const& abs_time)
+ {
+ boost::unique_lock<mutex_t> lk(mut_);
+ if ((state_ & write_entered_) || (state_ & n_readers_) == n_readers_)
+ {
+ while (true)
+ {
+ bool status = gate1_.timed_wait(lk, abs_time);
+ if ((state_ & write_entered_) == 0 &&
+ (state_ & n_readers_) < n_readers_)
+ break;
+ if (!status)
+ return false;
+ }
+ }
+ count_t num_readers = (state_ & n_readers_) + 1;
+ state_ &= ~n_readers_;
+ state_ |= num_readers;
+ return true;
+ }
+ bool upgrade_mutex::timed_lock_upgrade(system_time const& abs_time)
+ {
+ boost::unique_lock<mutex_t> lk(mut_);
+ if ((state_ & (write_entered_ | upgradable_entered_)) ||
+ (state_ & n_readers_) == n_readers_)
+ {
+ while (true)
+ {
+ bool status = gate1_.timed_wait(lk, abs_time);
+ if ((state_ & (write_entered_ | upgradable_entered_)) == 0 &&
+ (state_ & n_readers_) < n_readers_)
+ break;
+ if (!status)
+ return false;
+ }
+ }
+ count_t num_readers = (state_ & n_readers_) + 1;
+ state_ &= ~n_readers_;
+ state_ |= upgradable_entered_ | num_readers;
+ return true;
+ }
+
+#endif
template <class Clock, class Duration>
bool
upgrade_mutex::try_unlock_shared_and_lock_until(
@@ -560,6 +738,318 @@
return true;
}
+ //////
+ // shared_mutex
+
+ shared_mutex::shared_mutex()
+ : state_(0)
+ {
+ }
+
+ shared_mutex::~shared_mutex()
+ {
+ boost::lock_guard<mutex_t> _(mut_);
+ }
+
+ // Exclusive ownership
+
+ void
+ shared_mutex::lock()
+ {
+ boost::unique_lock<mutex_t> lk(mut_);
+ while (state_ & write_entered_)
+ gate1_.wait(lk);
+ state_ |= write_entered_;
+ while (state_ & n_readers_)
+ gate2_.wait(lk);
+ }
+
+ bool
+ shared_mutex::try_lock()
+ {
+ boost::unique_lock<mutex_t> lk(mut_);
+ if (state_ == 0)
+ {
+ state_ = write_entered_;
+ return true;
+ }
+ return false;
+ }
+
+ void
+ shared_mutex::unlock()
+ {
+ boost::lock_guard<mutex_t> _(mut_);
+ state_ = 0;
+ gate1_.notify_all();
+ }
+
+ // Shared ownership
+
+ void
+ shared_mutex::lock_shared()
+ {
+ boost::unique_lock<mutex_t> lk(mut_);
+ while ((state_ & write_entered_) || (state_ & n_readers_) == n_readers_)
+ gate1_.wait(lk);
+ count_t num_readers = (state_ & n_readers_) + 1;
+ state_ &= ~n_readers_;
+ state_ |= num_readers;
+ }
+
+ bool
+ shared_mutex::try_lock_shared()
+ {
+ boost::unique_lock<mutex_t> lk(mut_);
+ count_t num_readers = state_ & n_readers_;
+ if (!(state_ & write_entered_) && num_readers != n_readers_)
+ {
+ ++num_readers;
+ state_ &= ~n_readers_;
+ state_ |= num_readers;
+ return true;
+ }
+ return false;
+ }
+
+ void
+ shared_mutex::unlock_shared()
+ {
+ boost::lock_guard<mutex_t> _(mut_);
+ count_t num_readers = (state_ & n_readers_) - 1;
+ state_ &= ~n_readers_;
+ state_ |= num_readers;
+ if (state_ & write_entered_)
+ {
+ if (num_readers == 0)
+ gate2_.notify_one();
+ }
+ else
+ {
+ if (num_readers == n_readers_ - 1)
+ gate1_.notify_one();
+ }
+ }
+
+ // upgrade_mutex
+
+ upgrade_mutex::upgrade_mutex()
+ : gate1_(),
+ gate2_(),
+ state_(0)
+ {
+ }
+
+ upgrade_mutex::~upgrade_mutex()
+ {
+ boost::lock_guard<mutex_t> _(mut_);
+ }
+
+ // Exclusive ownership
+
+ void
+ upgrade_mutex::lock()
+ {
+ boost::unique_lock<mutex_t> lk(mut_);
+ while (state_ & (write_entered_ | upgradable_entered_))
+ gate1_.wait(lk);
+ state_ |= write_entered_;
+ while (state_ & n_readers_)
+ gate2_.wait(lk);
+ }
+
+ bool
+ upgrade_mutex::try_lock()
+ {
+ boost::unique_lock<mutex_t> lk(mut_);
+ if (state_ == 0)
+ {
+ state_ = write_entered_;
+ return true;
+ }
+ return false;
+ }
+
+ void
+ upgrade_mutex::unlock()
+ {
+ boost::lock_guard<mutex_t> _(mut_);
+ state_ = 0;
+ gate1_.notify_all();
+ }
+
+ // Shared ownership
+
+ void
+ upgrade_mutex::lock_shared()
+ {
+ boost::unique_lock<mutex_t> lk(mut_);
+ while ((state_ & write_entered_) || (state_ & n_readers_) == n_readers_)
+ gate1_.wait(lk);
+ count_t num_readers = (state_ & n_readers_) + 1;
+ state_ &= ~n_readers_;
+ state_ |= num_readers;
+ }
+
+ bool
+ upgrade_mutex::try_lock_shared()
+ {
+ boost::unique_lock<mutex_t> lk(mut_);
+ count_t num_readers = state_ & n_readers_;
+ if (!(state_ & write_entered_) && num_readers != n_readers_)
+ {
+ ++num_readers;
+ state_ &= ~n_readers_;
+ state_ |= num_readers;
+ return true;
+ }
+ return false;
+ }
+
+ void
+ upgrade_mutex::unlock_shared()
+ {
+ boost::lock_guard<mutex_t> _(mut_);
+ count_t num_readers = (state_ & n_readers_) - 1;
+ state_ &= ~n_readers_;
+ state_ |= num_readers;
+ if (state_ & write_entered_)
+ {
+ if (num_readers == 0)
+ gate2_.notify_one();
+ }
+ else
+ {
+ if (num_readers == n_readers_ - 1)
+ gate1_.notify_one();
+ }
+ }
+
+ // Upgrade ownership
+
+ void
+ upgrade_mutex::lock_upgrade()
+ {
+ boost::unique_lock<mutex_t> lk(mut_);
+ while ((state_ & (write_entered_ | upgradable_entered_)) ||
+ (state_ & n_readers_) == n_readers_)
+ gate1_.wait(lk);
+ count_t num_readers = (state_ & n_readers_) + 1;
+ state_ &= ~n_readers_;
+ state_ |= upgradable_entered_ | num_readers;
+ }
+
+ bool
+ upgrade_mutex::try_lock_upgrade()
+ {
+ boost::unique_lock<mutex_t> lk(mut_);
+ count_t num_readers = state_ & n_readers_;
+ if (!(state_ & (write_entered_ | upgradable_entered_))
+ && num_readers != n_readers_)
+ {
+ ++num_readers;
+ state_ &= ~n_readers_;
+ state_ |= upgradable_entered_ | num_readers;
+ return true;
+ }
+ return false;
+ }
+
+ void
+ upgrade_mutex::unlock_upgrade()
+ {
+ {
+ boost::lock_guard<mutex_t> _(mut_);
+ count_t num_readers = (state_ & n_readers_) - 1;
+ state_ &= ~(upgradable_entered_ | n_readers_);
+ state_ |= num_readers;
+ }
+ gate1_.notify_all();
+ }
+
+ // Shared <-> Exclusive
+
+ bool
+ upgrade_mutex::try_unlock_shared_and_lock()
+ {
+ boost::unique_lock<mutex_t> lk(mut_);
+ if (state_ == 1)
+ {
+ state_ = write_entered_;
+ return true;
+ }
+ return false;
+ }
+
+ void
+ upgrade_mutex::unlock_and_lock_shared()
+ {
+ {
+ boost::lock_guard<mutex_t> _(mut_);
+ state_ = 1;
+ }
+ gate1_.notify_all();
+ }
+
+ // Shared <-> Upgrade
+
+ bool
+ upgrade_mutex::try_unlock_shared_and_lock_upgrade()
+ {
+ boost::unique_lock<mutex_t> lk(mut_);
+ if (!(state_ & (write_entered_ | upgradable_entered_)))
+ {
+ state_ |= upgradable_entered_;
+ return true;
+ }
+ return false;
+ }
+
+ void
+ upgrade_mutex::unlock_upgrade_and_lock_shared()
+ {
+ {
+ boost::lock_guard<mutex_t> _(mut_);
+ state_ &= ~upgradable_entered_;
+ }
+ gate1_.notify_all();
+ }
+
+ // Upgrade <-> Exclusive
+
+ void
+ upgrade_mutex::unlock_upgrade_and_lock()
+ {
+ boost::unique_lock<mutex_t> lk(mut_);
+ count_t num_readers = (state_ & n_readers_) - 1;
+ state_ &= ~(upgradable_entered_ | n_readers_);
+ state_ |= write_entered_ | num_readers;
+ while (state_ & n_readers_)
+ gate2_.wait(lk);
+ }
+
+ bool
+ upgrade_mutex::try_unlock_upgrade_and_lock()
+ {
+ boost::unique_lock<mutex_t> lk(mut_);
+ if (state_ == (upgradable_entered_ | 1))
+ {
+ state_ = write_entered_;
+ return true;
+ }
+ return false;
+ }
+
+ void
+ upgrade_mutex::unlock_and_lock_upgrade()
+ {
+ {
+ boost::lock_guard<mutex_t> _(mut_);
+ state_ = upgradable_entered_ | 1;
+ }
+ gate1_.notify_all();
+ }
+
} // thread_v2
} // boost
Modified: branches/release/boost/thread/win32/once.hpp
==============================================================================
--- branches/release/boost/thread/win32/once.hpp (original)
+++ branches/release/boost/thread/win32/once.hpp 2013-02-12 13:32:00 EST (Tue, 12 Feb 2013)
@@ -19,6 +19,10 @@
#include <boost/thread/win32/thread_primitives.hpp>
#include <boost/thread/win32/interlocked_read.hpp>
#include <boost/detail/no_exceptions_support.hpp>
+#include <boost/thread/detail/move.hpp>
+#include <boost/thread/detail/invoke.hpp>
+
+#include <boost/bind.hpp>
#include <boost/config/abi_prefix.hpp>
@@ -32,6 +36,16 @@
namespace boost
{
+ struct once_flag;
+ namespace detail
+ {
+ struct once_context;
+
+ inline bool enter_once_region(once_flag& flag, once_context& ctx) BOOST_NOEXCEPT;
+ inline void commit_once_region(once_flag& flag, once_context& ctx) BOOST_NOEXCEPT;
+ inline void rollback_once_region(once_flag& flag, once_context& ctx) BOOST_NOEXCEPT;
+ }
+
#ifdef BOOST_THREAD_PROVIDES_ONCE_CXX11
struct once_flag
@@ -40,12 +54,12 @@
BOOST_CONSTEXPR once_flag() BOOST_NOEXCEPT
: status(0), count(0)
{}
- private:
long status;
long count;
- template<typename Function>
- friend
- void call_once(once_flag& flag,Function f);
+ private:
+ friend inline bool enter_once_region(once_flag& flag, detail::once_context& ctx) BOOST_NOEXCEPT;
+ friend inline void commit_once_region(once_flag& flag, detail::once_context& ctx) BOOST_NOEXCEPT;
+ friend inline void rollback_once_region(once_flag& flag, detail::once_context& ctx) BOOST_NOEXCEPT;
};
#define BOOST_ONCE_INIT once_flag()
@@ -136,91 +150,714 @@
::boost::detail::win32::event_initially_reset,
mutex_name);
}
+
+ struct once_context {
+ long const function_complete_flag_value;
+ long const running_value;
+ bool counted;
+ detail::win32::handle_manager event_handle;
+ detail::once_char_type mutex_name[once_mutex_name_length];
+ once_context() :
+ function_complete_flag_value(0xc15730e2),
+ running_value(0x7f0725e3),
+ counted(false)
+ {
+ mutex_name[0]=0;
+ }
+ };
+ enum once_action {try_, break_, continue_};
+
+ inline bool enter_once_region(once_flag& flag, once_context& ctx) BOOST_NOEXCEPT
+ {
+ long status=BOOST_INTERLOCKED_COMPARE_EXCHANGE(&flag.status,ctx.running_value,0);
+ if(!status)
+ {
+ if(!ctx.event_handle)
+ {
+ ctx.event_handle=detail::open_once_event(ctx.mutex_name,&flag);
+ }
+ if(ctx.event_handle)
+ {
+ ::boost::detail::win32::ResetEvent(ctx.event_handle);
+ }
+ return true;
+ }
+ return false;
+ }
+ inline void commit_once_region(once_flag& flag, once_context& ctx) BOOST_NOEXCEPT
+ {
+ if(!ctx.counted)
+ {
+ BOOST_INTERLOCKED_INCREMENT(&flag.count);
+ ctx.counted=true;
+ }
+ BOOST_INTERLOCKED_EXCHANGE(&flag.status,ctx.function_complete_flag_value);
+ if(!ctx.event_handle &&
+ (::boost::detail::interlocked_read_acquire(&flag.count)>1))
+ {
+ ctx.event_handle=detail::create_once_event(ctx.mutex_name,&flag);
+ }
+ if(ctx.event_handle)
+ {
+ ::boost::detail::win32::SetEvent(ctx.event_handle);
+ }
+ }
+ inline void rollback_once_region(once_flag& flag, once_context& ctx) BOOST_NOEXCEPT
+ {
+ BOOST_INTERLOCKED_EXCHANGE(&flag.status,0);
+ if(!ctx.event_handle)
+ {
+ ctx.event_handle=detail::open_once_event(ctx.mutex_name,&flag);
+ }
+ if(ctx.event_handle)
+ {
+ ::boost::detail::win32::SetEvent(ctx.event_handle);
+ }
+ }
}
+#ifndef BOOST_NO_CXX11_VARIADIC_TEMPLATES
+//#if defined(BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR)
+ inline void call_once(once_flag& flag, void (*f)())
+ {
+ // Try for a quick win: if the procedure has already been called
+ // just skip through:
+ detail::once_context ctx;
+ while(::boost::detail::interlocked_read_acquire(&flag.status)
+ !=ctx.function_complete_flag_value)
+ {
+ if(detail::enter_once_region(flag, ctx))
+ {
+ BOOST_TRY
+ {
+ f();
+ }
+ BOOST_CATCH(...)
+ {
+ detail::rollback_once_region(flag, ctx);
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+ detail::commit_once_region(flag, ctx);
+ break;
+ }
+ if(!ctx.counted)
+ {
+ BOOST_INTERLOCKED_INCREMENT(&flag.count);
+ ctx.counted=true;
+ long status=::boost::detail::interlocked_read_acquire(&flag.status);
+ if(status==ctx.function_complete_flag_value)
+ {
+ break;
+ }
+ if(!ctx.event_handle)
+ {
+ ctx.event_handle=detail::create_once_event(ctx.mutex_name,&flag);
+ continue;
+ }
+ }
+ BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObject(
+ ctx.event_handle,::boost::detail::win32::infinite));
+ }
+ }
+//#endif
+ template<typename Function, class ...ArgTypes>
+ inline void call_once(once_flag& flag, BOOST_THREAD_RV_REF(Function) f, BOOST_THREAD_RV_REF(ArgTypes)... args)
+ {
+ // Try for a quick win: if the procedure has already been called
+ // just skip through:
+ detail::once_context ctx;
+ while(::boost::detail::interlocked_read_acquire(&flag.status)
+ !=ctx.function_complete_flag_value)
+ {
+ if(detail::enter_once_region(flag, ctx))
+ {
+ BOOST_TRY
+ {
+#if defined BOOST_THREAD_PROVIDES_ONCE_CXX11
+#if defined BOOST_THREAD_PROVIDES_INVOKE
+ detail::invoke(
+ thread_detail::decay_copy(boost::forward<Function>(f)),
+ thread_detail::decay_copy(boost::forward<ArgTypes>(args))...
+ );
+#elif defined BOOST_THREAD_PROVIDES_INVOKE_RET
+ detail::invoke<void>(
+ thread_detail::decay_copy(boost::forward<Function>(f)),
+ thread_detail::decay_copy(boost::forward<ArgTypes>(args))...
+ );
+#else
+ boost::bind(
+ thread_detail::decay_copy(boost::forward<Function>(f)),
+ thread_detail::decay_copy(boost::forward<ArgTypes>(args))...
+ )();
+#endif
+#else
+ f(
+ thread_detail::decay_copy(boost::forward<ArgTypes>(args))...
+ );
+#endif
+ }
+ BOOST_CATCH(...)
+ {
+ detail::rollback_once_region(flag, ctx);
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+ detail::commit_once_region(flag, ctx);
+ break;
+ }
+ if(!ctx.counted)
+ {
+ BOOST_INTERLOCKED_INCREMENT(&flag.count);
+ ctx.counted=true;
+ long status=::boost::detail::interlocked_read_acquire(&flag.status);
+ if(status==ctx.function_complete_flag_value)
+ {
+ break;
+ }
+ if(!ctx.event_handle)
+ {
+ ctx.event_handle=detail::create_once_event(ctx.mutex_name,&flag);
+ continue;
+ }
+ }
+ BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObject(
+ ctx.event_handle,::boost::detail::win32::infinite));
+ }
+ }
+#else
+#ifndef BOOST_MSVC
template<typename Function>
void call_once(once_flag& flag,Function f)
{
// Try for a quick win: if the procedure has already been called
// just skip through:
- long const function_complete_flag_value=0xc15730e2;
- long const running_value=0x7f0725e3;
- long status;
- bool counted=false;
- detail::win32::handle_manager event_handle;
- detail::once_char_type mutex_name[detail::once_mutex_name_length];
- mutex_name[0]=0;
-
- while((status=::boost::detail::interlocked_read_acquire(&flag.status))
- !=function_complete_flag_value)
+ detail::once_context ctx;
+ while(::boost::detail::interlocked_read_acquire(&flag.status)
+ !=ctx.function_complete_flag_value)
+ {
+ if(detail::enter_once_region(flag, ctx))
+ {
+ BOOST_TRY
+ {
+ f();
+ }
+ BOOST_CATCH(...)
+ {
+ detail::rollback_once_region(flag, ctx);
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+ detail::commit_once_region(flag, ctx);
+ break;
+ }
+ if(!ctx.counted)
+ {
+ BOOST_INTERLOCKED_INCREMENT(&flag.count);
+ ctx.counted=true;
+ long status=::boost::detail::interlocked_read_acquire(&flag.status);
+ if(status==ctx.function_complete_flag_value)
+ {
+ break;
+ }
+ if(!ctx.event_handle)
+ {
+ ctx.event_handle=detail::create_once_event(ctx.mutex_name,&flag);
+ continue;
+ }
+ }
+ BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObject(
+ ctx.event_handle,::boost::detail::win32::infinite));
+ }
+ }
+ template<typename Function, typename T1>
+ void call_once(once_flag& flag,Function f, T1 p1)
+ {
+ // Try for a quick win: if the procedure has already been called
+ // just skip through:
+ detail::once_context ctx;
+ while(::boost::detail::interlocked_read_acquire(&flag.status)
+ !=ctx.function_complete_flag_value)
+ {
+ if(detail::enter_once_region(flag, ctx))
+ {
+ BOOST_TRY
+ {
+#if defined BOOST_THREAD_PROVIDES_ONCE_CXX11
+ boost::bind(f,p1)();
+#else
+ f(p1);
+#endif
+ }
+ BOOST_CATCH(...)
+ {
+ detail::rollback_once_region(flag, ctx);
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+ detail::commit_once_region(flag, ctx);
+ break;
+ }
+ if(!ctx.counted)
+ {
+ BOOST_INTERLOCKED_INCREMENT(&flag.count);
+ ctx.counted=true;
+ long status=::boost::detail::interlocked_read_acquire(&flag.status);
+ if(status==ctx.function_complete_flag_value)
+ {
+ break;
+ }
+ if(!ctx.event_handle)
+ {
+ ctx.event_handle=detail::create_once_event(ctx.mutex_name,&flag);
+ continue;
+ }
+ }
+ BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObject(
+ ctx.event_handle,::boost::detail::win32::infinite));
+ }
+ }
+ template<typename Function, typename T1, typename T2>
+ void call_once(once_flag& flag,Function f, T1 p1, T2 p2)
+ {
+ // Try for a quick win: if the procedure has already been called
+ // just skip through:
+ detail::once_context ctx;
+ while(::boost::detail::interlocked_read_acquire(&flag.status)
+ !=ctx.function_complete_flag_value)
+ {
+ if(detail::enter_once_region(flag, ctx))
+ {
+ BOOST_TRY
+ {
+#if defined BOOST_THREAD_PROVIDES_ONCE_CXX11
+ boost::bind(f,p1,p2)();
+#else
+ f(p1,p2);
+#endif
+ }
+ BOOST_CATCH(...)
+ {
+ detail::rollback_once_region(flag, ctx);
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+ detail::commit_once_region(flag, ctx);
+ break;
+ }
+ if(!ctx.counted)
+ {
+ BOOST_INTERLOCKED_INCREMENT(&flag.count);
+ ctx.counted=true;
+ long status=::boost::detail::interlocked_read_acquire(&flag.status);
+ if(status==ctx.function_complete_flag_value)
+ {
+ break;
+ }
+ if(!ctx.event_handle)
+ {
+ ctx.event_handle=detail::create_once_event(ctx.mutex_name,&flag);
+ continue;
+ }
+ }
+ BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObject(
+ ctx.event_handle,::boost::detail::win32::infinite));
+ }
+ }
+ template<typename Function, typename T1, typename T2, typename T3>
+ void call_once(once_flag& flag,Function f, T1 p1, T2 p2, T3 p3)
+ {
+ // Try for a quick win: if the procedure has already been called
+ // just skip through:
+ detail::once_context ctx;
+ while(::boost::detail::interlocked_read_acquire(&flag.status)
+ !=ctx.function_complete_flag_value)
{
- status=BOOST_INTERLOCKED_COMPARE_EXCHANGE(&flag.status,running_value,0);
- if(!status)
+ if(detail::enter_once_region(flag, ctx))
{
BOOST_TRY
{
- if(!event_handle)
+#if defined BOOST_THREAD_PROVIDES_ONCE_CXX11
+ boost::bind(f,p1,p2,p3)();
+#else
+ f(p1,p2,p3);
+#endif
+ }
+ BOOST_CATCH(...)
+ {
+ detail::rollback_once_region(flag, ctx);
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+ detail::commit_once_region(flag, ctx);
+ break;
+ }
+ if(!ctx.counted)
+ {
+ BOOST_INTERLOCKED_INCREMENT(&flag.count);
+ ctx.counted=true;
+ long status=::boost::detail::interlocked_read_acquire(&flag.status);
+ if(status==ctx.function_complete_flag_value)
+ {
+ break;
+ }
+ if(!ctx.event_handle)
+ {
+ ctx.event_handle=detail::create_once_event(ctx.mutex_name,&flag);
+ continue;
+ }
+ }
+ BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObject(
+ ctx.event_handle,::boost::detail::win32::infinite));
+ }
+ }
+#endif
+#if 1
+#if defined(BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR)
+ inline void call_once(once_flag& flag, void (*f)())
+ {
+ // Try for a quick win: if the procedure has already been called
+ // just skip through:
+ detail::once_context ctx;
+ while(::boost::detail::interlocked_read_acquire(&flag.status)
+ !=ctx.function_complete_flag_value)
+ {
+ if(detail::enter_once_region(flag, ctx))
+ {
+ BOOST_TRY
{
- event_handle=detail::open_once_event(mutex_name,&flag);
+ f();
}
- if(event_handle)
+ BOOST_CATCH(...)
{
- ::boost::detail::win32::ResetEvent(event_handle);
+ detail::rollback_once_region(flag, ctx);
+ BOOST_RETHROW
}
- f();
- if(!counted)
+ BOOST_CATCH_END
+ detail::commit_once_region(flag, ctx);
+ break;
+ }
+ if(!ctx.counted)
+ {
+ BOOST_INTERLOCKED_INCREMENT(&flag.count);
+ ctx.counted=true;
+ long status=::boost::detail::interlocked_read_acquire(&flag.status);
+ if(status==ctx.function_complete_flag_value)
{
- BOOST_INTERLOCKED_INCREMENT(&flag.count);
- counted=true;
+ break;
}
- BOOST_INTERLOCKED_EXCHANGE(&flag.status,function_complete_flag_value);
- if(!event_handle &&
- (::boost::detail::interlocked_read_acquire(&flag.count)>1))
+ if(!ctx.event_handle)
{
- event_handle=detail::create_once_event(mutex_name,&flag);
+ ctx.event_handle=detail::create_once_event(ctx.mutex_name,&flag);
+ continue;
}
- if(event_handle)
+ }
+ BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObject(
+ ctx.event_handle,::boost::detail::win32::infinite));
+ }
+ }
+ template<typename T1>
+ void call_once(once_flag& flag,void (*f)(BOOST_THREAD_RV_REF(T1)), BOOST_THREAD_RV_REF(T1) p1)
+ {
+ // Try for a quick win: if the procedure has already been called
+ // just skip through:
+ detail::once_context ctx;
+ while(::boost::detail::interlocked_read_acquire(&flag.status)
+ !=ctx.function_complete_flag_value)
+ {
+ if(detail::enter_once_region(flag, ctx))
+ {
+ BOOST_TRY
+ {
+ f(
+ thread_detail::decay_copy(boost::forward<T1>(p1))
+ );
+ }
+ BOOST_CATCH(...)
{
- ::boost::detail::win32::SetEvent(event_handle);
+ detail::rollback_once_region(flag, ctx);
+ BOOST_RETHROW
}
+ BOOST_CATCH_END
+ detail::commit_once_region(flag, ctx);
break;
}
- BOOST_CATCH(...)
+ if(!ctx.counted)
+ {
+ BOOST_INTERLOCKED_INCREMENT(&flag.count);
+ ctx.counted=true;
+ long status=::boost::detail::interlocked_read_acquire(&flag.status);
+ if(status==ctx.function_complete_flag_value)
+ {
+ break;
+ }
+ if(!ctx.event_handle)
+ {
+ ctx.event_handle=detail::create_once_event(ctx.mutex_name,&flag);
+ continue;
+ }
+ }
+ BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObject(
+ ctx.event_handle,::boost::detail::win32::infinite));
+ }
+ }
+ template<typename Function, typename T1, typename T2>
+ void call_once(once_flag& flag,void (*f)(BOOST_THREAD_RV_REF(T1),BOOST_THREAD_RV_REF(T2)), BOOST_THREAD_RV_REF(T1) p1, BOOST_THREAD_RV_REF(T2) p2)
+ {
+ // Try for a quick win: if the procedure has already been called
+ // just skip through:
+ detail::once_context ctx;
+ while(::boost::detail::interlocked_read_acquire(&flag.status)
+ !=ctx.function_complete_flag_value)
+ {
+ if(detail::enter_once_region(flag, ctx))
+ {
+ BOOST_TRY
+ {
+ f(
+ thread_detail::decay_copy(boost::forward<T1>(p1)),
+ thread_detail::decay_copy(boost::forward<T1>(p2))
+ );
+ }
+ BOOST_CATCH(...)
+ {
+ detail::rollback_once_region(flag, ctx);
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+ detail::commit_once_region(flag, ctx);
+ break;
+ }
+ if(!ctx.counted)
{
- BOOST_INTERLOCKED_EXCHANGE(&flag.status,0);
- if(!event_handle)
+ BOOST_INTERLOCKED_INCREMENT(&flag.count);
+ ctx.counted=true;
+ long status=::boost::detail::interlocked_read_acquire(&flag.status);
+ if(status==ctx.function_complete_flag_value)
{
- event_handle=detail::open_once_event(mutex_name,&flag);
+ break;
}
- if(event_handle)
+ if(!ctx.event_handle)
{
- ::boost::detail::win32::SetEvent(event_handle);
+ ctx.event_handle=detail::create_once_event(ctx.mutex_name,&flag);
+ continue;
}
+ }
+ BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObject(
+ ctx.event_handle,::boost::detail::win32::infinite));
+ }
+ }
+#endif
+ template<typename Function>
+ void call_once(once_flag& flag,BOOST_THREAD_RV_REF(Function) f)
+ {
+ // Try for a quick win: if the procedure has already been called
+ // just skip through:
+ detail::once_context ctx;
+ while(::boost::detail::interlocked_read_acquire(&flag.status)
+ !=ctx.function_complete_flag_value)
+ {
+ if(detail::enter_once_region(flag, ctx))
+ {
+ BOOST_TRY
+ {
+ f();
+ }
+ BOOST_CATCH(...)
+ {
+ detail::rollback_once_region(flag, ctx);
BOOST_RETHROW
}
BOOST_CATCH_END
+ detail::commit_once_region(flag, ctx);
+ break;
}
+ if(!ctx.counted)
+ {
+ BOOST_INTERLOCKED_INCREMENT(&flag.count);
+ ctx.counted=true;
+ long status=::boost::detail::interlocked_read_acquire(&flag.status);
+ if(status==ctx.function_complete_flag_value)
+ {
+ break;
+ }
+ if(!ctx.event_handle)
+ {
+ ctx.event_handle=detail::create_once_event(ctx.mutex_name,&flag);
+ continue;
+ }
+ }
+ BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObject(
+ ctx.event_handle,::boost::detail::win32::infinite));
+ }
+ }
- if(!counted)
+ template<typename Function, typename T1>
+ void call_once(once_flag& flag,BOOST_THREAD_RV_REF(Function) f, BOOST_THREAD_RV_REF(T1) p1)
+ {
+ // Try for a quick win: if the procedure has already been called
+ // just skip through:
+ detail::once_context ctx;
+ while(::boost::detail::interlocked_read_acquire(&flag.status)
+ !=ctx.function_complete_flag_value)
+ {
+ if(detail::enter_once_region(flag, ctx))
+ {
+ BOOST_TRY
+ {
+#if defined BOOST_THREAD_PROVIDES_ONCE_CXX11
+ boost::bind(
+ thread_detail::decay_copy(boost::forward<Function>(f)),
+ thread_detail::decay_copy(boost::forward<T1>(p1))
+ )();
+#else
+ f(
+ thread_detail::decay_copy(boost::forward<T1>(p1))
+ );
+#endif
+ }
+ BOOST_CATCH(...)
+ {
+ detail::rollback_once_region(flag, ctx);
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+ detail::commit_once_region(flag, ctx);
+ break;
+ }
+ if(!ctx.counted)
{
BOOST_INTERLOCKED_INCREMENT(&flag.count);
- counted=true;
- status=::boost::detail::interlocked_read_acquire(&flag.status);
- if(status==function_complete_flag_value)
+ ctx.counted=true;
+ long status=::boost::detail::interlocked_read_acquire(&flag.status);
+ if(status==ctx.function_complete_flag_value)
{
break;
}
- if(!event_handle)
+ if(!ctx.event_handle)
{
- event_handle=detail::create_once_event(mutex_name,&flag);
+ ctx.event_handle=detail::create_once_event(ctx.mutex_name,&flag);
continue;
}
}
BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObject(
- event_handle,::boost::detail::win32::infinite));
+ ctx.event_handle,::boost::detail::win32::infinite));
}
}
+ template<typename Function, typename T1, typename T2>
+ void call_once(once_flag& flag,BOOST_THREAD_RV_REF(Function) f, BOOST_THREAD_RV_REF(T1) p1, BOOST_THREAD_RV_REF(T2) p2)
+ {
+ // Try for a quick win: if the procedure has already been called
+ // just skip through:
+ detail::once_context ctx;
+ while(::boost::detail::interlocked_read_acquire(&flag.status)
+ !=ctx.function_complete_flag_value)
+ {
+ if(detail::enter_once_region(flag, ctx))
+ {
+ BOOST_TRY
+ {
+#if defined BOOST_THREAD_PROVIDES_ONCE_CXX11
+ boost::bind(
+ thread_detail::decay_copy(boost::forward<Function>(f)),
+ thread_detail::decay_copy(boost::forward<T1>(p1)),
+ thread_detail::decay_copy(boost::forward<T1>(p2))
+ )();
+#else
+ f(
+ thread_detail::decay_copy(boost::forward<T1>(p1)),
+ thread_detail::decay_copy(boost::forward<T1>(p2))
+ );
+#endif
+ }
+ BOOST_CATCH(...)
+ {
+ detail::rollback_once_region(flag, ctx);
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+ detail::commit_once_region(flag, ctx);
+ break;
+ }
+ if(!ctx.counted)
+ {
+ BOOST_INTERLOCKED_INCREMENT(&flag.count);
+ ctx.counted=true;
+ long status=::boost::detail::interlocked_read_acquire(&flag.status);
+ if(status==ctx.function_complete_flag_value)
+ {
+ break;
+ }
+ if(!ctx.event_handle)
+ {
+ ctx.event_handle=detail::create_once_event(ctx.mutex_name,&flag);
+ continue;
+ }
+ }
+ BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObject(
+ ctx.event_handle,::boost::detail::win32::infinite));
+ }
+ }
+ template<typename Function, typename T1, typename T2, typename T3>
+ void call_once(once_flag& flag,BOOST_THREAD_RV_REF(Function) f, BOOST_THREAD_RV_REF(T1) p1, BOOST_THREAD_RV_REF(T2) p2, BOOST_THREAD_RV_REF(T3) p3)
+ {
+ // Try for a quick win: if the procedure has already been called
+ // just skip through:
+ detail::once_context ctx;
+ while(::boost::detail::interlocked_read_acquire(&flag.status)
+ !=ctx.function_complete_flag_value)
+ {
+ if(detail::enter_once_region(flag, ctx))
+ {
+ BOOST_TRY
+ {
+#if defined BOOST_THREAD_PROVIDES_ONCE_CXX11
+ boost::bind(
+ thread_detail::decay_copy(boost::forward<Function>(f)),
+ thread_detail::decay_copy(boost::forward<T1>(p1)),
+ thread_detail::decay_copy(boost::forward<T1>(p2)),
+ thread_detail::decay_copy(boost::forward<T1>(p3))
+ )();
+#else
+ f(
+ thread_detail::decay_copy(boost::forward<T1>(p1)),
+ thread_detail::decay_copy(boost::forward<T1>(p2)),
+ thread_detail::decay_copy(boost::forward<T1>(p3))
+ );
+#endif
+ }
+ BOOST_CATCH(...)
+ {
+ detail::rollback_once_region(flag, ctx);
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+ detail::commit_once_region(flag, ctx);
+ break;
+ }
+ if(!ctx.counted)
+ {
+ BOOST_INTERLOCKED_INCREMENT(&flag.count);
+ ctx.counted=true;
+ long status=::boost::detail::interlocked_read_acquire(&flag.status);
+ if(status==ctx.function_complete_flag_value)
+ {
+ break;
+ }
+ if(!ctx.event_handle)
+ {
+ ctx.event_handle=detail::create_once_event(ctx.mutex_name,&flag);
+ continue;
+ }
+ }
+ BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObject(
+ ctx.event_handle,::boost::detail::win32::infinite));
+ }
+ }
+
+#endif
+#endif
}
#include <boost/config/abi_suffix.hpp>
Modified: branches/release/boost/thread/win32/shared_mutex.hpp
==============================================================================
--- branches/release/boost/thread/win32/shared_mutex.hpp (original)
+++ branches/release/boost/thread/win32/shared_mutex.hpp 2013-02-12 13:32:00 EST (Tue, 12 Feb 2013)
@@ -133,7 +133,11 @@
void lock_shared()
{
+#if defined BOOST_THREAD_USES_DATETIME
BOOST_VERIFY(timed_lock_shared(::boost::detail::get_system_time_sentinel()));
+#else
+ BOOST_VERIFY(try_lock_shared_until(chrono::steady_clock::now()));
+#endif
}
#if defined BOOST_THREAD_USES_DATETIME
@@ -379,14 +383,20 @@
void lock()
{
+#if defined BOOST_THREAD_USES_DATETIME
BOOST_VERIFY(timed_lock(::boost::detail::get_system_time_sentinel()));
+#else
+ BOOST_VERIFY(try_lock_until(chrono::steady_clock::now()));
+#endif
}
+#if defined BOOST_THREAD_USES_DATETIME
template<typename TimeDuration>
bool timed_lock(TimeDuration const & relative_time)
{
return timed_lock(get_system_time()+relative_time);
}
+#endif
bool try_lock()
{
@@ -414,6 +424,7 @@
}
+#if defined BOOST_THREAD_USES_DATETIME
bool timed_lock(boost::system_time const& wait_until)
{
for(;;)
@@ -492,7 +503,7 @@
BOOST_ASSERT(wait_res<2);
}
}
-
+#endif
#ifdef BOOST_THREAD_USES_CHRONO
template <class Rep, class Period>
bool try_lock_for(const chrono::duration<Rep, Period>& rel_time)
Modified: branches/release/libs/thread/build/Jamfile.v2
==============================================================================
--- branches/release/libs/thread/build/Jamfile.v2 (original)
+++ branches/release/libs/thread/build/Jamfile.v2 2013-02-12 13:32:00 EST (Tue, 12 Feb 2013)
@@ -225,11 +225,11 @@
}
}
- if ! <toolset>vacpp in $(properties) || <toolset-vacpp:version>11.1 in $(properties) || <toolset-vacpp:version>12.1.0.1 in $(properties)
+ if ! <toolset>vacpp in $(properties) || <toolset-vacpp:version>11.1 in $(properties) || <toolset-vacpp:version>12.1.0.1 in $(properties) || <toolset-vacpp:version>12.1 in $(properties)
{
result += <library>/boost/chrono//boost_chrono ;
}
-
+
return $(result) ;
}
@@ -254,6 +254,11 @@
}
}
result += <define>BOOST_THREAD_DONT_USE_CHRONO ;
+
+ if <toolset>pgi in $(properties) || <toolset>vacpp in $(properties)
+ {
+ result += <library>/boost/atomic//boost_atomic ;
+ }
return $(result) ;
}
Modified: branches/release/libs/thread/example/future_then.cpp
==============================================================================
--- branches/release/libs/thread/example/future_then.cpp (original)
+++ branches/release/libs/thread/example/future_then.cpp 2013-02-12 13:32:00 EST (Tue, 12 Feb 2013)
@@ -45,11 +45,12 @@
BOOST_THREAD_LOG << "<MAIN" << BOOST_THREAD_END_LOG;
try
{
- boost::future<int> f1 = boost::async(&p1);
+ boost::future<int> f1 = boost::async(boost::launch::async, &p1);
BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
boost::future<int> f2 = f1.then(&p2);
BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
- BOOST_THREAD_LOG << f2.get() << BOOST_THREAD_END_LOG;
+ int i = f2.get();
+ BOOST_THREAD_LOG << i << BOOST_THREAD_END_LOG;
}
catch (std::exception& ex)
{
Modified: branches/release/libs/thread/example/once.cpp
==============================================================================
--- branches/release/libs/thread/example/once.cpp (original)
+++ branches/release/libs/thread/example/once.cpp 2013-02-12 13:32:00 EST (Tue, 12 Feb 2013)
@@ -12,10 +12,11 @@
int value=0;
#ifdef BOOST_THREAD_PROVIDES_ONCE_CXX11
-boost::once_flag once;
+static boost::once_flag once;
+//static boost::once_flag once2 = BOOST_ONCE_INIT;
#else
-boost::once_flag once = BOOST_ONCE_INIT;
-boost::once_flag once2 = once;
+static boost::once_flag once = BOOST_ONCE_INIT;
+//static boost::once_flag once2 = once;
#endif
void init()
Copied: branches/release/libs/thread/example/perf_shared_mutex.cpp (from r82644, /trunk/libs/thread/example/perf_shared_mutex.cpp)
==============================================================================
--- /trunk/libs/thread/example/perf_shared_mutex.cpp (original)
+++ branches/release/libs/thread/example/perf_shared_mutex.cpp 2013-02-12 13:32:00 EST (Tue, 12 Feb 2013)
@@ -8,13 +8,11 @@
// This performance test is based on the performance test provided by maxim.yegorushkin
// at https://svn.boost.org/trac/boost/ticket/7422
-#define BOOST_THREAD_DONT_PROVIDE_INTERRUPTIONS
#define BOOST_THREAD_USES_CHRONO
#include <iostream>
#include <boost/thread/lock_types.hpp>
#include <boost/thread/thread.hpp>
-#include <boost/chrono/stopwatches/simple_stopwatch.hpp>
#include <boost/chrono/chrono_io.hpp>
#include <boost/thread/shared_mutex.hpp>
@@ -41,7 +39,6 @@
unique_lock<shared_mutex> lock(mtx);
}
}
-typedef boost::chrono::simple_stopwatch<> Stopwatch;
int main()
{
Modified: branches/release/libs/thread/src/pthread/once.cpp
==============================================================================
--- branches/release/libs/thread/src/pthread/once.cpp (original)
+++ branches/release/libs/thread/src/pthread/once.cpp 2013-02-12 13:32:00 EST (Tue, 12 Feb 2013)
@@ -3,6 +3,10 @@
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+#include <boost/thread/detail/config.hpp>
+#ifdef BOOST_THREAD_ONCE_ATOMIC
+#include "./once_atomic.cpp"
+#else
#define __STDC_CONSTANT_MACROS
#include <boost/thread/pthread/pthread_mutex_scoped_lock.hpp>
#include <boost/thread/once.hpp>
@@ -13,9 +17,9 @@
namespace boost
{
- namespace detail
+ namespace thread_detail
{
- BOOST_THREAD_DECL thread_detail::uintmax_atomic_t once_global_epoch=BOOST_THREAD_DETAIL_UINTMAX_ATOMIC_MAX_C;
+ BOOST_THREAD_DECL uintmax_atomic_t once_global_epoch=BOOST_THREAD_DETAIL_UINTMAX_ATOMIC_MAX_C;
BOOST_THREAD_DECL pthread_mutex_t once_epoch_mutex=PTHREAD_MUTEX_INITIALIZER;
BOOST_THREAD_DECL pthread_cond_t once_epoch_cv = PTHREAD_COND_INITIALIZER;
@@ -56,7 +60,7 @@
#endif
}
- thread_detail::uintmax_atomic_t& get_once_per_thread_epoch()
+ uintmax_atomic_t& get_once_per_thread_epoch()
{
BOOST_VERIFY(!pthread_once(&epoch_tss_key_flag,create_epoch_tss_key));
void* data=pthread_getspecific(epoch_tss_key);
@@ -71,3 +75,4 @@
}
}
+#endif //
Modified: branches/release/libs/thread/src/pthread/thread.cpp
==============================================================================
--- branches/release/libs/thread/src/pthread/thread.cpp (original)
+++ branches/release/libs/thread/src/pthread/thread.cpp 2013-02-12 13:32:00 EST (Tue, 12 Feb 2013)
@@ -6,10 +6,9 @@
// 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_VERSION 3
#include <boost/thread/detail/config.hpp>
-#include <boost/thread/thread.hpp>
+#include <boost/thread/thread_only.hpp>
#if defined BOOST_THREAD_USES_DATETIME
#include <boost/thread/xtime.hpp>
#endif
@@ -436,7 +435,11 @@
{
# if defined(BOOST_HAS_PTHREAD_DELAY_NP)
+ # if defined(__IBMCPP__)
+ BOOST_VERIFY(!pthread_delay_np(const_cast<timespec*>(&ts)));
+ # else
BOOST_VERIFY(!pthread_delay_np(&ts));
+ # endif
# elif defined(BOOST_HAS_NANOSLEEP)
// nanosleep takes a timespec that is an offset, not
// an absolute time.
Modified: branches/release/libs/thread/src/win32/thread.cpp
==============================================================================
--- branches/release/libs/thread/src/win32/thread.cpp (original)
+++ branches/release/libs/thread/src/win32/thread.cpp 2013-02-12 13:32:00 EST (Tue, 12 Feb 2013)
@@ -14,7 +14,7 @@
#endif
//#define BOOST_THREAD_VERSION 3
-#include <boost/thread/thread.hpp>
+#include <boost/thread/thread_only.hpp>
#include <boost/thread/once.hpp>
#include <boost/thread/tss.hpp>
#include <boost/thread/condition_variable.hpp>
Modified: branches/release/libs/thread/test/Jamfile.v2
==============================================================================
--- branches/release/libs/thread/test/Jamfile.v2 (original)
+++ branches/release/libs/thread/test/Jamfile.v2 2013-02-12 13:32:00 EST (Tue, 12 Feb 2013)
@@ -509,6 +509,15 @@
;
+ #explicit ts_once ;
+ test-suite ts_once
+ :
+ #[ thread-compile-fail ./sync/mutual_exclusion/once/once_flag/assign_fail.cpp : : once_flag__assign_f ]
+ #[ thread-compile-fail ./sync/mutual_exclusion/once/once_flag/copy_fail.cpp : : once_flag__copy_f ]
+ #[ thread-run2-noit ./sync/mutual_exclusion/once/once_flag/default_pass.cpp : once_flag__default_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/once/call_once/call_once_pass.cpp : call_once_p ]
+ ;
+
#explicit ts_mutex ;
test-suite ts_mutex
:
@@ -571,6 +580,19 @@
#[ thread-run2-h ./sync/mutual_exclusion/shared_mutex/default_pass.cpp : shared_mutex__default_p ]
;
+ #explicit ts_null_mutex ;
+ test-suite ts_null_mutex
+ :
+ [ thread-compile-fail ./sync/mutual_exclusion/null_mutex/assign_fail.cpp : : null_mutex__assign_f ]
+ [ thread-compile-fail ./sync/mutual_exclusion/null_mutex/copy_fail.cpp : : null_mutex__copy_f ]
+ [ thread-run2-noit ./sync/mutual_exclusion/null_mutex/default_pass.cpp : null_mutex__default_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/null_mutex/lock_pass.cpp : null_mutex__lock_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/null_mutex/try_lock_for_pass.cpp : null_mutex__try_lock_for_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/null_mutex/try_lock_pass.cpp : null_mutex__try_lock_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/null_mutex/try_lock_until_pass.cpp : null_mutex__try_lock_until_p ]
+ ;
+
+
#explicit ts_this_thread ;
test-suite ts_this_thread
:
@@ -677,7 +699,6 @@
test-suite ts_
:
- #[ thread-run2-noit ./sync/futures/future/then_pass.cpp : future__then_p ]
#[ thread-run ../example/test_so.cpp ]
#[ thread-run ../example/test_so2.cpp ]
Modified: branches/release/libs/thread/test/sync/futures/async/async_pass.cpp
==============================================================================
--- branches/release/libs/thread/test/sync/futures/async/async_pass.cpp (original)
+++ branches/release/libs/thread/test/sync/futures/async/async_pass.cpp 2013-02-12 13:32:00 EST (Tue, 12 Feb 2013)
@@ -25,6 +25,7 @@
//#define BOOST_THREAD_VERSION 3
#define BOOST_THREAD_VERSION 4
+#include <iostream>
#include <boost/thread/future.hpp>
#include <boost/thread/thread.hpp>
#include <boost/thread/detail/memory.hpp>
@@ -56,20 +57,40 @@
public:
typedef int result_type;
+ int value;
+
BOOST_THREAD_MOVABLE_ONLY(MoveOnly)
MoveOnly()
{
+ value=0;
}
MoveOnly(BOOST_THREAD_RV_REF(MoveOnly))
- {}
+ {
+ value=1;
+ }
+ MoveOnly& operator=(BOOST_THREAD_RV_REF(MoveOnly))
+ {
+ value=2;
+ return *this;
+ }
int operator()()
{
boost::this_thread::sleep_for(ms(200));
return 3;
}
+ template <typename OS>
+ friend OS& operator<<(OS& os, MoveOnly const& v)
+ {
+ os << v.value;
+ return os;
+ }
};
+namespace boost {
+BOOST_THREAD_DCL_MOVABLE(MoveOnly)
+}
+
int f0()
{
boost::this_thread::sleep_for(ms(200));
@@ -89,6 +110,19 @@
boost::this_thread::sleep_for(ms(200));
}
+boost::interprocess::unique_ptr<int, boost::default_delete<int> > f3_0()
+{
+ boost::this_thread::sleep_for(ms(200));
+ boost::interprocess::unique_ptr<int, boost::default_delete<int> > r((new int(3)));
+ return boost::move(r);
+}
+MoveOnly f3_1()
+{
+ boost::this_thread::sleep_for(ms(200));
+ MoveOnly r;
+ return boost::move(r);
+}
+
boost::interprocess::unique_ptr<int, boost::default_delete<int> > f3(int i)
{
boost::this_thread::sleep_for(ms(200));
@@ -114,7 +148,6 @@
BOOST_TEST(f.get() == 3);
Clock::time_point t1 = Clock::now();
BOOST_TEST(t1 - t0 < ms(200));
- std::cout << __FILE__ <<"["<<__LINE__<<"] "<< (t1 - t0).count() << std::endl;
} catch (std::exception& ex) {
std::cout << __FILE__ <<"["<<__LINE__<<"]"<<ex.what() << std::endl;
BOOST_TEST(false && "exception thrown");
@@ -285,15 +318,10 @@
{
try {
boost::future<void> f = boost::async(f2);
- std::cout << __FILE__ <<"["<<__LINE__<<"]"<<std::endl;
boost::this_thread::sleep_for(ms(300));
- std::cout << __FILE__ <<"["<<__LINE__<<"]"<<std::endl;
Clock::time_point t0 = Clock::now();
- std::cout << __FILE__ <<"["<<__LINE__<<"]"<<std::endl;
f.get();
- std::cout << __FILE__ <<"["<<__LINE__<<"]"<<std::endl;
Clock::time_point t1 = Clock::now();
- std::cout << __FILE__ <<"["<<__LINE__<<"]"<<std::endl;
BOOST_TEST(t1 - t0 < ms(200));
std::cout << __FILE__ <<"["<<__LINE__<<"] "<< (t1 - t0).count() << std::endl;
} catch (std::exception& ex) {
@@ -356,8 +384,59 @@
}
#endif
- // todo fixme
-#if 0 && defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+
+ std::cout << __FILE__ <<"["<<__LINE__<<"]"<<std::endl;
+ {
+ try {
+ boost::future<MoveOnly> f = boost::async(&f3_1);
+ boost::this_thread::sleep_for(ms(300));
+ Clock::time_point t0 = Clock::now();
+ BOOST_TEST(f.get().value == 1);
+ Clock::time_point t1 = Clock::now();
+ BOOST_TEST(t1 - t0 < ms(200));
+ } catch (std::exception& ex) {
+ std::cout << __FILE__ <<"["<<__LINE__<<"]"<<ex.what() << std::endl;
+ BOOST_TEST(false && "exception thrown");
+ } catch (...) {
+ BOOST_TEST(false && "exception thrown");
+ }
+ }
+ std::cout << __FILE__ <<"["<<__LINE__<<"]"<<std::endl;
+ {
+ try {
+ boost::future<MoveOnly> f;
+ f = boost::async(&f3_1);
+ boost::this_thread::sleep_for(ms(300));
+ Clock::time_point t0 = Clock::now();
+ BOOST_TEST(f.get().value == 1);
+ Clock::time_point t1 = Clock::now();
+ BOOST_TEST(t1 - t0 < ms(200));
+ } catch (std::exception& ex) {
+ std::cout << __FILE__ <<"["<<__LINE__<<"]"<<ex.what() << std::endl;
+ BOOST_TEST(false && "exception thrown");
+ } catch (...) {
+ BOOST_TEST(false && "exception thrown");
+ }
+ }
+ std::cout << __FILE__ <<"["<<__LINE__<<"]"<<std::endl;
+ {
+ try {
+ boost::future<boost::interprocess::unique_ptr<int, boost::default_delete<int> > > f = boost::async(&f3_0);
+ boost::this_thread::sleep_for(ms(300));
+ Clock::time_point t0 = Clock::now();
+ BOOST_TEST(*f.get() == 3);
+ Clock::time_point t1 = Clock::now();
+ BOOST_TEST(t1 - t0 < ms(200));
+ std::cout << __FILE__ <<"["<<__LINE__<<"] "<< (t1 - t0).count() << std::endl;
+ } catch (std::exception& ex) {
+ std::cout << __FILE__ <<"["<<__LINE__<<"]"<<ex.what() << std::endl;
+ BOOST_TEST(false && "exception thrown");
+ } catch (...) {
+ BOOST_TEST(false && "exception thrown");
+ }
+ }
+
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
std::cout << __FILE__ <<"["<<__LINE__<<"]"<<std::endl;
{
try {
@@ -375,10 +454,44 @@
BOOST_TEST(false && "exception thrown");
}
}
+ std::cout << __FILE__ <<"["<<__LINE__<<"]"<<std::endl;
+ {
+ try {
+ boost::future<boost::interprocess::unique_ptr<int, boost::default_delete<int> > > f = boost::async(&f3, 3);
+ boost::this_thread::sleep_for(ms(300));
+ Clock::time_point t0 = Clock::now();
+ BOOST_TEST(*f.get() == 3);
+ Clock::time_point t1 = Clock::now();
+ BOOST_TEST(t1 - t0 < ms(200));
+ std::cout << __FILE__ <<"["<<__LINE__<<"] "<< (t1 - t0).count() << std::endl;
+ } catch (std::exception& ex) {
+ std::cout << __FILE__ <<"["<<__LINE__<<"]"<<ex.what() << std::endl;
+ BOOST_TEST(false && "exception thrown");
+ } catch (...) {
+ BOOST_TEST(false && "exception thrown");
+ }
+ }
#endif
- // todo fixme
-#if 0 && defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ std::cout << __FILE__ <<"["<<__LINE__<<"]"<<std::endl;
+ {
+ try {
+ boost::future<boost::interprocess::unique_ptr<int, boost::default_delete<int> > > f = boost::async(boost::launch::async, &f4, boost::interprocess::unique_ptr<int, boost::default_delete<int> >(new int(3)));
+ boost::this_thread::sleep_for(ms(300));
+ Clock::time_point t0 = Clock::now();
+ BOOST_TEST(*f.get() == 3);
+ Clock::time_point t1 = Clock::now();
+ BOOST_TEST(t1 - t0 < ms(200));
+ std::cout << __FILE__ <<"["<<__LINE__<<"] "<< (t1 - t0).count() << std::endl;
+ } catch (std::exception& ex) {
+ std::cout << __FILE__ <<"["<<__LINE__<<"]"<<ex.what() << std::endl;
+ BOOST_TEST(false && "exception thrown");
+ } catch (...) {
+ BOOST_TEST(false && "exception thrown");
+ }
+ }
+ std::cout << __FILE__ <<"["<<__LINE__<<"]"<<std::endl;
{
try {
boost::future<boost::interprocess::unique_ptr<int, boost::default_delete<int> > > f = boost::async(&f4, boost::interprocess::unique_ptr<int, boost::default_delete<int> >(new int(3)));
Copied: branches/release/libs/thread/test/sync/mutual_exclusion/once/call_once/call_once_pass.cpp (from r82540, /trunk/libs/thread/test/sync/mutual_exclusion/once/call_once/call_once_pass.cpp)
==============================================================================
--- /trunk/libs/thread/test/sync/mutual_exclusion/once/call_once/call_once_pass.cpp (original)
+++ branches/release/libs/thread/test/sync/mutual_exclusion/once/call_once/call_once_pass.cpp 2013-02-12 13:32:00 EST (Tue, 12 Feb 2013)
@@ -17,9 +17,11 @@
// struct once_flag;
// template<class Callable, class ...Args>
-// void call_once(once_flag& flag, Callable func, Args&&... args);
+// void call_once(once_flag& flag, Callable&& func, Args&&... args);
//#define BOOST_THREAD_VERSION 4
+#define BOOST_THREAD_USES_MOVE
+#define BOOST_THREAD_PROVIDES_ONCE_CXX11
#include <boost/thread/once.hpp>
#include <boost/thread/thread.hpp>
@@ -73,13 +75,13 @@
}
}
-#if ! defined BOOST_NO_CXX11_VARIADIC_TEMPLATES && defined(BOOST_THREAD_PLATFORM_PTHREAD)
-
struct init1
{
static int called;
+ typedef void result_type;
void operator()(int i) {called += i;}
+ void operator()(int i) const {called += i;}
};
int init1::called = 0;
@@ -91,10 +93,35 @@
boost::call_once(flg1, init1(), 1);
}
+boost::once_flag flg1_member BOOST_INIT_ONCE_INIT;
+
+struct init1_member
+{
+ static int called;
+ typedef void result_type;
+ void call(int i) {
+ called += i;
+ }
+};
+int init1_member::called = 0;
+
+//#if defined BOOST_THREAD_PLATFORM_PTHREAD
+void f1_member()
+{
+ init1_member o;
+#if defined BOOST_THREAD_PROVIDES_ONCE_CXX11
+ boost::call_once(flg1_member, &init1_member::call, o, 1);
+#else
+ boost::call_once(flg1_member, boost::bind(&init1_member::call, o, 1));
+#endif
+}
+//#endif
struct init2
{
static int called;
+ typedef void result_type;
+ void operator()(int i, int j) {called += i + j;}
void operator()(int i, int j) const {called += i + j;}
};
@@ -108,8 +135,6 @@
boost::call_once(flg2, init2(), 4, 5);
}
-#endif // BOOST_NO_CXX11_VARIADIC_TEMPLATES
-
boost::once_flag flg41 BOOST_INIT_ONCE_INIT;
boost::once_flag flg42 BOOST_INIT_ONCE_INIT;
@@ -142,11 +167,11 @@
boost::call_once(flg41, init41);
}
-#ifndef BOOST_NO_CXX11_VARIADIC_TEMPLATES
-
class MoveOnly
{
public:
+ typedef void result_type;
+
BOOST_THREAD_MOVABLE_ONLY(MoveOnly)
MoveOnly()
{
@@ -157,10 +182,14 @@
void operator()(BOOST_THREAD_RV_REF(MoveOnly))
{
}
+ void operator()(int)
+ {
+ }
+ void operator()()
+ {
+ }
};
-#endif
-
int main()
{
// check basic functionality
@@ -189,7 +218,6 @@
BOOST_TEST(init41_called == 1);
BOOST_TEST(init42_called == 1);
}
-#if ! defined BOOST_NO_CXX11_VARIADIC_TEMPLATES && defined(BOOST_THREAD_PLATFORM_PTHREAD)
// check functors with 1 arg
{
boost::thread t0(f1);
@@ -206,11 +234,31 @@
t1.join();
BOOST_TEST(init2::called == 5);
}
+
+ // check member function with 1 arg
+ {
+ boost::thread t0(f1_member);
+ boost::thread t1(f1_member);
+ t0.join();
+ t1.join();
+ BOOST_TEST(init1_member::called == 1);
+ }
+#if defined BOOST_THREAD_PLATFORM_PTHREAD || (__GNUC__*10000 + __GNUC_MINOR__*100 + __GNUC_PATCHLEVEL__ > 40600)
+ {
+ boost::once_flag f BOOST_INIT_ONCE_INIT;
+ boost::call_once(f, MoveOnly());
+ }
+ {
+ boost::once_flag f BOOST_INIT_ONCE_INIT;
+ boost::call_once(f, MoveOnly(), 1);
+ }
+#endif
+#if defined BOOST_THREAD_PROVIDES_INVOKE
{
boost::once_flag f BOOST_INIT_ONCE_INIT;
boost::call_once(f, MoveOnly(), MoveOnly());
}
-#endif // BOOST_NO_CXX11_VARIADIC_TEMPLATES
+#endif // BOOST_THREAD_PLATFORM_PTHREAD
return boost::report_errors();
}
Modified: branches/release/libs/thread/test/test_2309.cpp
==============================================================================
--- branches/release/libs/thread/test/test_2309.cpp (original)
+++ branches/release/libs/thread/test/test_2309.cpp 2013-02-12 13:32:00 EST (Tue, 12 Feb 2013)
@@ -71,15 +71,4 @@
return tests;
}
-void remove_unused_warning()
-{
- //../../../boost/test/results_collector.hpp:40:13: warning: unused function 'first_failed_assertion' [-Wunused-function]
- //(void)first_failed_assertion;
-
- //../../../boost/test/tools/floating_point_comparison.hpp:304:25: warning: unused variable 'check_is_close' [-Wunused-variable]
- //../../../boost/test/tools/floating_point_comparison.hpp:326:25: warning: unused variable 'check_is_small' [-Wunused-variable]
- (void)boost::test_tools::check_is_close;
- (void)boost::test_tools::check_is_small;
-
-}
Modified: branches/release/libs/thread/test/test_2741.cpp
==============================================================================
--- branches/release/libs/thread/test/test_2741.cpp (original)
+++ branches/release/libs/thread/test/test_2741.cpp 2013-02-12 13:32:00 EST (Tue, 12 Feb 2013)
@@ -86,15 +86,4 @@
return test;
}
-void remove_unused_warning()
-{
- //../../../boost/test/results_collector.hpp:40:13: warning: unused function 'first_failed_assertion' [-Wunused-function]
- //(void)first_failed_assertion;
-
- //../../../boost/test/tools/floating_point_comparison.hpp:304:25: warning: unused variable 'check_is_close' [-Wunused-variable]
- //../../../boost/test/tools/floating_point_comparison.hpp:326:25: warning: unused variable 'check_is_small' [-Wunused-variable]
- (void)boost::test_tools::check_is_close;
- (void)boost::test_tools::check_is_small;
-
-}
Modified: branches/release/libs/thread/test/test_4882.cpp
==============================================================================
--- branches/release/libs/thread/test/test_4882.cpp (original)
+++ branches/release/libs/thread/test/test_4882.cpp 2013-02-12 13:32:00 EST (Tue, 12 Feb 2013)
@@ -4,7 +4,7 @@
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#define BOOST_THREAD_VERSION 2
-#define BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN
+//#define BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN
//#define BOOST_THREAD_USES_LOG
#include <boost/thread/thread.hpp>
Modified: branches/release/libs/thread/test/test_barrier.cpp
==============================================================================
--- branches/release/libs/thread/test/test_barrier.cpp (original)
+++ branches/release/libs/thread/test/test_barrier.cpp 2013-02-12 13:32:00 EST (Tue, 12 Feb 2013)
@@ -67,15 +67,3 @@
return test;
}
-void remove_unused_warning()
-{
-
- //../../../boost/test/results_collector.hpp:40:13: warning: unused function 'first_failed_assertion' [-Wunused-function]
- //(void)first_failed_assertion;
-
- //../../../boost/test/tools/floating_point_comparison.hpp:304:25: warning: unused variable 'check_is_close' [-Wunused-variable]
- //../../../boost/test/tools/floating_point_comparison.hpp:326:25: warning: unused variable 'check_is_small' [-Wunused-variable]
- (void)boost::test_tools::check_is_close;
- (void)boost::test_tools::check_is_small;
-
-}
Modified: branches/release/libs/thread/test/test_condition.cpp
==============================================================================
--- branches/release/libs/thread/test/test_condition.cpp (original)
+++ branches/release/libs/thread/test/test_condition.cpp 2013-02-12 13:32:00 EST (Tue, 12 Feb 2013)
@@ -192,15 +192,4 @@
return test;
}
-void remove_unused_warning()
-{
- //../../../boost/test/results_collector.hpp:40:13: warning: unused function 'first_failed_assertion' [-Wunused-function]
- //(void)first_failed_assertion;
-
- //../../../boost/test/tools/floating_point_comparison.hpp:304:25: warning: unused variable 'check_is_close' [-Wunused-variable]
- //../../../boost/test/tools/floating_point_comparison.hpp:326:25: warning: unused variable 'check_is_small' [-Wunused-variable]
- (void)boost::test_tools::check_is_close;
- (void)boost::test_tools::check_is_small;
-
-}
Modified: branches/release/libs/thread/test/test_condition_notify_all.cpp
==============================================================================
--- branches/release/libs/thread/test/test_condition_notify_all.cpp (original)
+++ branches/release/libs/thread/test/test_condition_notify_all.cpp 2013-02-12 13:32:00 EST (Tue, 12 Feb 2013)
@@ -223,15 +223,4 @@
return test;
}
-void remove_unused_warning()
-{
- //../../../boost/test/results_collector.hpp:40:13: warning: unused function 'first_failed_assertion' [-Wunused-function]
- //(void)first_failed_assertion;
-
- //../../../boost/test/tools/floating_point_comparison.hpp:304:25: warning: unused variable 'check_is_close' [-Wunused-variable]
- //../../../boost/test/tools/floating_point_comparison.hpp:326:25: warning: unused variable 'check_is_small' [-Wunused-variable]
- (void)boost::test_tools::check_is_close;
- (void)boost::test_tools::check_is_small;
-
-}
Modified: branches/release/libs/thread/test/test_condition_notify_one.cpp
==============================================================================
--- branches/release/libs/thread/test/test_condition_notify_one.cpp (original)
+++ branches/release/libs/thread/test/test_condition_notify_one.cpp 2013-02-12 13:32:00 EST (Tue, 12 Feb 2013)
@@ -156,15 +156,3 @@
return test;
}
-void remove_unused_warning()
-{
-
- //../../../boost/test/results_collector.hpp:40:13: warning: unused function 'first_failed_assertion' [-Wunused-function]
- //(void)first_failed_assertion;
-
- //../../../boost/test/tools/floating_point_comparison.hpp:304:25: warning: unused variable 'check_is_close' [-Wunused-variable]
- //../../../boost/test/tools/floating_point_comparison.hpp:326:25: warning: unused variable 'check_is_small' [-Wunused-variable]
- (void)boost::test_tools::check_is_close;
- (void)boost::test_tools::check_is_small;
-
-}
Modified: branches/release/libs/thread/test/test_condition_timed_wait_times_out.cpp
==============================================================================
--- branches/release/libs/thread/test/test_condition_timed_wait_times_out.cpp (original)
+++ branches/release/libs/thread/test/test_condition_timed_wait_times_out.cpp 2013-02-12 13:32:00 EST (Tue, 12 Feb 2013)
@@ -174,15 +174,4 @@
return test;
}
-void remove_unused_warning()
-{
- //../../../boost/test/results_collector.hpp:40:13: warning: unused function 'first_failed_assertion' [-Wunused-function]
- //(void)first_failed_assertion;
-
- //../../../boost/test/tools/floating_point_comparison.hpp:304:25: warning: unused variable 'check_is_close' [-Wunused-variable]
- //../../../boost/test/tools/floating_point_comparison.hpp:326:25: warning: unused variable 'check_is_small' [-Wunused-variable]
- (void)boost::test_tools::check_is_close;
- (void)boost::test_tools::check_is_small;
-
-}
Modified: branches/release/libs/thread/test/test_futures.cpp
==============================================================================
--- branches/release/libs/thread/test/test_futures.cpp (original)
+++ branches/release/libs/thread/test/test_futures.cpp 2013-02-12 13:32:00 EST (Tue, 12 Feb 2013)
@@ -59,6 +59,9 @@
~X()
{}
};
+namespace boost {
+ BOOST_THREAD_DCL_MOVABLE(X)
+}
int make_int()
{
@@ -1287,15 +1290,4 @@
return test;
}
-void remove_unused_warning()
-{
-
- //../../../boost/test/results_collector.hpp:40:13: warning: unused function 'first_failed_assertion' [-Wunused-function]
- //(void)first_failed_assertion;
- //../../../boost/test/tools/floating_point_comparison.hpp:304:25: warning: unused variable 'check_is_close' [-Wunused-variable]
- //../../../boost/test/tools/floating_point_comparison.hpp:326:25: warning: unused variable 'check_is_small' [-Wunused-variable]
- (void)boost::test_tools::check_is_close;
- (void)boost::test_tools::check_is_small;
-
-}
Modified: branches/release/libs/thread/test/test_generic_locks.cpp
==============================================================================
--- branches/release/libs/thread/test/test_generic_locks.cpp (original)
+++ branches/release/libs/thread/test/test_generic_locks.cpp 2013-02-12 13:32:00 EST (Tue, 12 Feb 2013)
@@ -595,15 +595,4 @@
return test;
}
-void remove_unused_warning()
-{
- //../../../boost/test/results_collector.hpp:40:13: warning: unused function 'first_failed_assertion' [-Wunused-function]
- //(void)first_failed_assertion;
-
- //../../../boost/test/tools/floating_point_comparison.hpp:304:25: warning: unused variable 'check_is_close' [-Wunused-variable]
- //../../../boost/test/tools/floating_point_comparison.hpp:326:25: warning: unused variable 'check_is_small' [-Wunused-variable]
- (void)boost::test_tools::check_is_close;
- (void)boost::test_tools::check_is_small;
-
-}
Modified: branches/release/libs/thread/test/test_hardware_concurrency.cpp
==============================================================================
--- branches/release/libs/thread/test/test_hardware_concurrency.cpp (original)
+++ branches/release/libs/thread/test/test_hardware_concurrency.cpp 2013-02-12 13:32:00 EST (Tue, 12 Feb 2013)
@@ -20,15 +20,4 @@
return test;
}
-void remove_unused_warning()
-{
- //../../../boost/test/results_collector.hpp:40:13: warning: unused function 'first_failed_assertion' [-Wunused-function]
- //(void)first_failed_assertion;
-
- //../../../boost/test/tools/floating_point_comparison.hpp:304:25: warning: unused variable 'check_is_close' [-Wunused-variable]
- //../../../boost/test/tools/floating_point_comparison.hpp:326:25: warning: unused variable 'check_is_small' [-Wunused-variable]
- (void)boost::test_tools::check_is_close;
- (void)boost::test_tools::check_is_small;
-
-}
Modified: branches/release/libs/thread/test/test_lock_concept.cpp
==============================================================================
--- branches/release/libs/thread/test/test_lock_concept.cpp (original)
+++ branches/release/libs/thread/test/test_lock_concept.cpp 2013-02-12 13:32:00 EST (Tue, 12 Feb 2013)
@@ -575,15 +575,3 @@
return test;
}
-void remove_unused_warning()
-{
-
- //../../../boost/test/results_collector.hpp:40:13: warning: unused function 'first_failed_assertion' [-Wunused-function]
- //(void)first_failed_assertion;
-
- //../../../boost/test/tools/floating_point_comparison.hpp:304:25: warning: unused variable 'check_is_close' [-Wunused-variable]
- //../../../boost/test/tools/floating_point_comparison.hpp:326:25: warning: unused variable 'check_is_small' [-Wunused-variable]
- (void)boost::test_tools::check_is_close;
- (void)boost::test_tools::check_is_small;
-
-}
Modified: branches/release/libs/thread/test/test_move_function.cpp
==============================================================================
--- branches/release/libs/thread/test/test_move_function.cpp (original)
+++ branches/release/libs/thread/test/test_move_function.cpp 2013-02-12 13:32:00 EST (Tue, 12 Feb 2013)
@@ -143,15 +143,4 @@
return test;
}
-void remove_unused_warning()
-{
- //../../../boost/test/results_collector.hpp:40:13: warning: unused function 'first_failed_assertion' [-Wunused-function]
- //(void)first_failed_assertion;
-
- //../../../boost/test/tools/floating_point_comparison.hpp:304:25: warning: unused variable 'check_is_close' [-Wunused-variable]
- //../../../boost/test/tools/floating_point_comparison.hpp:326:25: warning: unused variable 'check_is_small' [-Wunused-variable]
- (void)boost::test_tools::check_is_close;
- (void)boost::test_tools::check_is_small;
-
-}
Modified: branches/release/libs/thread/test/test_mutex.cpp
==============================================================================
--- branches/release/libs/thread/test/test_mutex.cpp (original)
+++ branches/release/libs/thread/test/test_mutex.cpp 2013-02-12 13:32:00 EST (Tue, 12 Feb 2013)
@@ -349,15 +349,4 @@
return test;
}
-void remove_unused_warning()
-{
- //../../../boost/test/results_collector.hpp:40:13: warning: unused function 'first_failed_assertion' [-Wunused-function]
- //(void)first_failed_assertion;
-
- //../../../boost/test/tools/floating_point_comparison.hpp:304:25: warning: unused variable 'check_is_close' [-Wunused-variable]
- //../../../boost/test/tools/floating_point_comparison.hpp:326:25: warning: unused variable 'check_is_small' [-Wunused-variable]
- (void)boost::test_tools::check_is_close;
- (void)boost::test_tools::check_is_small;
-
-}
Modified: branches/release/libs/thread/test/test_once.cpp
==============================================================================
--- branches/release/libs/thread/test/test_once.cpp (original)
+++ branches/release/libs/thread/test/test_once.cpp 2013-02-12 13:32:00 EST (Tue, 12 Feb 2013)
@@ -201,15 +201,4 @@
return test;
}
-void remove_unused_warning()
-{
- //../../../boost/test/results_collector.hpp:40:13: warning: unused function 'first_failed_assertion' [-Wunused-function]
- //(void)first_failed_assertion;
-
- //../../../boost/test/tools/floating_point_comparison.hpp:304:25: warning: unused variable 'check_is_close' [-Wunused-variable]
- //../../../boost/test/tools/floating_point_comparison.hpp:326:25: warning: unused variable 'check_is_small' [-Wunused-variable]
- (void)boost::test_tools::check_is_close;
- (void)boost::test_tools::check_is_small;
-
-}
Modified: branches/release/libs/thread/test/test_shared_mutex.cpp
==============================================================================
--- branches/release/libs/thread/test/test_shared_mutex.cpp (original)
+++ branches/release/libs/thread/test/test_shared_mutex.cpp 2013-02-12 13:32:00 EST (Tue, 12 Feb 2013)
@@ -287,15 +287,4 @@
return test;
}
-void remove_unused_warning()
-{
- //../../../boost/test/results_collector.hpp:40:13: warning: unused function 'first_failed_assertion' [-Wunused-function]
- //(void)first_failed_assertion;
-
- //../../../boost/test/tools/floating_point_comparison.hpp:304:25: warning: unused variable 'check_is_close' [-Wunused-variable]
- //../../../boost/test/tools/floating_point_comparison.hpp:326:25: warning: unused variable 'check_is_small' [-Wunused-variable]
- (void)boost::test_tools::check_is_close;
- (void)boost::test_tools::check_is_small;
-
-}
Modified: branches/release/libs/thread/test/test_shared_mutex_part_2.cpp
==============================================================================
--- branches/release/libs/thread/test/test_shared_mutex_part_2.cpp (original)
+++ branches/release/libs/thread/test/test_shared_mutex_part_2.cpp 2013-02-12 13:32:00 EST (Tue, 12 Feb 2013)
@@ -300,15 +300,3 @@
return test;
}
-void remove_unused_warning()
-{
-
- //../../../boost/test/results_collector.hpp:40:13: warning: unused function 'first_failed_assertion' [-Wunused-function]
- //(void)first_failed_assertion;
-
- //../../../boost/test/tools/floating_point_comparison.hpp:304:25: warning: unused variable 'check_is_close' [-Wunused-variable]
- //../../../boost/test/tools/floating_point_comparison.hpp:326:25: warning: unused variable 'check_is_small' [-Wunused-variable]
- (void)boost::test_tools::check_is_close;
- (void)boost::test_tools::check_is_small;
-
-}
Modified: branches/release/libs/thread/test/test_shared_mutex_timed_locks.cpp
==============================================================================
--- branches/release/libs/thread/test/test_shared_mutex_timed_locks.cpp (original)
+++ branches/release/libs/thread/test/test_shared_mutex_timed_locks.cpp 2013-02-12 13:32:00 EST (Tue, 12 Feb 2013)
@@ -269,15 +269,4 @@
return test;
}
-void remove_unused_warning()
-{
- //../../../boost/test/results_collector.hpp:40:13: warning: unused function 'first_failed_assertion' [-Wunused-function]
- //(void)first_failed_assertion;
-
- //../../../boost/test/tools/floating_point_comparison.hpp:304:25: warning: unused variable 'check_is_close' [-Wunused-variable]
- //../../../boost/test/tools/floating_point_comparison.hpp:326:25: warning: unused variable 'check_is_small' [-Wunused-variable]
- (void)boost::test_tools::check_is_close;
- (void)boost::test_tools::check_is_small;
-
-}
Modified: branches/release/libs/thread/test/test_shared_mutex_timed_locks_chrono.cpp
==============================================================================
--- branches/release/libs/thread/test/test_shared_mutex_timed_locks_chrono.cpp (original)
+++ branches/release/libs/thread/test/test_shared_mutex_timed_locks_chrono.cpp 2013-02-12 13:32:00 EST (Tue, 12 Feb 2013)
@@ -276,15 +276,3 @@
#endif
-void remove_unused_warning()
-{
-
- //../../../boost/test/results_collector.hpp:40:13: warning: unused function 'first_failed_assertion' [-Wunused-function]
- //(void)first_failed_assertion;
-
- //../../../boost/test/tools/floating_point_comparison.hpp:304:25: warning: unused variable 'check_is_close' [-Wunused-variable]
- //../../../boost/test/tools/floating_point_comparison.hpp:326:25: warning: unused variable 'check_is_small' [-Wunused-variable]
- (void)boost::test_tools::check_is_close;
- (void)boost::test_tools::check_is_small;
-
-}
Modified: branches/release/libs/thread/test/test_thread.cpp
==============================================================================
--- branches/release/libs/thread/test/test_thread.cpp (original)
+++ branches/release/libs/thread/test/test_thread.cpp 2013-02-12 13:32:00 EST (Tue, 12 Feb 2013)
@@ -236,16 +236,3 @@
return test;
}
-void remove_unused_warning()
-{
-
- //../../../boost/test/results_collector.hpp:40:13: warning: unused function 'first_failed_assertion' [-Wunused-function]
- //(void)boost::unit_test::first_failed_assertion;
-
- //../../../boost/test/tools/floating_point_comparison.hpp:304:25: warning: unused variable 'check_is_close' [-Wunused-variable]
- //../../../boost/test/tools/floating_point_comparison.hpp:326:25: warning: unused variable 'check_is_small' [-Wunused-variable]
- (void)boost::test_tools::check_is_close;
- (void)boost::test_tools::check_is_small;
-
-
-}
Modified: branches/release/libs/thread/test/test_thread_exit.cpp
==============================================================================
--- branches/release/libs/thread/test/test_thread_exit.cpp (original)
+++ branches/release/libs/thread/test/test_thread_exit.cpp 2013-02-12 13:32:00 EST (Tue, 12 Feb 2013)
@@ -72,15 +72,4 @@
return test;
}
-void remove_unused_warning()
-{
- //../../../boost/test/results_collector.hpp:40:13: warning: unused function 'first_failed_assertion' [-Wunused-function]
- //(void)boost::unit_test::first_failed_assertion;
-
- //../../../boost/test/tools/floating_point_comparison.hpp:304:25: warning: unused variable 'check_is_close' [-Wunused-variable]
- //../../../boost/test/tools/floating_point_comparison.hpp:326:25: warning: unused variable 'check_is_small' [-Wunused-variable]
- (void)boost::test_tools::check_is_close;
- (void)boost::test_tools::check_is_small;
-
-}
Modified: branches/release/libs/thread/test/test_thread_id.cpp
==============================================================================
--- branches/release/libs/thread/test/test_thread_id.cpp (original)
+++ branches/release/libs/thread/test/test_thread_id.cpp 2013-02-12 13:32:00 EST (Tue, 12 Feb 2013)
@@ -148,15 +148,4 @@
return test;
}
-void remove_unused_warning()
-{
- //../../../boost/test/results_collector.hpp:40:13: warning: unused function 'first_failed_assertion' [-Wunused-function]
- //(void)boost::unit_test::first_failed_assertion;
-
- //../../../boost/test/tools/floating_point_comparison.hpp:304:25: warning: unused variable 'check_is_close' [-Wunused-variable]
- //../../../boost/test/tools/floating_point_comparison.hpp:326:25: warning: unused variable 'check_is_small' [-Wunused-variable]
- (void)boost::test_tools::check_is_close;
- (void)boost::test_tools::check_is_small;
-
-}
Modified: branches/release/libs/thread/test/test_thread_launching.cpp
==============================================================================
--- branches/release/libs/thread/test/test_thread_launching.cpp (original)
+++ branches/release/libs/thread/test/test_thread_launching.cpp 2013-02-12 13:32:00 EST (Tue, 12 Feb 2013)
@@ -230,16 +230,4 @@
return test;
}
-void remove_unused_warning()
-{
- //../../../boost/test/results_collector.hpp:40:13: warning: unused function 'first_failed_assertion' [-Wunused-function]
- //(void)boost::unit_test::first_failed_assertion;
-
- //../../../boost/test/tools/floating_point_comparison.hpp:304:25: warning: unused variable 'check_is_close' [-Wunused-variable]
- //../../../boost/test/tools/floating_point_comparison.hpp:326:25: warning: unused variable 'check_is_small' [-Wunused-variable]
- (void)boost::test_tools::check_is_close;
- (void)boost::test_tools::check_is_small;
-
-
-}
Modified: branches/release/libs/thread/test/test_thread_move.cpp
==============================================================================
--- branches/release/libs/thread/test/test_thread_move.cpp (original)
+++ branches/release/libs/thread/test/test_thread_move.cpp 2013-02-12 13:32:00 EST (Tue, 12 Feb 2013)
@@ -55,16 +55,4 @@
return test;
}
-void remove_unused_warning()
-{
- //../../../boost/test/results_collector.hpp:40:13: warning: unused function 'first_failed_assertion' [-Wunused-function]
- //(void)boost::unit_test::first_failed_assertion;
-
- //../../../boost/test/tools/floating_point_comparison.hpp:304:25: warning: unused variable 'check_is_close' [-Wunused-variable]
- //../../../boost/test/tools/floating_point_comparison.hpp:326:25: warning: unused variable 'check_is_small' [-Wunused-variable]
- (void)boost::test_tools::check_is_close;
- (void)boost::test_tools::check_is_small;
-
-
-}
Modified: branches/release/libs/thread/test/test_thread_move_return.cpp
==============================================================================
--- branches/release/libs/thread/test/test_thread_move_return.cpp (original)
+++ branches/release/libs/thread/test/test_thread_move_return.cpp 2013-02-12 13:32:00 EST (Tue, 12 Feb 2013)
@@ -37,16 +37,4 @@
return test;
}
-void remove_unused_warning()
-{
- //../../../boost/test/results_collector.hpp:40:13: warning: unused function 'first_failed_assertion' [-Wunused-function]
- //(void)boost::unit_test::first_failed_assertion;
-
- //../../../boost/test/tools/floating_point_comparison.hpp:304:25: warning: unused variable 'check_is_close' [-Wunused-variable]
- //../../../boost/test/tools/floating_point_comparison.hpp:326:25: warning: unused variable 'check_is_small' [-Wunused-variable]
- (void)boost::test_tools::check_is_close;
- (void)boost::test_tools::check_is_small;
-
-
-}
Modified: branches/release/libs/thread/test/test_thread_return_local.cpp
==============================================================================
--- branches/release/libs/thread/test/test_thread_return_local.cpp (original)
+++ branches/release/libs/thread/test/test_thread_return_local.cpp 2013-02-12 13:32:00 EST (Tue, 12 Feb 2013)
@@ -37,16 +37,4 @@
return test;
}
-void remove_unused_warning()
-{
- //../../../boost/test/results_collector.hpp:40:13: warning: unused function 'first_failed_assertion' [-Wunused-function]
- //(void)boost::unit_test::first_failed_assertion;
-
- //../../../boost/test/tools/floating_point_comparison.hpp:304:25: warning: unused variable 'check_is_close' [-Wunused-variable]
- //../../../boost/test/tools/floating_point_comparison.hpp:326:25: warning: unused variable 'check_is_small' [-Wunused-variable]
- (void)boost::test_tools::check_is_close;
- (void)boost::test_tools::check_is_small;
-
-
-}
Modified: branches/release/libs/thread/test/test_tss.cpp
==============================================================================
--- branches/release/libs/thread/test/test_tss.cpp (original)
+++ branches/release/libs/thread/test/test_tss.cpp 2013-02-12 13:32:00 EST (Tue, 12 Feb 2013)
@@ -372,17 +372,3 @@
return test;
}
-
-void remove_unused_warning()
-{
-
- //../../../boost/test/results_collector.hpp:40:13: warning: unused function 'first_failed_assertion' [-Wunused-function]
- //(void)boost::unit_test::first_failed_assertion;
-
- //../../../boost/test/tools/floating_point_comparison.hpp:304:25: warning: unused variable 'check_is_close' [-Wunused-variable]
- //../../../boost/test/tools/floating_point_comparison.hpp:326:25: warning: unused variable 'check_is_small' [-Wunused-variable]
- (void)boost::test_tools::check_is_close;
- (void)boost::test_tools::check_is_small;
-
-
-}
Modified: branches/release/libs/thread/test/test_xtime.cpp
==============================================================================
--- branches/release/libs/thread/test/test_xtime.cpp (original)
+++ branches/release/libs/thread/test/test_xtime.cpp 2013-02-12 13:32:00 EST (Tue, 12 Feb 2013)
@@ -109,17 +109,3 @@
return test;
}
-
-void remove_unused_warning()
-{
-
- //../../../boost/test/results_collector.hpp:40:13: warning: unused function 'first_failed_assertion' [-Wunused-function]
- //(void)boost::unit_test::first_failed_assertion;
-
- //../../../boost/test/tools/floating_point_comparison.hpp:304:25: warning: unused variable 'check_is_close' [-Wunused-variable]
- //../../../boost/test/tools/floating_point_comparison.hpp:326:25: warning: unused variable 'check_is_small' [-Wunused-variable]
- (void)boost::test_tools::check_is_close;
- (void)boost::test_tools::check_is_small;
-
-
-}
Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk