|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r82029 - in branches/release: boost/thread boost/thread/detail libs/thread libs/thread/build libs/thread/example libs/thread/src libs/thread/src/pthread libs/thread/src/win32 libs/thread/test libs/thread/test/sync/futures/future libs/thread/test/sync/futures/packaged_task libs/thread/test/sync/futures/promise libs/thread/test/sync/mutual_exclusion/locks/nested_strict_lock libs/thread/test/sync/mutual_exclusion/locks/strict_lock
From: vicente.botet_at_[hidden]
Date: 2012-12-16 14:01:47
Author: viboes
Date: 2012-12-16 14:01:45 EST (Sun, 16 Dec 2012)
New Revision: 82029
URL: http://svn.boost.org/trac/boost/changeset/82029
Log:
Merge from trunk 1.53
Added:
branches/release/boost/thread/detail/lockable_wrapper.hpp
- copied unchanged from r82018, /trunk/boost/thread/detail/lockable_wrapper.hpp
branches/release/boost/thread/future_error_code.hpp
- copied unchanged from r82018, /trunk/boost/thread/future_error_code.hpp
Properties modified:
branches/release/boost/thread/ (props changed)
branches/release/libs/thread/ (props changed)
Text files modified:
branches/release/boost/thread/detail/thread.hpp | 2
branches/release/boost/thread/externally_locked.hpp | 16
branches/release/boost/thread/future.hpp | 254 ++++++++++-----------------
branches/release/boost/thread/lock_guard.hpp | 28 --
branches/release/boost/thread/strict_lock.hpp | 43 ++++
branches/release/boost/thread/synchronized_value.hpp | 361 +++++++++++++++++++++++----------------
branches/release/libs/thread/build/Jamfile.v2 | 4
branches/release/libs/thread/example/future_then.cpp | 5
branches/release/libs/thread/example/synchronized_person.cpp | 25 ++
branches/release/libs/thread/example/synchronized_value.cpp | 8
branches/release/libs/thread/src/future.cpp | 6
branches/release/libs/thread/src/pthread/thread.cpp | 2
branches/release/libs/thread/src/win32/thread.cpp | 2
branches/release/libs/thread/test/Jamfile.v2 | 14
branches/release/libs/thread/test/sync/futures/future/get_pass.cpp | 51 ++++-
branches/release/libs/thread/test/sync/futures/future/then_pass.cpp | 19 +
branches/release/libs/thread/test/sync/futures/packaged_task/make_ready_at_thread_exit_pass.cpp | 39 ++++
branches/release/libs/thread/test/sync/futures/promise/set_exception_at_thread_exit_pass.cpp | 21 ++
branches/release/libs/thread/test/sync/futures/promise/set_value_at_thread_exit_const_pass.cpp | 7
branches/release/libs/thread/test/sync/futures/promise/set_value_at_thread_exit_void_pass.cpp | 38 +++
branches/release/libs/thread/test/sync/mutual_exclusion/locks/nested_strict_lock/copy_ctor_fail.cpp | 4
branches/release/libs/thread/test/sync/mutual_exclusion/locks/nested_strict_lock/make_nested_strict_lock_pass.cpp | 4
branches/release/libs/thread/test/sync/mutual_exclusion/locks/strict_lock/make_strict_lock_pass.cpp | 2
23 files changed, 557 insertions(+), 398 deletions(-)
Modified: branches/release/boost/thread/detail/thread.hpp
==============================================================================
--- branches/release/boost/thread/detail/thread.hpp (original)
+++ branches/release/boost/thread/detail/thread.hpp 2012-12-16 14:01:45 EST (Sun, 16 Dec 2012)
@@ -731,7 +731,7 @@
namespace this_thread
{
- thread::id get_id() BOOST_NOEXCEPT
+ inline thread::id get_id() BOOST_NOEXCEPT
{
#if defined BOOST_THREAD_PROVIDES_BASIC_THREAD_ID
return pthread_self();
Modified: branches/release/boost/thread/externally_locked.hpp
==============================================================================
--- branches/release/boost/thread/externally_locked.hpp (original)
+++ branches/release/boost/thread/externally_locked.hpp 2012-12-16 14:01:45 EST (Sun, 16 Dec 2012)
@@ -53,7 +53,7 @@
/**
* Requires: T is a model of Movable.
- * Effects: Constructs an externally locked object copying the cloaked type.
+ * Effects: Constructs an externally locked object by moving the cloaked type.
*/
BOOST_CONSTEXPR externally_locked(mutex_type& mtx, BOOST_THREAD_RV_REF(T) obj) :
obj_(move(obj)), mtx_(&mtx)
@@ -83,7 +83,7 @@
*
* Returns: The address of the cloaked object..
*
- * Throws: lock_error if BOOST_THREAD_EXTERNALLY_LOCKED_DONT_CHECK_SAME is not defined and the lk parameter doesn't satisfy the preconditions
+ * Throws: lock_error if BOOST_THREAD_THROW_IF_PRECONDITION_NOT_SATISFIED is not defined and the lk parameter doesn't satisfy the preconditions
*/
T& get(strict_lock<mutex_type>& lk)
{
@@ -117,7 +117,7 @@
* Requires: The lk parameter must be locking the associated mtx.
* Returns: The address of the cloaked object..
*
- * Throws: lock_error if BOOST_THREAD_EXTERNALLY_LOCKED_DONT_CHECK_SAME is not defined and the lk parameter doesn't satisfy the preconditions
+ * Throws: lock_error if BOOST_THREAD_THROW_IF_PRECONDITION_NOT_SATISFIED is not defined and the lk parameter doesn't satisfy the preconditions
*/
template <class Lock>
T& get(Lock& lk)
@@ -203,7 +203,7 @@
*
* Returns: The address of the cloaked object..
*
- * Throws: lock_error if BOOST_THREAD_EXTERNALLY_LOCKED_DONT_CHECK_SAME is not defined and the lk parameter doesn't satisfy the preconditions
+ * Throws: lock_error if BOOST_THREAD_THROW_IF_PRECONDITION_NOT_SATISFIED is not defined and the lk parameter doesn't satisfy the preconditions
*/
T& get(strict_lock<mutex_type> const& lk)
{
@@ -237,7 +237,7 @@
* Requires: The lk parameter must be locking the associated mtx.
* Returns: The address of the cloaked object..
*
- * Throws: lock_error if BOOST_THREAD_EXTERNALLY_LOCKED_DONT_CHECK_SAME is not defined and the lk parameter doesn't satisfy the preconditions
+ * Throws: lock_error if BOOST_THREAD_THROW_IF_PRECONDITION_NOT_SATISFIED is not defined and the lk parameter doesn't satisfy the preconditions
*/
template <class Lock>
T& get(Lock const& lk)
@@ -245,7 +245,7 @@
BOOST_CONCEPT_ASSERT(( StrictLock<Lock> ));
BOOST_STATIC_ASSERT( (is_strict_lock<Lock>::value)); /*< lk is a strict lock "sur parolle" >*/
BOOST_STATIC_ASSERT( (is_same<mutex_type, typename Lock::mutex_type>::value)); /*< that locks the same type >*/
- BOOST_THREAD_ASSERT_PRECONDITION( lk.owns_lock(), lock_error() ); /*< run time check throw if no locked >*/
+ //BOOST_THREAD_ASSERT_PRECONDITION( lk.owns_lock(), lock_error() ); /*< run time check throw if no locked >*/
BOOST_THREAD_ASSERT_PRECONDITION( lk.owns_lock(mtx_), lock_error() ); /*< run time check throw if not locks the same >*/
return *obj_;
}
@@ -254,7 +254,7 @@
* Requires: The lk parameter must be locking the associated mtx.
* Returns: The address of the cloaked object..
*
- * Throws: lock_error if BOOST_THREAD_EXTERNALLY_LOCKED_DONT_CHECK_SAME is not defined and the lk parameter doesn't satisfy the preconditions
+ * Throws: lock_error if BOOST_THREAD_THROW_IF_PRECONDITION_NOT_SATISFIED is not defined and the lk parameter doesn't satisfy the preconditions
*/
template <class Lock>
T const& get(Lock const& lk) const
@@ -262,7 +262,7 @@
BOOST_CONCEPT_ASSERT(( StrictLock<Lock> ));
BOOST_STATIC_ASSERT( (is_strict_lock<Lock>::value)); /*< lk is a strict lock "sur parolle" >*/
BOOST_STATIC_ASSERT( (is_same<mutex_type, typename Lock::mutex_type>::value)); /*< that locks the same type >*/
- BOOST_THREAD_ASSERT_PRECONDITION( lk.owns_lock(), lock_error() ); /*< run time check throw if no locked >*/
+ //BOOST_THREAD_ASSERT_PRECONDITION( lk.owns_lock(), lock_error() ); /*< run time check throw if no locked >*/
BOOST_THREAD_ASSERT_PRECONDITION( lk.owns_lock(mtx_), lock_error() ); /*< run time check throw if not locks the same >*/
return *obj_;
}
Modified: branches/release/boost/thread/future.hpp
==============================================================================
--- branches/release/boost/thread/future.hpp (original)
+++ branches/release/boost/thread/future.hpp 2012-12-16 14:01:45 EST (Sun, 16 Dec 2012)
@@ -15,6 +15,7 @@
#ifndef BOOST_NO_EXCEPTIONS
+//#include <boost/thread/detail/log.hpp>
#include <boost/detail/scoped_enum_emulation.hpp>
#include <stdexcept>
#include <boost/thread/detail/move.hpp>
@@ -45,7 +46,7 @@
#include <boost/next_prior.hpp>
#include <vector>
-#include <boost/system/error_code.hpp>
+#include <boost/thread/future_error_code.hpp>
#ifdef BOOST_THREAD_USES_CHRONO
#include <boost/chrono/system_clocks.hpp>
#endif
@@ -66,87 +67,46 @@
namespace boost
{
-
- //enum class future_errc
- BOOST_SCOPED_ENUM_DECLARE_BEGIN(future_errc)
- {
- broken_promise = 1,
- future_already_retrieved,
- promise_already_satisfied,
- no_state
- }
- BOOST_SCOPED_ENUM_DECLARE_END(future_errc)
-
- namespace system
- {
- template <>
- struct BOOST_SYMBOL_VISIBLE is_error_code_enum<future_errc> : public true_type {};
-
- #ifdef BOOST_NO_CXX11_SCOPED_ENUMS
- template <>
- struct BOOST_SYMBOL_VISIBLE is_error_code_enum<future_errc::enum_type> : public true_type { };
- #endif
- }
-
- //enum class launch
- BOOST_SCOPED_ENUM_DECLARE_BEGIN(launch)
- {
- async = 1,
- deferred = 2,
- any = async | deferred
- }
- BOOST_SCOPED_ENUM_DECLARE_END(launch)
-
- //enum class future_status
- BOOST_SCOPED_ENUM_DECLARE_BEGIN(future_status)
- {
- ready,
- timeout,
- deferred
- }
- BOOST_SCOPED_ENUM_DECLARE_END(future_status)
-
- BOOST_THREAD_DECL
- const system::error_category& future_category() BOOST_NOEXCEPT;
-
- namespace system
- {
- inline
- error_code
- make_error_code(future_errc e) //BOOST_NOEXCEPT
+ //enum class launch
+ BOOST_SCOPED_ENUM_DECLARE_BEGIN(launch)
{
- return error_code(underlying_cast<int>(e), boost::future_category());
+ none = 0,
+ async = 1,
+ deferred = 2,
+ any = async | deferred
}
+ BOOST_SCOPED_ENUM_DECLARE_END(launch)
- inline
- error_condition
- make_error_condition(future_errc e) //BOOST_NOEXCEPT
+ //enum class future_status
+ BOOST_SCOPED_ENUM_DECLARE_BEGIN(future_status)
{
- return error_condition(underlying_cast<int>(e), future_category());
+ ready,
+ timeout,
+ deferred
}
- }
+ BOOST_SCOPED_ENUM_DECLARE_END(future_status)
- class BOOST_SYMBOL_VISIBLE future_error
- : public std::logic_error
- {
- system::error_code ec_;
- public:
- future_error(system::error_code ec)
- : logic_error(ec.message()),
- ec_(ec)
- {
- }
+ class BOOST_SYMBOL_VISIBLE future_error
+ : public std::logic_error
+ {
+ system::error_code ec_;
+ public:
+ future_error(system::error_code ec)
+ : logic_error(ec.message()),
+ ec_(ec)
+ {
+ }
- const system::error_code& code() const BOOST_NOEXCEPT
- {
- return ec_;
- }
- const char* what() const BOOST_THREAD_NOEXCEPT_OR_THROW
- {
- return code().message().c_str();
- }
+ const system::error_code& code() const BOOST_NOEXCEPT
+ {
+ return ec_;
+ }
+ const char* what() const BOOST_THREAD_NOEXCEPT_OR_THROW
+ {
+ return code().message().c_str();
+ }
- };
+ };
class BOOST_SYMBOL_VISIBLE future_uninitialized:
public future_error
@@ -190,23 +150,23 @@
{}
};
- class BOOST_SYMBOL_VISIBLE task_moved:
- public future_error
- {
- public:
- task_moved():
- future_error(system::make_error_code(future_errc::no_state))
- {}
- };
+ class BOOST_SYMBOL_VISIBLE task_moved:
+ public future_error
+ {
+ public:
+ task_moved():
+ future_error(system::make_error_code(future_errc::no_state))
+ {}
+ };
- class promise_moved:
- public future_error
- {
- public:
- promise_moved():
- future_error(system::make_error_code(future_errc::no_state))
- {}
- };
+ class promise_moved:
+ public future_error
+ {
+ public:
+ promise_moved():
+ future_error(system::make_error_code(future_errc::no_state))
+ {}
+ };
namespace future_state
{
@@ -283,7 +243,7 @@
future_object_base():
done(false),
is_deferred_(false),
- policy_(launch::any),
+ policy_(launch::none),
is_constructed(false)
//#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
, thread_was_interrupted(false)
@@ -295,8 +255,19 @@
virtual ~future_object_base()
{}
- void set_deferred() {is_deferred_ = true;}
- void set_launch_policy(launch policy) {policy_ = policy;}
+ void set_deferred()
+ {
+ is_deferred_ = true;
+ set_launch_policy(launch::deferred);
+ }
+ void set_async()
+ {
+ set_launch_policy(launch::async);
+ }
+ void set_launch_policy(launch policy)
+ {
+ policy_ = policy;
+ }
waiter_list::iterator register_external_waiter(boost::condition_variable_any& cv)
{
@@ -508,7 +479,9 @@
#endif
);
}
- void is_deferred() {is_deferred_ = true;}
+ bool is_deferred() const BOOST_NOEXCEPT {
+ return is_deferred_ == true;
+ }
launch launch_policy() const BOOST_NOEXCEPT
{
@@ -518,6 +491,7 @@
template<typename F,typename U>
void set_wait_callback(F f,U* u)
{
+ boost::lock_guard<boost::mutex> lock(mutex);
callback=boost::bind(f,boost::ref(*u));
}
virtual void execute(boost::unique_lock<boost::mutex>&) {}
@@ -861,35 +835,41 @@
future_object& operator=(future_object const&);
};
+ /////////////////////////
/// future_async_object
+ /////////////////////////
template<typename Rp, typename Fp>
struct future_async_object: future_object<Rp>
{
typedef future_object<Rp> base_type;
+ typedef typename base_type::move_dest_type move_dest_type;
+
boost::thread thr_;
public:
- #if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
- explicit future_async_object(Fp&& f)
- :
- #else
- explicit future_async_object(BOOST_THREAD_FWD_REF(Fp) f)
- :
- #endif
- thr_(&future_async_object::run, this, boost::forward<Fp>(f))
+ explicit future_async_object(BOOST_THREAD_FWD_REF(Fp) f) :
+ thr_(&future_async_object::run, this, boost::forward<Fp>(f))
{
+ this->set_async();
}
~future_async_object()
{
- thr_.join();
+ if (thr_.joinable()) thr_.join();
+ }
+
+ move_dest_type get()
+ {
+ if (thr_.joinable()) thr_.join();
+ // fixme Is the lock needed during the whole scope?
+ //this->wait();
+ boost::unique_lock<boost::mutex> lock(this->mutex);
+ this->wait_internal(lock);
+
+ return static_cast<move_dest_type>(*(this->result));
}
-#if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
- static void run(future_async_object* that, Fp&& f)
-#else
static void run(future_async_object* that, BOOST_THREAD_FWD_REF(Fp) f)
-#endif
{
try
{
@@ -912,30 +892,22 @@
struct future_async_object<void, Fp>: public future_object<void>
{
typedef future_object<void> base_type;
+
boost::thread thr_;
public:
- #if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
- explicit future_async_object(Fp&& f)
- :
- #else
- explicit future_async_object(BOOST_THREAD_FWD_REF(Fp) f)
- :
- #endif
- thr_(&future_async_object::run, this, boost::forward<Fp>(f))
+ explicit future_async_object(BOOST_THREAD_FWD_REF(Fp) f) :
+ thr_(&future_async_object::run, this, boost::forward<Fp>(f))
{
+ this->set_async();
}
~future_async_object()
{
- thr_.join();
+ if (thr_.joinable()) thr_.join();
}
-#if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
- static void run(future_async_object* that, Fp&& f)
-#else
static void run(future_async_object* that, BOOST_THREAD_FWD_REF(Fp) f)
-#endif
{
try
{
@@ -954,7 +926,9 @@
}
}
};
+ //////////////////////////
/// future_deferred_object
+ //////////////////////////
template<typename Rp, typename Fp>
struct future_deferred_object: future_object<Rp>
{
@@ -962,13 +936,8 @@
Fp func_;
public:
- #if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
- explicit future_deferred_object(Fp&& f)
+ explicit future_deferred_object(BOOST_THREAD_FWD_REF(Fp) f)
: func_(boost::forward<Fp>(f))
- #else
- explicit future_deferred_object(Fp f)
- : func_(f)
- #endif
{
this->set_deferred();
}
@@ -992,13 +961,8 @@
Fp func_;
public:
- #if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
- explicit future_deferred_object(Fp&& f)
+ explicit future_deferred_object(BOOST_THREAD_FWD_REF(Fp) f)
: func_(boost::forward<Fp>(f))
- #else
- explicit future_deferred_object(Fp f)
- : func_(f)
- #endif
{
this->set_deferred();
}
@@ -1333,7 +1297,7 @@
launch launch_policy() const BOOST_NOEXCEPT
{
if ( future_ ) return future_->launch_policy();
- else return launch(launch::any);
+ else return launch(launch::none);
}
bool valid() const BOOST_NOEXCEPT
@@ -1396,19 +1360,11 @@
{
template <class Rp, class Fp>
BOOST_THREAD_FUTURE<Rp>
- #if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
- make_future_async_object(Fp&& f);
- #else
make_future_async_object(BOOST_THREAD_FWD_REF(Fp) f);
- #endif
template <class Rp, class Fp>
BOOST_THREAD_FUTURE<Rp>
- #if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
- make_future_deferred_object(Fp&& f);
- #else
make_future_deferred_object(BOOST_THREAD_FWD_REF(Fp) f);
- #endif
}
template <typename R>
@@ -1433,19 +1389,11 @@
template <class Rp, class Fp>
friend BOOST_THREAD_FUTURE<Rp>
- #if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
- detail::make_future_async_object(Fp&& f);
- #else
detail::make_future_async_object(BOOST_THREAD_FWD_REF(Fp) f);
- #endif
template <class Rp, class Fp>
friend BOOST_THREAD_FUTURE<Rp>
- #if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
- detail::make_future_deferred_object(Fp&& f);
- #else
detail::make_future_deferred_object(BOOST_THREAD_FWD_REF(Fp) f);
- #endif
typedef typename detail::future_traits<R>::move_dest_type move_dest_type;
@@ -2856,11 +2804,7 @@
////////////////////////////////
template <class Rp, class Fp>
BOOST_THREAD_FUTURE<Rp>
- #if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
- make_future_deferred_object(Fp&& f)
- #else
make_future_deferred_object(BOOST_THREAD_FWD_REF(Fp) f)
- #endif
{
shared_ptr<future_deferred_object<Rp, Fp> >
h(new future_deferred_object<Rp, Fp>(boost::forward<Fp>(f)));
@@ -2872,11 +2816,7 @@
////////////////////////////////
template <class Rp, class Fp>
BOOST_THREAD_FUTURE<Rp>
- #if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
- make_future_async_object(Fp&& f)
- #else
make_future_async_object(BOOST_THREAD_FWD_REF(Fp) f)
- #endif
{
shared_ptr<future_async_object<Rp, Fp> >
h(new future_async_object<Rp, Fp>(boost::forward<Fp>(f)));
Modified: branches/release/boost/thread/lock_guard.hpp
==============================================================================
--- branches/release/boost/thread/lock_guard.hpp (original)
+++ branches/release/boost/thread/lock_guard.hpp 2012-12-16 14:01:45 EST (Sun, 16 Dec 2012)
@@ -9,42 +9,18 @@
#include <boost/thread/detail/delete.hpp>
#include <boost/thread/detail/move.hpp>
+#include <boost/thread/detail/lockable_wrapper.hpp>
#include <boost/thread/lock_options.hpp>
#if ! defined BOOST_THREAD_PROVIDES_NESTED_LOCKS
#include <boost/thread/is_locked_by_this_thread.hpp>
-#endif
#include <boost/assert.hpp>
-#include <iostream>
-#if ! defined BOOST_NO_CXX11_HDR_INITIALIZER_LIST
-#include <initializer_list>
#endif
+
#include <boost/config/abi_prefix.hpp>
namespace boost
{
-#if ! defined BOOST_NO_CXX11_HDR_INITIALIZER_LIST
- namespace thread_detail
- {
- template <typename Mutex>
- struct lockable_wrapper
- {
- Mutex* m;
- explicit lockable_wrapper(Mutex& m_) :
- m(&m_)
- {}
- };
- template <typename Mutex>
- struct lockable_adopt_wrapper
- {
- Mutex* m;
- explicit lockable_adopt_wrapper(Mutex& m_) :
- m(&m_)
- {}
- };
- }
-#endif
-
template <typename Mutex>
class lock_guard
{
Modified: branches/release/boost/thread/strict_lock.hpp
==============================================================================
--- branches/release/boost/thread/strict_lock.hpp (original)
+++ branches/release/boost/thread/strict_lock.hpp 2012-12-16 14:01:45 EST (Sun, 16 Dec 2012)
@@ -7,6 +7,7 @@
#define BOOST_THREAD_STRICT_LOCK_HPP
#include <boost/thread/detail/delete.hpp>
+#include <boost/thread/detail/lockable_wrapper.hpp>
#include <boost/thread/lock_options.hpp>
#include <boost/thread/lock_traits.hpp>
#include <boost/thread/lockable_traits.hpp>
@@ -48,6 +49,15 @@
mtx.lock();
} /*< locks on construction >*/
+
+#if ! defined BOOST_NO_CXX11_HDR_INITIALIZER_LIST
+ strict_lock(std::initializer_list<thread_detail::lockable_wrapper<Lockable> > l_) :
+ mtx_(*(const_cast<thread_detail::lockable_wrapper<Lockable>*>(l_.begin())->m))
+ {
+ mtx_.lock();
+ }
+#endif
+
/**
* Destructor
*
@@ -97,7 +107,7 @@
/**
* A nested strict lock is a scoped lock guard ensuring the mutex is locked on its
- * scope, by taking ownership of an nesting lock, and locking the mutex on construction if not already locked
+ * scope, by taking ownership of an nesting lock, locking the mutex on construction if not already locked
* and restoring the ownership to the nesting lock on destruction.
*/
//[nested_strict_lock
@@ -117,8 +127,8 @@
*
* __Requires: <c>lk.mutex() != null_ptr</c>
* __Effects: Stores the reference to the lock parameter and takes ownership on it.
- * If the lock doesn't owns the mutex @mtx lock it.
- * __Postconditions: @c owns_lock()
+ * If the lock doesn't owns the mutex @c mtx lock it.
+ * __Postconditions: @c owns_lock(lk.mutex())
* __StrongException
* __Throws:
*
@@ -127,7 +137,7 @@
* - Any exception that @c lk.lock() can throw.
*
*/
- nested_strict_lock(Lock& lk) :
+ explicit nested_strict_lock(Lock& lk) :
lk_(lk) /*< Store reference to lk >*/
{
/*< Define BOOST_THREAD_DONT_CHECK_PRECONDITIONS if you don't want to check lk ownership >*/
@@ -138,6 +148,19 @@
tmp_lk_ = move(lk); /*< Move ownership to temporary lk >*/
}
+#if ! defined BOOST_NO_CXX11_HDR_INITIALIZER_LIST
+ nested_strict_lock(std::initializer_list<thread_detail::lockable_wrapper<Lock> > l_) :
+ lk_(*(const_cast<thread_detail::lockable_wrapper<Lock>*>(l_.begin())->m))
+ {
+ /*< Define BOOST_THREAD_DONT_CHECK_PRECONDITIONS if you don't want to check lk ownership >*/
+ BOOST_THREAD_ASSERT_PRECONDITION( lk_.mutex() != 0,
+ lock_error()
+ );
+ if (!lk_.owns_lock()) lk_.lock(); /*< ensures it is locked >*/
+ tmp_lk_ = move(lk_); /*< Move ownership to temporary lk >*/
+ }
+#endif
+
/**
* Destructor
*
@@ -180,6 +203,18 @@
{
};
+#if ! defined BOOST_NO_CXX11_HDR_INITIALIZER_LIST
+ template <typename Lockable>
+ strict_lock<Lockable> make_strict_lock(Lockable& mtx)
+ {
+ return { thread_detail::lockable_wrapper<Lockable>(mtx) };
+ }
+ template <typename Lock>
+ nested_strict_lock<Lock> make_nested_strict_lock(Lock& lk)
+ {
+ return { thread_detail::lockable_wrapper<Lock>(lk) };
+ }
+#endif
}
#include <boost/config/abi_suffix.hpp>
Modified: branches/release/boost/thread/synchronized_value.hpp
==============================================================================
--- branches/release/boost/thread/synchronized_value.hpp (original)
+++ branches/release/boost/thread/synchronized_value.hpp 2012-12-16 14:01:45 EST (Sun, 16 Dec 2012)
@@ -23,6 +23,195 @@
namespace boost
{
+
+ /**
+ *
+ */
+ template <typename T, typename Lockable = mutex>
+ class const_strict_lock_ptr
+ {
+ public:
+ typedef T value_type;
+ typedef Lockable lockable_type;
+ protected:
+
+ // this should be a strict_lock, but we need to be able to return it.
+ boost::unique_lock<lockable_type> lk_;
+ T const& value_;
+
+ public:
+ BOOST_THREAD_MOVABLE_ONLY( const_strict_lock_ptr )
+
+ const_strict_lock_ptr(T const& value, Lockable & mtx) :
+ lk_(mtx), value_(value)
+ {
+ }
+
+ const_strict_lock_ptr(BOOST_THREAD_RV_REF(const_strict_lock_ptr) other)
+ : lk_(boost::move(BOOST_THREAD_RV(other).lk_)),value_(BOOST_THREAD_RV(other).value_)
+ {
+ }
+
+ ~const_strict_lock_ptr()
+ {
+ }
+
+ const T* operator->() const
+ {
+ return &value_;
+ }
+
+ const T& operator*() const
+ {
+ return value_;
+ }
+
+ };
+
+ /**
+ *
+ */
+ template <typename T, typename Lockable = mutex>
+ class strict_lock_ptr : public const_strict_lock_ptr<T,Lockable>
+ {
+ typedef const_strict_lock_ptr<T,Lockable> base_type;
+ public:
+ BOOST_THREAD_MOVABLE_ONLY( strict_lock_ptr )
+
+ strict_lock_ptr(T & value, Lockable & mtx) :
+ base_type(value, mtx)
+ {
+ }
+
+ strict_lock_ptr(BOOST_THREAD_RV_REF(strict_lock_ptr) other)
+ : base_type(boost::move(static_cast<base_type&>(other)))
+ {
+ }
+
+ ~strict_lock_ptr()
+ {
+ }
+
+ T* operator->()
+ {
+ return const_cast<T*>(&this->value_);
+ }
+
+ T& operator*()
+ {
+ return const_cast<T&>(this->value_);
+ }
+
+ };
+
+ /**
+ *
+ */
+ template <typename T, typename Lockable = mutex>
+ class const_unique_lock_ptr : public unique_lock<Lockable>
+ {
+ typedef unique_lock<Lockable> base_type;
+ public:
+ typedef T value_type;
+ typedef Lockable lockable_type;
+ protected:
+ T const& value_;
+
+ public:
+ BOOST_THREAD_MOVABLE_ONLY(const_unique_lock_ptr)
+
+ const_unique_lock_ptr(T const& value, Lockable & mtx)
+ : base_type(mtx), value_(value)
+ {
+ }
+ const_unique_lock_ptr(T const& value, Lockable & mtx, adopt_lock_t)
+ : base_type(mtx, adopt_lock), value_(value)
+ {
+ }
+ const_unique_lock_ptr(T const& value, Lockable & mtx, defer_lock_t)
+ : base_type(mtx, defer_lock), value_(value)
+ {
+ }
+ const_unique_lock_ptr(T const& value, Lockable & mtx, try_to_lock_t)
+ : base_type(mtx, try_to_lock), value_(value)
+ {
+ }
+ const_unique_lock_ptr(BOOST_THREAD_RV_REF(const_unique_lock_ptr) other)
+ : base_type(boost::move(static_cast<base_type&>(other))), value_(BOOST_THREAD_RV(other).value_)
+ {
+ }
+
+ ~const_unique_lock_ptr()
+ {
+ }
+
+ const T* operator->() const
+ {
+ BOOST_ASSERT (this->owns_lock());
+ return &value_;
+ }
+
+ const T& operator*() const
+ {
+ BOOST_ASSERT (this->owns_lock());
+ return value_;
+ }
+
+ };
+
+ /**
+ *
+ */
+ template <typename T, typename Lockable = mutex>
+ class unique_lock_ptr : public const_unique_lock_ptr<T, Lockable>
+ {
+ typedef const_unique_lock_ptr<T, Lockable> base_type;
+ public:
+ typedef T value_type;
+ typedef Lockable lockable_type;
+
+ BOOST_THREAD_MOVABLE_ONLY(unique_lock_ptr)
+
+ unique_lock_ptr(T & value, Lockable & mtx)
+ : base_type(value, mtx)
+ {
+ }
+ unique_lock_ptr(T & value, Lockable & mtx, adopt_lock_t)
+ : base_type(value, mtx, adopt_lock)
+ {
+ }
+ unique_lock_ptr(T & value, Lockable & mtx, defer_lock_t)
+ : base_type(value, mtx, defer_lock)
+ {
+ }
+ unique_lock_ptr(T & value, Lockable & mtx, try_to_lock_t)
+ : base_type(value, mtx, try_to_lock)
+ {
+ }
+ unique_lock_ptr(BOOST_THREAD_RV_REF(unique_lock_ptr) other)
+ : base_type(boost::move(static_cast<base_type&>(other)))
+ {
+ }
+
+ ~unique_lock_ptr()
+ {
+ }
+
+ T* operator->()
+ {
+ BOOST_ASSERT (this->owns_lock());
+ return const_cast<T*>(&this->value_);
+ }
+
+ T& operator*()
+ {
+ BOOST_ASSERT (this->owns_lock());
+ return const_cast<T&>(this->value_);
+ }
+
+
+ };
+
/**
*
*/
@@ -181,99 +370,24 @@
boost::swap(value_, rhs.value_);
}
- /**
- *
- */
- struct const_strict_synchronizer
- {
- protected:
- friend class synchronized_value;
-
- // this should be a strict_lock, but we need to be able to return it.
- boost::unique_lock<lockable_type> lk_;
- T const& value_;
-
- explicit const_strict_synchronizer(synchronized_value const& outer) :
- lk_(outer.mtx_), value_(outer.value_)
- {
- }
- public:
- BOOST_THREAD_MOVABLE_ONLY( const_strict_synchronizer )
-
- const_strict_synchronizer(BOOST_THREAD_RV_REF(const_strict_synchronizer) other)
- : lk_(boost::move(BOOST_THREAD_RV(other).lk_)),value_(BOOST_THREAD_RV(other).value_)
- {
- }
-
- ~const_strict_synchronizer()
- {
- }
-
- const T* operator->() const
- {
- return &value_;
- }
-
- const T& operator*() const
- {
- return value_;
- }
-
- };
-
- /**
- *
- */
- struct strict_synchronizer : const_strict_synchronizer
- {
- protected:
- friend class synchronized_value;
-
- explicit strict_synchronizer(synchronized_value& outer) :
- const_strict_synchronizer(const_cast<synchronized_value&>(outer))
- {
- }
- public:
- BOOST_THREAD_MOVABLE_ONLY( strict_synchronizer )
-
- strict_synchronizer(BOOST_THREAD_RV_REF(strict_synchronizer) other)
- : const_strict_synchronizer(boost::move(static_cast<const_strict_synchronizer&>(other)))
- {
- }
-
- ~strict_synchronizer()
- {
- }
-
- T* operator->()
- {
- return const_cast<T*>(&this->value_);
- }
-
- T& operator*()
- {
- return const_cast<T&>(this->value_);
- }
-
- };
/**
* Essentially calling a method obj->foo(x, y, z) calls the method foo(x, y, z) inside a critical section as
* long-lived as the call itself.
*/
- strict_synchronizer operator->()
+ strict_lock_ptr<T,Lockable> operator->()
{
- return BOOST_THREAD_MAKE_RV_REF(strict_synchronizer(*this));
+ return BOOST_THREAD_MAKE_RV_REF((strict_lock_ptr<T,Lockable>(value_, mtx_)));
}
/**
* If the synchronized_value object involved is const-qualified, then you'll only be able to call const methods
* through operator->. So, for example, vec->push_back("xyz") won't work if vec were const-qualified.
* The locking mechanism capitalizes on the assumption that const methods don't modify their underlying data.
*/
- const_strict_synchronizer operator->() const
+ const_strict_lock_ptr<T,Lockable> operator->() const
{
- return BOOST_THREAD_MAKE_RV_REF(const_strict_synchronizer(*this));
+ return BOOST_THREAD_MAKE_RV_REF((const_strict_lock_ptr<T,Lockable>(value_, mtx_)));
}
/**
@@ -288,83 +402,32 @@
* assert(vec.back() == 42);
* }
*/
- strict_synchronizer synchronize()
+ strict_lock_ptr<T,Lockable> synchronize()
{
- return BOOST_THREAD_MAKE_RV_REF(strict_synchronizer(*this));
+ return BOOST_THREAD_MAKE_RV_REF((strict_lock_ptr<T,Lockable>(value_, mtx_)));
}
- const_strict_synchronizer synchronize() const
+ const_strict_lock_ptr<T,Lockable> synchronize() const
{
- return BOOST_THREAD_MAKE_RV_REF(const_strict_synchronizer(*this));
+ return BOOST_THREAD_MAKE_RV_REF((const_strict_lock_ptr<T,Lockable>(value_, mtx_)));
}
- /**
- *
- */
- struct unique_synchronizer : unique_lock<lockable_type>
+ unique_lock_ptr<T,Lockable> unique_synchronize()
{
- private:
- //friend class synchronized_value;
- typedef unique_lock<lockable_type> base_type;
-
- T& value_;
-
- public:
- BOOST_THREAD_MOVABLE_ONLY(unique_synchronizer)
-
- explicit unique_synchronizer(synchronized_value& outer)
- : base_type(outer.mtx_), value_(outer.value_)
- {
- }
- unique_synchronizer(synchronized_value& outer, adopt_lock_t)
- : base_type(outer.mtx_, adopt_lock), value_(outer.value_)
- {
- }
- unique_synchronizer(synchronized_value& outer, defer_lock_t)
- : base_type(outer.mtx_, defer_lock), value_(outer.value_)
- {
- }
- unique_synchronizer(synchronized_value& outer, try_to_lock_t)
- : base_type(outer.mtx_, try_to_lock), value_(outer.value_)
- {
- }
- unique_synchronizer(BOOST_THREAD_RV_REF(unique_synchronizer) other)
- : base_type(boost::move(other)),value_(BOOST_THREAD_RV(other).value_)
- {
- }
-
- ~unique_synchronizer()
- {
- }
-
- T* operator->()
- {
- if (this->owns_lock())
- return &value_;
- else
- return 0;
- }
-
- const T* operator->() const
- {
- if (this->owns_lock())
- return &value_;
- else
- return 0;
- }
-
- T& operator*()
- {
- BOOST_ASSERT (this->owns_lock());
- return value_;
- }
-
- const T& operator*() const
- {
- BOOST_ASSERT (this->owns_lock());
- return value_;
- }
+ return BOOST_THREAD_MAKE_RV_REF((unique_lock_ptr<T,Lockable>(value_, mtx_)));
+ }
+ unique_lock_ptr<T,Lockable> unique_synchronize(defer_lock_t tag)
+ {
+ return BOOST_THREAD_MAKE_RV_REF((unique_lock_ptr<T,Lockable>(value_, mtx_, tag)));
+ }
+ const_unique_lock_ptr<T,Lockable> unique_synchronize() const
+ {
+ return BOOST_THREAD_MAKE_RV_REF((const_unique_lock_ptr<T,Lockable>(value_, mtx_)));
+ }
+ const_unique_lock_ptr<T,Lockable> unique_synchronize(defer_lock_t tag) const
+ {
+ return BOOST_THREAD_MAKE_RV_REF((const_unique_lock_ptr<T,Lockable>(value_, mtx_, tag)));
+ }
- };
private:
class deref_value
Modified: branches/release/libs/thread/build/Jamfile.v2
==============================================================================
--- branches/release/libs/thread/build/Jamfile.v2 (original)
+++ branches/release/libs/thread/build/Jamfile.v2 2012-12-16 14:01:45 EST (Sun, 16 Dec 2012)
@@ -48,7 +48,7 @@
<tag>@$(__name__).tag
<toolset>gcc:<cxxflags>-Wno-long-long
<define>BOOST_THREAD_THROW_IF_PRECONDITION_NOT_SATISFIED
- <define>BOOST_SYSTEM_NO_DEPRECATED
+ #<define>BOOST_SYSTEM_NO_DEPRECATED
#<define>BOOST_THREAD_DONT_PROVIDE_INTERRUPTIONS
<library>/boost/system//boost_system
@@ -114,7 +114,7 @@
<link>static:<define>BOOST_THREAD_BUILD_LIB=1
<link>shared:<define>BOOST_THREAD_BUILD_DLL=1
<define>BOOST_THREAD_THROW_IF_PRECONDITION_NOT_SATISFIED
- <define>BOOST_SYSTEM_NO_DEPRECATED
+ #<define>BOOST_SYSTEM_NO_DEPRECATED
<library>/boost/system//boost_system
;
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 2012-12-16 14:01:45 EST (Sun, 16 Dec 2012)
@@ -4,8 +4,9 @@
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//#define BOOST_THREAD_VERSION 4
-#define BOOST_THREAD_USES_LOG
-#define BOOST_THREAD_DONT_PROVIDE_FUTURE_INVALID_AFTER_GET
+//#define BOOST_THREAD_USES_LOG
+#define BOOST_THREAD_USES_LOG_THREAD_ID
+//#define BOOST_THREAD_DONT_PROVIDE_FUTURE_INVALID_AFTER_GET
#include <boost/thread/detail/log.hpp>
#include <boost/thread/future.hpp>
Modified: branches/release/libs/thread/example/synchronized_person.cpp
==============================================================================
--- branches/release/libs/thread/example/synchronized_person.cpp (original)
+++ branches/release/libs/thread/example/synchronized_person.cpp 2012-12-16 14:01:45 EST (Sun, 16 Dec 2012)
@@ -158,7 +158,7 @@
#if ! defined BOOST_NO_CXX11_AUTO_DECLARATIONS
auto memberSync = member.synchronize();
#else
- boost::synchronized_value<Member>::const_strict_synchronizer memberSync = member.synchronize();
+ boost::const_strict_lock_ptr<Member> memberSync = member.synchronize();
#endif
Invariant(memberSync);
return memberSync->name;
@@ -167,7 +167,7 @@
#if ! defined BOOST_NO_CXX11_AUTO_DECLARATIONS
auto memberSync = member.synchronize();
#else
- boost::synchronized_value<Member>::strict_synchronizer memberSync = member.synchronize();
+ boost::strict_lock_ptr<Member> memberSync = member.synchronize();
#endif
Invariant(memberSync);
memberSync->name = newName;
@@ -180,7 +180,7 @@
std::string name;
unsigned int age;
};
- void Invariant(boost::synchronized_value<Member>::const_strict_synchronizer & mbr) const
+ void Invariant(boost::const_strict_lock_ptr<Member> & mbr) const
{
if (mbr->age < 1) throw std::runtime_error("Age cannot be negative");
}
@@ -236,5 +236,24 @@
Person3_ts p(1);
p->SetName("Vicente");
}
+ {
+ Person3_ts p1(1);
+ Person3_ts p2(2);
+ Person3_ts p3(3);
+#if ! defined BOOST_NO_CXX11_AUTO_DECLARATIONS
+ auto lk1 = p1.unique_synchronize(boost::defer_lock);
+ auto lk2 = p2.unique_synchronize(boost::defer_lock);
+ auto lk3 = p3.unique_synchronize(boost::defer_lock);
+#else
+ boost::unique_lock_ptr<Person3> lk1 = p1.unique_synchronize(boost::defer_lock);
+ boost::unique_lock_ptr<Person3> lk2 = p2.unique_synchronize(boost::defer_lock);
+ boost::unique_lock_ptr<Person3> lk3 = p3.unique_synchronize(boost::defer_lock);
+#endif
+ boost::lock(lk1,lk2,lk3);
+
+ lk1->SetName("Carmen");
+ lk2->SetName("Javier");
+ lk3->SetName("Matias");
+ }
return 0;
}
Modified: branches/release/libs/thread/example/synchronized_value.cpp
==============================================================================
--- branches/release/libs/thread/example/synchronized_value.cpp (original)
+++ branches/release/libs/thread/example/synchronized_value.cpp 2012-12-16 14:01:45 EST (Sun, 16 Dec 2012)
@@ -12,7 +12,7 @@
void addTrailingSlashIfMissing(boost::synchronized_value<std::string> & path)
{
- boost::synchronized_value<std::string>::strict_synchronizer u=path.synchronize();
+ boost::strict_lock_ptr<std::string> u=path.synchronize();
if(u->empty() || (*u->rbegin()!='/'))
{
@@ -24,13 +24,13 @@
std::cout<<"v="<<*v<<std::endl;
}
-void g(const boost::synchronized_value<int>::const_strict_synchronizer &v) {
+void g(const boost::const_strict_lock_ptr<int> &v) {
std::cout<<"v="<<*v<<std::endl;
}
bool checkIfMissingTrailingSlash(boost::synchronized_value<std::string> & path)
{
- boost::synchronized_value<std::string>::strict_synchronizer u=path.synchronize();
+ boost::strict_lock_ptr<std::string> u=path.synchronize();
return (u->empty() || (*u->rbegin()!='/'));
}
@@ -46,7 +46,7 @@
std::cout<<"i="<<i<<std::endl;
{
- boost::synchronized_value<int>::strict_synchronizer u=v1.synchronize();
+ boost::strict_lock_ptr<int> u=v1.synchronize();
*u+=43;
std::cout<<"v1="<<*u<<std::endl;
Modified: branches/release/libs/thread/src/future.cpp
==============================================================================
--- branches/release/libs/thread/src/future.cpp (original)
+++ branches/release/libs/thread/src/future.cpp 2012-12-16 14:01:45 EST (Sun, 16 Dec 2012)
@@ -7,7 +7,7 @@
#ifndef BOOST_NO_EXCEPTIONS
-#include <boost/thread/future.hpp>
+#include <boost/thread/future_error_code.hpp>
namespace boost
{
@@ -19,12 +19,12 @@
public boost::system::error_category
{
public:
- virtual const char* name() const; //BOOST_NOEXCEPT;
+ virtual const char* name() const BOOST_NOEXCEPT;
virtual std::string message(int ev) const;
};
const char*
- future_error_category::name() const //BOOST_NOEXCEPT
+ future_error_category::name() const BOOST_NOEXCEPT
{
return "future";
}
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 2012-12-16 14:01:45 EST (Sun, 16 Dec 2012)
@@ -395,7 +395,7 @@
bool thread::joinable() const BOOST_NOEXCEPT
{
- return (get_thread_info)()!=0;
+ return (get_thread_info)()?true:false;
}
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 2012-12-16 14:01:45 EST (Sun, 16 Dec 2012)
@@ -330,7 +330,7 @@
bool thread::joinable() const BOOST_NOEXCEPT
{
- return (get_thread_info)() != 0;
+ return (get_thread_info)() ? true : false;
}
bool thread::join_noexcept()
{
Modified: branches/release/libs/thread/test/Jamfile.v2
==============================================================================
--- branches/release/libs/thread/test/Jamfile.v2 (original)
+++ branches/release/libs/thread/test/Jamfile.v2 2012-12-16 14:01:45 EST (Sun, 16 Dec 2012)
@@ -228,7 +228,7 @@
[ thread-run test_5542_2.cpp ]
[ thread-run test_5542_3.cpp ]
[ thread-run test_5891.cpp ]
- [ thread-run test_6130.cpp ]
+ #[ thread-run test_6130.cpp ]
#[ thread-run test_6170.cpp ]
[ thread-run test_6174.cpp ]
#[ thread-run test_7160.cpp ]
@@ -480,7 +480,7 @@
[ thread-run2-noit ./sync/mutual_exclusion/locks/strict_lock/default_pass.cpp : strict_lock__cons__default_p ]
[ thread-run2-noit ./sync/mutual_exclusion/locks/strict_lock/owns_lock_pass.cpp : strict_lock__owns_lock_p ]
[ thread-run2-noit ./sync/mutual_exclusion/locks/strict_lock/types_pass.cpp : strict_lock__types_p ]
- #[ thread-run2-noit ./sync/mutual_exclusion/locks/strict_lock/make_strict_lock_pass.cpp : make_strict_lock_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/locks/strict_lock/make_strict_lock_pass.cpp : make_strict_lock_p ]
;
#explicit ts_nested_strict_lock ;
@@ -491,7 +491,7 @@
[ thread-run2-noit ./sync/mutual_exclusion/locks/nested_strict_lock/default_pass.cpp : nested_strict_lock__cons__default_p ]
[ thread-run2-noit ./sync/mutual_exclusion/locks/nested_strict_lock/owns_lock_pass.cpp : nested_strict_lock__owns_lock_p ]
[ thread-run2-noit ./sync/mutual_exclusion/locks/nested_strict_lock/types_pass.cpp : nested_strict_lock__types_p ]
- #[ thread-run2-noit ./sync/mutual_exclusion/locks/nested_strict_lock/make_nested_strict_lock_pass.cpp : make_nested_strict_lock_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/locks/nested_strict_lock/make_nested_strict_lock_pass.cpp : make_nested_strict_lock_p ]
;
@@ -662,11 +662,11 @@
explicit ts_ ;
test-suite ts_
:
- [ thread-run2-noit ./sync/conditions/notify_all_at_thread_exit_pass.cpp : notify_all_at_thread_exit_p2 ]
- [ thread-run2-noit ./threads/thread/members/try_join_until_pass.cpp : thread__join_until_p2 ]
- [ thread-run2-noit ./threads/thread/members/try_join_for_pass.cpp : thread__join_for_p2 ]
- [ thread-run2-noit ./sync/futures/async/async_pass.cpp : async__async_p2 ]
+ #[ thread-run2-noit ./sync/futures/future/then_pass.cpp : future__then_p ]
+ #[ thread-run ../example/test_so.cpp ]
+ #[ thread-run ../example/test_so2.cpp ]
+ #[ compile virtual_noexcept.cpp ]
#[ thread-run test_7665.cpp ]
#[ thread-run test_7666.cpp ]
#[ thread-run ../example/unwrap.cpp ]
Modified: branches/release/libs/thread/test/sync/futures/future/get_pass.cpp
==============================================================================
--- branches/release/libs/thread/test/sync/futures/future/get_pass.cpp (original)
+++ branches/release/libs/thread/test/sync/futures/future/get_pass.cpp 2012-12-16 14:01:45 EST (Sun, 16 Dec 2012)
@@ -22,6 +22,9 @@
//#define BOOST_THREAD_VERSION 3
#define BOOST_THREAD_VERSION 4
+#define BOOST_THREAD_USES_LOG
+#define BOOST_THREAD_USES_LOG_THREAD_ID
+#include <boost/thread/detail/log.hpp>
#include <boost/thread/future.hpp>
#include <boost/thread/thread.hpp>
@@ -87,49 +90,65 @@
int main()
{
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
{
typedef int T;
+// {
+// boost::promise<T> p;
+// boost::future<T> f = p.get_future();
+//#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+// boost::thread(func1, boost::move(p)).detach();
+//#else
+// p.set_value(3);
+//#endif
+// BOOST_TEST(f.valid());
+// BOOST_TEST(f.get() == 3);
+//#ifdef BOOST_THREAD_PROVIDES_FUTURE_INVALID_AFTER_GET
+// BOOST_TEST(!f.valid());
+//#endif
+// }
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
{
boost::promise<T> p;
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
boost::future<T> f = p.get_future();
-#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
- boost::thread(func1, boost::move(p)).detach();
-#else
- p.set_value(3);
-#endif
- BOOST_TEST(f.valid());
- BOOST_TEST(f.get() == 3);
-#ifdef BOOST_THREAD_PROVIDES_FUTURE_INVALID_AFTER_GET
- BOOST_TEST(!f.valid());
-#endif
- }
- {
- boost::promise<T> p;
- boost::future<T> f = p.get_future();
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
boost::thread(func2, boost::move(p)).detach();
#else
p.set_exception(boost::make_exception_ptr(3));
#endif
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
try
{
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
BOOST_TEST(f.valid());
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
BOOST_TEST(f.get() == 3);
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
BOOST_TEST(false);
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
}
catch (boost::wrap<int> const& i)
{
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
BOOST_TEST(i.value == 3);
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
}
catch (...)
{
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
BOOST_TEST(false);
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
}
#ifdef BOOST_THREAD_PROVIDES_FUTURE_INVALID_AFTER_GET
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
BOOST_TEST(!f.valid());
#endif
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
}
}
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
{
typedef int& T;
{
@@ -147,6 +166,7 @@
BOOST_TEST(!f.valid());
#endif
}
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
{
boost::promise<T> p;
boost::future<T> f = p.get_future();
@@ -170,6 +190,7 @@
#endif
}
}
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
typedef void T;
{
@@ -186,6 +207,7 @@
BOOST_TEST(!f.valid());
#endif
}
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
{
boost::promise<T> p;
boost::future<T> f = p.get_future();
@@ -212,6 +234,7 @@
BOOST_TEST(!f.valid());
#endif
}
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
return boost::report_errors();
}
Modified: branches/release/libs/thread/test/sync/futures/future/then_pass.cpp
==============================================================================
--- branches/release/libs/thread/test/sync/futures/future/then_pass.cpp (original)
+++ branches/release/libs/thread/test/sync/futures/future/then_pass.cpp 2012-12-16 14:01:45 EST (Sun, 16 Dec 2012)
@@ -8,10 +8,13 @@
// class future<R>
// template<typename F>
-// auto then(F&& func) -> BOOST_THREAD_FUTURE<decltype(func(*this))>;
+// auto then(F&& func) -> future<decltype(func(*this))>;
#define BOOST_THREAD_VERSION 4
#define BOOST_THREAD_DONT_PROVIDE_FUTURE_INVALID_AFTER_GET
+//#define BOOST_THREAD_USES_LOG
+#define BOOST_THREAD_USES_LOG_THREAD_ID
+#include <boost/thread/detail/log.hpp>
#include <boost/thread/future.hpp>
#include <boost/detail/lightweight_test.hpp>
@@ -30,23 +33,37 @@
int main()
{
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
{
boost::future<int> f1 = boost::async(p1);
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
boost::future<int> f2 = f1.then(p2);
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
BOOST_TEST(f2.get()==2);
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
}
{
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
boost::future<int> f2 = boost::async(p1).then(p2);
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
BOOST_TEST(f2.get()==2);
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
}
{
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
boost::future<int> f1 = boost::async(p1);
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
boost::future<int> f2 = f1.then(p2).then(p2);
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
BOOST_TEST(f2.get()==4);
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
}
{
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
boost::future<int> f2 = boost::async(p1).then(p2).then(p2);
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
BOOST_TEST(f2.get()==4);
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
}
return boost::report_errors();
Modified: branches/release/libs/thread/test/sync/futures/packaged_task/make_ready_at_thread_exit_pass.cpp
==============================================================================
--- branches/release/libs/thread/test/sync/futures/packaged_task/make_ready_at_thread_exit_pass.cpp (original)
+++ branches/release/libs/thread/test/sync/futures/packaged_task/make_ready_at_thread_exit_pass.cpp 2012-12-16 14:01:45 EST (Sun, 16 Dec 2012)
@@ -99,7 +99,14 @@
{
boost::packaged_task<double(int, char)> p(A(5));
boost::future<double> f = p.get_future();
- // BUG boost::thread(func0, boost::move(p)).detach();
+ // fixme BUG boost::thread(func0, boost::move(p)).detach();
+ boost::thread(func0, &p).detach();
+ BOOST_TEST(f.get() == 105.0);
+ }
+ {
+ boost::packaged_task<double(int, char)> p2(A(5));
+ boost::future<double> f = p2.get_future();
+ boost::packaged_task<double(int, char)> p = boost::move(p2);
boost::thread(func0, &p).detach();
BOOST_TEST(f.get() == 105.0);
}
@@ -119,6 +126,21 @@
}
}
{
+ boost::packaged_task<double(int, char)> p2(A(5));
+ boost::future<double> f = p2.get_future();
+ boost::packaged_task<double(int, char)> p = boost::move(p2);
+ boost::thread(func1, &p).detach();
+ try
+ {
+ f.get();
+ BOOST_TEST(false);
+ }
+ catch (const E& e)
+ {
+ BOOST_TEST(e.data == 6);
+ }
+ }
+ {
boost::packaged_task<double(int, char)> p(A(5));
boost::future<double> f = p.get_future();
//boost::thread(func2, boost::move(p)).detach();
@@ -126,11 +148,24 @@
BOOST_TEST(f.get() == 105.0);
}
{
- boost::packaged_task<double(int, char)> p;
+ boost::packaged_task<double(int, char)> p2(A(5));
+ boost::future<double> f = p2.get_future();
+ boost::packaged_task<double(int, char)> p = boost::move(p2);
+ boost::thread(func2, &p).detach();
+ BOOST_TEST(f.get() == 105.0);
+ }
+ {
+ boost::packaged_task<double(int, char)> p(A(5));
//boost::thread t(func3, boost::move(p));
boost::thread t(func3, &p);
t.join();
}
+ {
+ boost::packaged_task<double(int, char)> p2(A(5));
+ boost::packaged_task<double(int, char)> p = boost::move(p2);
+ boost::thread t(func3, &p);
+ t.join();
+ }
return boost::report_errors();
}
Modified: branches/release/libs/thread/test/sync/futures/promise/set_exception_at_thread_exit_pass.cpp
==============================================================================
--- branches/release/libs/thread/test/sync/futures/promise/set_exception_at_thread_exit_pass.cpp (original)
+++ branches/release/libs/thread/test/sync/futures/promise/set_exception_at_thread_exit_pass.cpp 2012-12-16 14:01:45 EST (Sun, 16 Dec 2012)
@@ -73,6 +73,27 @@
BOOST_TEST(false);
}
}
+ {
+ typedef int T;
+ boost::promise<T> p2;
+ boost::future<T> f = p2.get_future();
+ //boost::thread(func, boost::move(p)).detach();
+ p = boost::move(p2);
+ boost::thread(func).detach();
+ try
+ {
+ f.get();
+ BOOST_TEST(false);
+ }
+ catch (boost::wrap<int> i)
+ {
+ BOOST_TEST(i.value == 3);
+ }
+ catch (...)
+ {
+ BOOST_TEST(false);
+ }
+ }
return boost::report_errors();
}
Modified: branches/release/libs/thread/test/sync/futures/promise/set_value_at_thread_exit_const_pass.cpp
==============================================================================
--- branches/release/libs/thread/test/sync/futures/promise/set_value_at_thread_exit_const_pass.cpp (original)
+++ branches/release/libs/thread/test/sync/futures/promise/set_value_at_thread_exit_const_pass.cpp 2012-12-16 14:01:45 EST (Sun, 16 Dec 2012)
@@ -40,6 +40,13 @@
boost::thread(func).detach();
BOOST_TEST(f.get() == 5);
}
+ {
+ boost::promise<int> p2;
+ boost::future<int> f = p2.get_future();
+ p = boost::move(p2);
+ boost::thread(func).detach();
+ BOOST_TEST(f.get() == 5);
+ }
return boost::report_errors();
}
Modified: branches/release/libs/thread/test/sync/futures/promise/set_value_at_thread_exit_void_pass.cpp
==============================================================================
--- branches/release/libs/thread/test/sync/futures/promise/set_value_at_thread_exit_void_pass.cpp (original)
+++ branches/release/libs/thread/test/sync/futures/promise/set_value_at_thread_exit_void_pass.cpp 2012-12-16 14:01:45 EST (Sun, 16 Dec 2012)
@@ -19,8 +19,11 @@
// void promise<void>::set_value_at_thread_exit();
#define BOOST_THREAD_VERSION 4
+#define BOOST_THREAD_USES_LOG
+#define BOOST_THREAD_USES_LOG_THREAD_ID
#include <boost/thread/future.hpp>
+#include <boost/thread/detail/log.hpp>
#include <boost/detail/lightweight_test.hpp>
int i = 0;
@@ -35,7 +38,7 @@
void func2(boost::promise<void> p2)
{
p2.set_value_at_thread_exit();
- i = 1;
+ i = 2;
}
int main()
@@ -57,20 +60,39 @@
BOOST_TEST(false);
}
+ try
+ {
+ boost::promise<void> p2;
+ boost::future<void> f = p2.get_future();
+ p = boost::move(p2);
+ boost::thread(func).detach();
+ f.get();
+ BOOST_TEST(i == 1);
+
+ }
+ catch(std::exception ex)
+ {
+ std::cout << __FILE__ << ":" << __LINE__ << " " << ex.what() << std::endl;
+ BOOST_TEST(false);
+ }
+ catch(...)
+ {
+ BOOST_TEST(false);
+ }
// BUG when moving promise. fixme
// try
// {
-// std::cout << __FILE__ << ":" << __LINE__ <<std::endl;
+// BOOST_THREAD_LOG << BOOST_THREAD_END_LOG
// boost::promise<void> p2; // BUG
-// std::cout << __FILE__ << ":" << __LINE__ <<std::endl;
+// BOOST_THREAD_LOG << BOOST_THREAD_END_LOG
// boost::future<void> f = p2.get_future();
-// std::cout << __FILE__ << ":" << __LINE__ <<std::endl;
+// BOOST_THREAD_LOG << BOOST_THREAD_END_LOG
// boost::thread(func2, boost::move(p2)).detach(); // BUG
-// std::cout << __FILE__ << ":" << __LINE__ <<std::endl;
+// BOOST_THREAD_LOG << BOOST_THREAD_END_LOG
// f.get();
-// std::cout << __FILE__ << ":" << __LINE__ <<std::endl;
-// BOOST_TEST(i == 1);
-// std::cout << __FILE__ << ":" << __LINE__ <<std::endl;
+// BOOST_THREAD_LOG << BOOST_THREAD_END_LOG
+// BOOST_TEST(i == 2);
+// BOOST_THREAD_LOG << BOOST_THREAD_END_LOG
//
// }
// catch(std::exception ex)
Modified: branches/release/libs/thread/test/sync/mutual_exclusion/locks/nested_strict_lock/copy_ctor_fail.cpp
==============================================================================
--- branches/release/libs/thread/test/sync/mutual_exclusion/locks/nested_strict_lock/copy_ctor_fail.cpp (original)
+++ branches/release/libs/thread/test/sync/mutual_exclusion/locks/nested_strict_lock/copy_ctor_fail.cpp 2012-12-16 14:01:45 EST (Sun, 16 Dec 2012)
@@ -20,8 +20,8 @@
int main()
{
- boost::nested_strict_lock<boost::mutex> lk0(m0);
- boost::nested_strict_lock<boost::mutex> lk1 = lk0;
+ boost::nested_strict_lock<boost::unique_lock<boost::mutex> > lk0(m0);
+ boost::nested_strict_lock<boost::unique_lock<boost::mutex> > lk1 = lk0;
}
#include "../../../../remove_error_code_unused_warning.hpp"
Modified: branches/release/libs/thread/test/sync/mutual_exclusion/locks/nested_strict_lock/make_nested_strict_lock_pass.cpp
==============================================================================
--- branches/release/libs/thread/test/sync/mutual_exclusion/locks/nested_strict_lock/make_nested_strict_lock_pass.cpp (original)
+++ branches/release/libs/thread/test/sync/mutual_exclusion/locks/nested_strict_lock/make_nested_strict_lock_pass.cpp 2012-12-16 14:01:45 EST (Sun, 16 Dec 2012)
@@ -30,7 +30,7 @@
boost::mutex m;
-#if ! defined(BOOST_NO_CXX11_AUTO) && ! defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && ! defined BOOST_NO_CXX11_HDR_INITIALIZER_LIST && BOOST_THREAD_USES_CHRONO
+#if ! defined(BOOST_NO_CXX11_AUTO) && ! defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && ! defined BOOST_NO_CXX11_HDR_INITIALIZER_LIST && defined BOOST_THREAD_USES_CHRONO
void f()
{
@@ -38,7 +38,7 @@
time_point t1;
boost::unique_lock<boost::mutex> lg(m);
{
- const auto&& nlg = boost::make_strict_lock(lg); (void)nlg;
+ const auto&& nlg = boost::make_nested_strict_lock(lg); (void)nlg;
t1 = Clock::now();
BOOST_THREAD_TRACE;
}
Modified: branches/release/libs/thread/test/sync/mutual_exclusion/locks/strict_lock/make_strict_lock_pass.cpp
==============================================================================
--- branches/release/libs/thread/test/sync/mutual_exclusion/locks/strict_lock/make_strict_lock_pass.cpp (original)
+++ branches/release/libs/thread/test/sync/mutual_exclusion/locks/strict_lock/make_strict_lock_pass.cpp 2012-12-16 14:01:45 EST (Sun, 16 Dec 2012)
@@ -29,7 +29,7 @@
boost::mutex m;
-#if ! defined(BOOST_NO_CXX11_AUTO) && ! defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && ! defined BOOST_NO_CXX11_HDR_INITIALIZER_LIST && BOOST_THREAD_USES_CHRONO
+#if ! defined(BOOST_NO_CXX11_AUTO) && ! defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && ! defined BOOST_NO_CXX11_HDR_INITIALIZER_LIST && defined BOOST_THREAD_USES_CHRONO
void f()
{
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