Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r77704 - in trunk: boost/thread boost/thread/pthread libs/thread/build libs/thread/doc libs/thread/example libs/thread/src libs/thread/test/sync/mutual_exclusion/locks/reverse_lock libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons
From: vicente.botet_at_[hidden]
Date: 2012-04-01 17:52:50


Author: viboes
Date: 2012-04-01 17:52:47 EDT (Sun, 01 Apr 2012)
New Revision: 77704
URL: http://svn.boost.org/trac/boost/changeset/77704

Log:
Thread: Added shared mutex upwards conversion + configuration macros
Added:
   trunk/libs/thread/doc/configuration.qbk (contents, props changed)
   trunk/libs/thread/doc/sync_tutorial.qbk (contents, props changed)
   trunk/libs/thread/src/shared_mutex.cpp (contents, props changed)
   trunk/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_shared_lock_for_pass.cpp (contents, props changed)
   trunk/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_shared_lock_try_pass.cpp (contents, props changed)
   trunk/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_shared_lock_until_pass.cpp (contents, props changed)
   trunk/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/move_ctor_shared_lock_for_pass.cpp (contents, props changed)
   trunk/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/move_ctor_shared_lock_try_pass.cpp (contents, props changed)
   trunk/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/move_ctor_shared_lock_until_pass.cpp (contents, props changed)
Text files modified:
   trunk/boost/thread/locks.hpp | 465 +++++++++++++++++++++++++++++++++++----
   trunk/boost/thread/pthread/shared_mutex.hpp | 103 ++++++++
   trunk/libs/thread/build/Jamfile.v2 | 20 -
   trunk/libs/thread/doc/changes.qbk | 6
   trunk/libs/thread/doc/compliance.qbk | 18
   trunk/libs/thread/doc/future_ref.qbk | 2
   trunk/libs/thread/doc/mutex_concepts.qbk | 190 ++++++++++++++-
   trunk/libs/thread/doc/overview.qbk | 9
   trunk/libs/thread/doc/thread.qbk | 3
   trunk/libs/thread/example/shared_mutex.cpp | 1
   trunk/libs/thread/test/sync/mutual_exclusion/locks/reverse_lock/copy_assign_fail.cpp | 3
   trunk/libs/thread/test/sync/mutual_exclusion/locks/reverse_lock/copy_ctor_fail.cpp | 1
   12 files changed, 709 insertions(+), 112 deletions(-)

Modified: trunk/boost/thread/locks.hpp
==============================================================================
--- trunk/boost/thread/locks.hpp (original)
+++ trunk/boost/thread/locks.hpp 2012-04-01 17:52:47 EDT (Sun, 01 Apr 2012)
@@ -640,6 +640,181 @@
 #endif
 #endif
 
+#ifdef BOOST_THREAD_SHARED_MUTEX_PROVIDES_UPWARDS_CONVERSION
+#ifndef BOOST_NO_RVALUE_REFERENCES
+ // Conversion from shared locking
+ unique_lock(shared_lock<mutex_type>&& sl, try_to_lock_t)
+ : m(0),is_locked(false)
+ {
+ if (sl.owns_lock()) {
+ if (sl.mutex()->try_unlock_shared_and_lock())
+ {
+ m = sl.release();
+ is_locked = true;
+ }
+ }
+ else
+ {
+ m = sl.release();
+ }
+ }
+
+#ifdef BOOST_THREAD_USES_CHRONO
+ template <class Clock, class Duration>
+ unique_lock(shared_lock<mutex_type>&& sl,
+ const chrono::time_point<Clock, Duration>& abs_time)
+ : m(0),is_locked(false)
+ {
+ if (sl.owns_lock()) {
+ if (sl.mutex()->try_unlock_shared_and_lock_until(abs_time))
+ {
+ m = sl.release();
+ is_locked = true;
+ }
+ }
+ else
+ {
+ m = sl.release();
+ }
+ }
+
+ template <class Rep, class Period>
+ unique_lock(shared_lock<mutex_type>&& sl,
+ const chrono::duration<Rep, Period>& rel_time)
+ : m(0),is_locked(false)
+ {
+ if (sl.owns_lock()) {
+ if (sl.mutex()->try_unlock_shared_and_lock_for(rel_time))
+ {
+ m = sl.release();
+ is_locked = true;
+ }
+ }
+ else
+ {
+ m = sl.release();
+ }
+ }
+#endif
+#else
+
+#if defined BOOST_THREAD_USES_MOVE
+
+ // Conversion from shared locking
+ unique_lock(boost::rv<shared_lock<mutex_type> >& sl, try_to_lock_t)
+ : m(0),is_locked(false)
+ {
+ if (sl.owns_lock()) {
+ if (sl.mutex()->try_unlock_shared_and_lock())
+ {
+ m = sl.release();
+ is_locked = true;
+ }
+ }
+ else
+ {
+ m = sl.release();
+ }
+ }
+
+#ifdef BOOST_THREAD_USES_CHRONO
+ template <class Clock, class Duration>
+ unique_lock(boost::rv<shared_lock<mutex_type> >& sl,
+ const chrono::time_point<Clock, Duration>& abs_time)
+ : m(0),is_locked(false)
+ {
+ if (sl.owns_lock()) {
+ if (sl.mutex()->try_unlock_shared_and_lock_until(abs_time))
+ {
+ m = sl.release();
+ is_locked = true;
+ }
+ }
+ else
+ {
+ m = sl.release();
+ }
+ }
+
+ template <class Rep, class Period>
+ unique_lock(boost::rv<shared_lock<mutex_type> >& sl,
+ const chrono::duration<Rep, Period>& rel_time)
+ : m(0),is_locked(false)
+ {
+ if (sl.owns_lock()) {
+ if (sl.mutex()->try_unlock_shared_and_lock_for(rel_time))
+ {
+ m = sl.release();
+ is_locked = true;
+ }
+ }
+ else
+ {
+ m = sl.release();
+ }
+ }
+#endif
+#else
+
+ // Conversion from shared locking
+ unique_lock(detail::thread_move_t<shared_lock<mutex_type> > sl, try_to_lock_t)
+ : m(0),is_locked(false)
+ {
+ if (sl.owns_lock()) {
+ if (sl.mutex()->try_unlock_shared_and_lock())
+ {
+ m = sl.release();
+ is_locked = true;
+ }
+ }
+ else
+ {
+ m = sl.release();
+ }
+ }
+
+#ifdef BOOST_THREAD_USES_CHRONO
+ template <class Clock, class Duration>
+ unique_lock(detail::thread_move_t<shared_lock<mutex_type> > sl,
+ const chrono::time_point<Clock, Duration>& abs_time)
+ : m(0),is_locked(false)
+ {
+ if (sl.owns_lock()) {
+ if (sl.mutex()->try_unlock_shared_and_lock_until(abs_time))
+ {
+ m = sl.release();
+ is_locked = true;
+ }
+ }
+ else
+ {
+ m = sl.release();
+ }
+ }
+
+ template <class Rep, class Period>
+ unique_lock(detail::thread_move_t<shared_lock<mutex_type> > sl,
+ const chrono::duration<Rep, Period>& rel_time)
+ : m(0),is_locked(false)
+ {
+ if (sl.owns_lock()) {
+ if (sl.mutex()->try_unlock_shared_and_lock_for(rel_time))
+ {
+ m = sl.release();
+ is_locked = true;
+ }
+ }
+ else
+ {
+ m = sl.release();
+ }
+ }
+#endif
+#endif
+#endif
+#endif
+
+
         void swap(unique_lock& other) BOOST_NOEXCEPT
         {
             std::swap(m,other.m);
@@ -836,7 +1011,7 @@
     public:
         typedef Mutex mutex_type;
 
- shared_lock():
+ shared_lock() BOOST_NOEXCEPT:
             m(0),is_locked(false)
         {}
 
@@ -848,7 +1023,7 @@
         shared_lock(Mutex& m_,adopt_lock_t):
             m(&m_),is_locked(true)
         {}
- shared_lock(Mutex& m_,defer_lock_t):
+ shared_lock(Mutex& m_,defer_lock_t) BOOST_NOEXCEPT:
             m(&m_),is_locked(false)
         {}
         shared_lock(Mutex& m_,try_to_lock_t):
@@ -876,7 +1051,7 @@
 #endif
 
 #ifndef BOOST_NO_RVALUE_REFERENCES
- shared_lock(shared_lock<Mutex> && other):
+ shared_lock(shared_lock<Mutex> && other) BOOST_NOEXCEPT:
             m(other.m),is_locked(other.is_locked)
         {
             other.is_locked=false;
@@ -906,7 +1081,7 @@
         }
 
 
- shared_lock& operator=(shared_lock<Mutex> && other)
+ shared_lock& operator=(shared_lock<Mutex> && other) BOOST_NOEXCEPT
         {
             shared_lock temp(::boost::move(other));
             swap(temp);
@@ -930,7 +1105,7 @@
 #endif
 #else
 #if defined BOOST_THREAD_USES_MOVE
- shared_lock(boost::rv<shared_lock<Mutex> >& other):
+ shared_lock(boost::rv<shared_lock<Mutex> >& other) BOOST_NOEXCEPT:
             m(other.m),is_locked(other.is_locked)
         {
             other.is_locked=false;
@@ -959,24 +1134,24 @@
             other.m=0;
         }
 
- operator ::boost::rv<shared_lock<Mutex> >&()
+ operator ::boost::rv<shared_lock<Mutex> >&() BOOST_NOEXCEPT
         {
           return *static_cast< ::boost::rv<shared_lock<Mutex> >* >(this);
         }
- operator const ::boost::rv<shared_lock<Mutex> >&() const
+ operator const ::boost::rv<shared_lock<Mutex> >&() const BOOST_NOEXCEPT
         {
           return *static_cast<const ::boost::rv<shared_lock<Mutex> >* >(this);
         }
- ::boost::rv<shared_lock<Mutex> >& move()
+ ::boost::rv<shared_lock<Mutex> >& move() BOOST_NOEXCEPT
         {
           return *static_cast< ::boost::rv<shared_lock<Mutex> >* >(this);
         }
- const ::boost::rv<shared_lock<Mutex> >& move() const
+ const ::boost::rv<shared_lock<Mutex> >& move() const BOOST_NOEXCEPT
         {
           return *static_cast<const ::boost::rv<shared_lock<Mutex> >* >(this);
         }
 
- shared_lock& operator=(::boost::rv<shared_lock<Mutex> >& other)
+ shared_lock& operator=(::boost::rv<shared_lock<Mutex> >& other) BOOST_NOEXCEPT
         {
             shared_lock temp(other);
             swap(temp);
@@ -1000,7 +1175,7 @@
 #endif
 #else
 
- shared_lock(detail::thread_move_t<shared_lock<Mutex> > other):
+ shared_lock(detail::thread_move_t<shared_lock<Mutex> > other) BOOST_NOEXCEPT:
             m(other->m),is_locked(other->is_locked)
         {
             other->is_locked=false;
@@ -1029,18 +1204,18 @@
             other->m=0;
         }
 
- operator detail::thread_move_t<shared_lock<Mutex> >()
+ operator detail::thread_move_t<shared_lock<Mutex> >() BOOST_NOEXCEPT
         {
             return move();
         }
 
- detail::thread_move_t<shared_lock<Mutex> > move()
+ detail::thread_move_t<shared_lock<Mutex> > move() BOOST_NOEXCEPT
         {
             return detail::thread_move_t<shared_lock<Mutex> >(*this);
         }
 
 
- shared_lock& operator=(detail::thread_move_t<shared_lock<Mutex> > other)
+ shared_lock& operator=(detail::thread_move_t<shared_lock<Mutex> > other) BOOST_NOEXCEPT
         {
             shared_lock temp(other);
             swap(temp);
@@ -1065,13 +1240,13 @@
 #endif
 #endif
 
- void swap(shared_lock& other)
+ void swap(shared_lock& other) BOOST_NOEXCEPT
         {
             std::swap(m,other.m);
             std::swap(is_locked,other.is_locked);
         }
 
- Mutex* mutex() const
+ Mutex* mutex() const BOOST_NOEXCEPT
         {
             return m;
         }
@@ -1190,21 +1365,21 @@
 
 #if defined(BOOST_NO_EXPLICIT_CONVERSION_OPERATORS)
         typedef void (shared_lock<Mutex>::*bool_type)();
- operator bool_type() const
+ operator bool_type() const BOOST_NOEXCEPT
         {
             return is_locked?&shared_lock::lock:0;
         }
- bool operator!() const
+ bool operator!() const BOOST_NOEXCEPT
         {
             return !owns_lock();
         }
 #else
- explicit operator bool() const
+ explicit operator bool() const BOOST_NOEXCEPT
         {
             return owns_lock();
         }
 #endif
- bool owns_lock() const
+ bool owns_lock() const BOOST_NOEXCEPT
         {
             return is_locked;
         }
@@ -1218,8 +1393,9 @@
   {};
 #endif
 
+
     template<typename Mutex>
- void swap(shared_lock<Mutex>& lhs,shared_lock<Mutex>& rhs)
+ void swap(shared_lock<Mutex>& lhs,shared_lock<Mutex>& rhs) BOOST_NOEXCEPT
     {
         lhs.swap(rhs);
     }
@@ -1241,7 +1417,7 @@
 #endif
     public:
         typedef Mutex mutex_type;
- upgrade_lock():
+ upgrade_lock() BOOST_NOEXCEPT:
             m(0),is_locked(false)
         {}
 
@@ -1253,7 +1429,7 @@
         upgrade_lock(Mutex& m_,adopt_lock_t):
             m(&m_),is_locked(true)
         {}
- upgrade_lock(Mutex& m_,defer_lock_t):
+ upgrade_lock(Mutex& m_,defer_lock_t) BOOST_NOEXCEPT:
             m(&m_),is_locked(false)
         {}
         upgrade_lock(Mutex& m_,try_to_lock_t):
@@ -1276,7 +1452,7 @@
 #endif
 
 #ifndef BOOST_NO_RVALUE_REFERENCES
- upgrade_lock(upgrade_lock<Mutex>&& other):
+ upgrade_lock(upgrade_lock<Mutex>&& other) BOOST_NOEXCEPT:
             m(other.m),is_locked(other.is_locked)
         {
             other.is_locked=false;
@@ -1294,7 +1470,7 @@
             other.m=0;
         }
 
- upgrade_lock& operator=(upgrade_lock<Mutex>&& other)
+ upgrade_lock& operator=(upgrade_lock<Mutex>&& other) BOOST_NOEXCEPT
         {
             upgrade_lock temp(::boost::move(other));
             swap(temp);
@@ -1311,7 +1487,7 @@
 #endif
 #else
 #if defined BOOST_THREAD_USES_MOVE
- upgrade_lock(boost::rv<upgrade_lock<Mutex> >& other):
+ upgrade_lock(boost::rv<upgrade_lock<Mutex> >& other) BOOST_NOEXCEPT:
             m(other.m),is_locked(other.is_locked)
         {
             other.is_locked=false;
@@ -1329,23 +1505,23 @@
             other.m=0;
         }
 
- operator ::boost::rv<upgrade_lock>&()
+ operator ::boost::rv<upgrade_lock>&() BOOST_NOEXCEPT
         {
           return *static_cast< ::boost::rv<upgrade_lock>* >(this);
         }
- operator const ::boost::rv<upgrade_lock>&() const
+ operator const ::boost::rv<upgrade_lock>&() const BOOST_NOEXCEPT
         {
           return *static_cast<const ::boost::rv<upgrade_lock>* >(this);
         }
- ::boost::rv<upgrade_lock>& move()
+ ::boost::rv<upgrade_lock>& move() BOOST_NOEXCEPT
         {
           return *static_cast< ::boost::rv<upgrade_lock>* >(this);
         }
- const ::boost::rv<upgrade_lock>& move() const
+ const ::boost::rv<upgrade_lock>& move() const BOOST_NOEXCEPT
         {
           return *static_cast<const ::boost::rv<upgrade_lock>* >(this);
         }
- upgrade_lock& operator=(boost::rv<upgrade_lock<Mutex> >& other)
+ upgrade_lock& operator=(boost::rv<upgrade_lock<Mutex> >& other) BOOST_NOEXCEPT
         {
             upgrade_lock temp(other);
             swap(temp);
@@ -1361,7 +1537,7 @@
         }
 #endif
 #else
- upgrade_lock(detail::thread_move_t<upgrade_lock<Mutex> > other):
+ upgrade_lock(detail::thread_move_t<upgrade_lock<Mutex> > other) BOOST_NOEXCEPT:
             m(other->m),is_locked(other->is_locked)
         {
             other->is_locked=false;
@@ -1379,18 +1555,18 @@
             other->m=0;
         }
 
- operator detail::thread_move_t<upgrade_lock<Mutex> >()
+ operator detail::thread_move_t<upgrade_lock<Mutex> >() BOOST_NOEXCEPT
         {
             return move();
         }
 
- detail::thread_move_t<upgrade_lock<Mutex> > move()
+ detail::thread_move_t<upgrade_lock<Mutex> > move() BOOST_NOEXCEPT
         {
             return detail::thread_move_t<upgrade_lock<Mutex> >(*this);
         }
 
 
- upgrade_lock& operator=(detail::thread_move_t<upgrade_lock<Mutex> > other)
+ upgrade_lock& operator=(detail::thread_move_t<upgrade_lock<Mutex> > other) BOOST_NOEXCEPT
         {
             upgrade_lock temp(other);
             swap(temp);
@@ -1408,12 +1584,185 @@
 #endif
 #endif
 
- void swap(upgrade_lock& other)
+#ifdef BOOST_THREAD_SHARED_MUTEX_PROVIDES_UPWARDS_CONVERSION
+#ifndef BOOST_NO_RVALUE_REFERENCES
+ // Conversion from shared locking
+
+ upgrade_lock(shared_lock<mutex_type>&& sl, try_to_lock_t)
+ : m(0),is_locked(false)
+ {
+ if (sl.owns_lock()) {
+ if (sl.mutex()->try_unlock_shared_and_lock_upgrade())
+ {
+ m = sl.release();
+ is_locked = true;
+ }
+ }
+ else
+ {
+ m = sl.release();
+ }
+ }
+#ifdef BOOST_THREAD_USES_CHRONO
+ template <class Clock, class Duration>
+ upgrade_lock(shared_lock<mutex_type>&& sl,
+ const chrono::time_point<Clock, Duration>& abs_time)
+ : m(0),is_locked(false)
+ {
+ if (sl.owns_lock()) {
+ if (sl.mutex()->try_unlock_shared_and_lock_upgrade_until(abs_time))
+ {
+ m = sl.release();
+ is_locked = true;
+ }
+ }
+ else
+ {
+ m = sl.release();
+ }
+ }
+
+ template <class Rep, class Period>
+ upgrade_lock(shared_lock<mutex_type>&& sl,
+ const chrono::duration<Rep, Period>& rel_time)
+ : m(0),is_locked(false)
+ {
+ if (sl.owns_lock()) {
+ if (sl.mutex()->try_unlock_shared_and_lock_upgrade_for(rel_time))
+ {
+ m = sl.release();
+ is_locked = true;
+ }
+ }
+ else
+ {
+ m = sl.release();
+ }
+ }
+#endif
+#else
+
+
+#if defined BOOST_THREAD_USES_MOVE
+ // Conversion from shared locking
+
+ upgrade_lock(boost::rv<shared_lock<mutex_type> > &sl, try_to_lock_t)
+ : m(0),is_locked(false)
+ {
+ if (sl.owns_lock()) {
+ if (sl.mutex()->try_unlock_shared_and_lock_upgrade())
+ {
+ m = sl.release();
+ is_locked = true;
+ }
+ }
+ else
+ {
+ m = sl.release();
+ }
+ }
+#ifdef BOOST_THREAD_USES_CHRONO
+ template <class Clock, class Duration>
+ upgrade_lock(boost::rv<shared_lock<mutex_type> > &sl,
+ const chrono::time_point<Clock, Duration>& abs_time)
+ : m(0),is_locked(false)
+ {
+ if (sl.owns_lock()) {
+ if (sl.mutex()->try_unlock_shared_and_lock_upgrade_until(abs_time))
+ {
+ m = sl.release();
+ is_locked = true;
+ }
+ }
+ else
+ {
+ m = sl.release();
+ }
+ }
+
+ template <class Rep, class Period>
+ upgrade_lock(boost::rv<shared_lock<mutex_type> > &sl,
+ const chrono::duration<Rep, Period>& rel_time)
+ : m(0),is_locked(false)
+ {
+ if (sl.owns_lock()) {
+ if (sl.mutex()->try_unlock_shared_and_lock_upgrade_for(rel_time))
+ {
+ m = sl.release();
+ is_locked = true;
+ }
+ }
+ else
+ {
+ m = sl.release();
+ }
+ }
+#endif
+#else
+ // Conversion from shared locking
+
+ upgrade_lock(detail::thread_move_t<shared_lock<mutex_type> > sl, try_to_lock_t)
+ : m(0),is_locked(false)
+ {
+ if (sl.owns_lock()) {
+ if (sl.mutex()->try_unlock_shared_and_lock_upgrade())
+ {
+ m = sl.release();
+ is_locked = true;
+ }
+ }
+ else
+ {
+ m = sl.release();
+ }
+ }
+#ifdef BOOST_THREAD_USES_CHRONO
+ template <class Clock, class Duration>
+ upgrade_lock(detail::thread_move_t<shared_lock<mutex_type> > sl,
+ const chrono::time_point<Clock, Duration>& abs_time)
+ : m(0),is_locked(false)
+ {
+ if (sl.owns_lock()) {
+ if (sl.mutex()->try_unlock_shared_and_lock_upgrade_until(abs_time))
+ {
+ m = sl.release();
+ is_locked = true;
+ }
+ }
+ else
+ {
+ m = sl.release();
+ }
+ }
+
+ template <class Rep, class Period>
+ upgrade_lock(detail::thread_move_t<shared_lock<mutex_type> >& sl,
+ const chrono::duration<Rep, Period>& rel_time)
+ : m(0),is_locked(false)
+ {
+ if (sl.owns_lock()) {
+ if (sl.mutex()->try_unlock_shared_and_lock_upgrade_for(rel_time))
+ {
+ m = sl.release();
+ is_locked = true;
+ }
+ }
+ else
+ {
+ m = sl.release();
+ }
+ }
+#endif
+#endif
+#endif
+#endif
+
+ void swap(upgrade_lock& other) BOOST_NOEXCEPT
         {
             std::swap(m,other.m);
             std::swap(is_locked,other.is_locked);
         }
- Mutex* mutex() const
+ Mutex* mutex() const BOOST_NOEXCEPT
         {
             return m;
         }
@@ -1503,21 +1852,21 @@
 #endif
 #if defined(BOOST_NO_EXPLICIT_CONVERSION_OPERATORS)
         typedef void (upgrade_lock::*bool_type)();
- operator bool_type() const
+ operator bool_type() const BOOST_NOEXCEPT
         {
             return is_locked?&upgrade_lock::lock:0;
         }
- bool operator!() const
+ bool operator!() const BOOST_NOEXCEPT
         {
             return !owns_lock();
         }
 #else
- explicit operator bool() const
+ explicit operator bool() const BOOST_NOEXCEPT
         {
             return owns_lock();
         }
 #endif
- bool owns_lock() const
+ bool owns_lock() const BOOST_NOEXCEPT
         {
             return is_locked;
         }
@@ -1605,13 +1954,13 @@
         }
 
 #ifndef BOOST_NO_RVALUE_REFERENCES
- upgrade_to_unique_lock(upgrade_to_unique_lock<Mutex>&& other):
+ upgrade_to_unique_lock(upgrade_to_unique_lock<Mutex>&& other) BOOST_NOEXCEPT:
             source(other.source),exclusive(::boost::move(other.exclusive))
         {
             other.source=0;
         }
 
- upgrade_to_unique_lock& operator=(upgrade_to_unique_lock<Mutex>&& other)
+ upgrade_to_unique_lock& operator=(upgrade_to_unique_lock<Mutex>&& other) BOOST_NOEXCEPT
         {
             upgrade_to_unique_lock temp(other);
             swap(temp);
@@ -1619,59 +1968,59 @@
         }
 #else
 #if defined BOOST_THREAD_USES_MOVE
- upgrade_to_unique_lock(boost::rv<upgrade_to_unique_lock<Mutex> >& other):
+ upgrade_to_unique_lock(boost::rv<upgrade_to_unique_lock<Mutex> >& other) BOOST_NOEXCEPT:
             source(other.source),exclusive(::boost::move(other.exclusive))
         {
             other.source=0;
         }
 
- upgrade_to_unique_lock& operator=(boost::rv<upgrade_to_unique_lock<Mutex> >& other)
+ upgrade_to_unique_lock& operator=(boost::rv<upgrade_to_unique_lock<Mutex> >& other) BOOST_NOEXCEPT
         {
             upgrade_to_unique_lock temp(other);
             swap(temp);
             return *this;
         }
- operator ::boost::rv<upgrade_to_unique_lock>&()
+ operator ::boost::rv<upgrade_to_unique_lock>&() BOOST_NOEXCEPT
         {
           return *static_cast< ::boost::rv<upgrade_to_unique_lock>* >(this);
         }
- operator const ::boost::rv<upgrade_to_unique_lock>&() const
+ operator const ::boost::rv<upgrade_to_unique_lock>&() const BOOST_NOEXCEPT
         {
           return *static_cast<const ::boost::rv<upgrade_to_unique_lock>* >(this);
         }
- ::boost::rv<upgrade_to_unique_lock>& move()
+ ::boost::rv<upgrade_to_unique_lock>& move() BOOST_NOEXCEPT
         {
           return *static_cast< ::boost::rv<upgrade_to_unique_lock>* >(this);
         }
- const ::boost::rv<upgrade_to_unique_lock>& move() const
+ const ::boost::rv<upgrade_to_unique_lock>& move() const BOOST_NOEXCEPT
         {
           return *static_cast<const ::boost::rv<upgrade_to_unique_lock>* >(this);
         }
 #else
- upgrade_to_unique_lock(detail::thread_move_t<upgrade_to_unique_lock<Mutex> > other):
+ upgrade_to_unique_lock(detail::thread_move_t<upgrade_to_unique_lock<Mutex> > other) BOOST_NOEXCEPT:
             source(other->source),exclusive(::boost::move(other->exclusive))
         {
             other->source=0;
         }
 
- upgrade_to_unique_lock& operator=(detail::thread_move_t<upgrade_to_unique_lock<Mutex> > other)
+ upgrade_to_unique_lock& operator=(detail::thread_move_t<upgrade_to_unique_lock<Mutex> > other) BOOST_NOEXCEPT
         {
             upgrade_to_unique_lock temp(other);
             swap(temp);
             return *this;
         }
- operator detail::thread_move_t<upgrade_to_unique_lock<Mutex> >()
+ operator detail::thread_move_t<upgrade_to_unique_lock<Mutex> >() BOOST_NOEXCEPT
         {
             return move();
         }
 
- detail::thread_move_t<upgrade_to_unique_lock<Mutex> > move()
+ detail::thread_move_t<upgrade_to_unique_lock<Mutex> > move() BOOST_NOEXCEPT
         {
             return detail::thread_move_t<upgrade_to_unique_lock<Mutex> >(*this);
         }
 #endif
 #endif
- void swap(upgrade_to_unique_lock& other)
+ void swap(upgrade_to_unique_lock& other) BOOST_NOEXCEPT
         {
             std::swap(source,other.source);
             exclusive.swap(other.exclusive);
@@ -1679,22 +2028,22 @@
 
 #if defined(BOOST_NO_EXPLICIT_CONVERSION_OPERATORS)
         typedef void (upgrade_to_unique_lock::*bool_type)(upgrade_to_unique_lock&);
- operator bool_type() const
+ operator bool_type() const BOOST_NOEXCEPT
         {
             return exclusive.owns_lock()?&upgrade_to_unique_lock::swap:0;
         }
- bool operator!() const
+ bool operator!() const BOOST_NOEXCEPT
         {
             return !owns_lock();
         }
 #else
- explicit operator bool() const
+ explicit operator bool() const BOOST_NOEXCEPT
         {
             return owns_lock();
         }
 #endif
 
- bool owns_lock() const
+ bool owns_lock() const BOOST_NOEXCEPT
         {
             return exclusive.owns_lock();
         }

Modified: trunk/boost/thread/pthread/shared_mutex.hpp
==============================================================================
--- trunk/boost/thread/pthread/shared_mutex.hpp (original)
+++ trunk/boost/thread/pthread/shared_mutex.hpp 2012-04-01 17:52:47 EDT (Sun, 01 Apr 2012)
@@ -437,6 +437,57 @@
             release_waiters();
         }
 
+#ifdef BOOST_THREAD_SHARED_MUTEX_PROVIDES_UPWARDS_CONVERSION
+ bool try_unlock_shared_and_lock()
+ {
+ boost::mutex::scoped_lock lk(state_change);
+ if( !state.exclusive
+ && !state.exclusive_waiting_blocked
+ && !state.upgrade
+ && state.shared_count==1)
+ {
+ state.shared_count=0;
+ state.exclusive=true;
+ return true;
+ }
+ return false;
+ }
+#ifdef BOOST_THREAD_USES_CHRONO
+ template <class Rep, class Period>
+ bool
+ try_unlock_shared_and_lock_for(
+ const chrono::duration<Rep, Period>& rel_time)
+ {
+ return try_unlock_shared_and_lock_until(
+ chrono::steady_clock::now() + rel_time);
+ }
+ template <class Clock, class Duration>
+ bool
+ try_unlock_shared_and_lock_until(
+ const chrono::time_point<Clock, Duration>& abs_time)
+ {
+ boost::this_thread::disable_interruption do_not_disturb;
+ boost::mutex::scoped_lock lk(state_change);
+ if (state.shared_count != 1)
+ {
+ while (true)
+ {
+ cv_status status = shared_cond.wait_until(lk,abs_time);
+ if (state.shared_count == 1)
+ break;
+ if(status == cv_status::timeout)
+ return false;
+ }
+ }
+ state.upgrade=false;
+ state.exclusive=true;
+ state.exclusive_waiting_blocked=false;
+ state.shared_count=0;
+ return true;
+ }
+#endif
+#endif
+
         // Shared <-> Upgrade
         void unlock_upgrade_and_lock_shared()
         {
@@ -446,6 +497,58 @@
             release_waiters();
         }
 
+#ifdef BOOST_THREAD_SHARED_MUTEX_PROVIDES_UPWARDS_CONVERSION
+ bool try_unlock_shared_and_lock_upgrade()
+ {
+ boost::mutex::scoped_lock lk(state_change);
+ if( !state.exclusive
+ && !state.exclusive_waiting_blocked
+ && !state.upgrade
+ )
+ {
+ state.upgrade=true;
+ return true;
+ }
+ return false;
+ }
+#ifdef BOOST_THREAD_USES_CHRONO
+ template <class Rep, class Period>
+ bool
+ try_unlock_shared_and_lock_upgrade_for(
+ const chrono::duration<Rep, Period>& rel_time)
+ {
+ return try_unlock_shared_and_lock_upgrade_until(
+ chrono::steady_clock::now() + rel_time);
+ }
+ template <class Clock, class Duration>
+ bool
+ try_unlock_shared_and_lock_upgrade_until(
+ const chrono::time_point<Clock, Duration>& abs_time)
+ {
+ boost::this_thread::disable_interruption do_not_disturb;
+ boost::mutex::scoped_lock lk(state_change);
+ if( state.exclusive
+ || state.exclusive_waiting_blocked
+ || state.upgrade
+ )
+ {
+ while (true)
+ {
+ cv_status status = exclusive_cond.wait_until(lk,abs_time);
+ if( ! state.exclusive
+ && ! state.exclusive_waiting_blocked
+ && ! state.upgrade
+ )
+ break;
+ if(status == cv_status::timeout)
+ return false;
+ }
+ }
+ state.upgrade=true;
+ return true;
+ }
+#endif
+#endif
     };
 
     typedef shared_mutex upgrade_mutex;

Modified: trunk/libs/thread/build/Jamfile.v2
==============================================================================
--- trunk/libs/thread/build/Jamfile.v2 (original)
+++ trunk/libs/thread/build/Jamfile.v2 2012-04-01 17:52:47 EDT (Sun, 01 Apr 2012)
@@ -161,14 +161,7 @@
         }
     }
 
- if <toolset>vacpp in $(properties)
- {
- result += <define>BOOST_THREAD_DONT_USE_CHRONO ;
- }
- else
- {
- result += <library>/boost/chrono//boost_chrono ;
- }
+ result += <library>/boost/chrono//boost_chrono ;
 
     return $(result) ;
 }
@@ -193,14 +186,7 @@
             }
         }
     }
- if <toolset>vacpp in $(properties)
- {
- result += <define>BOOST_THREAD_DONT_USE_CHRONO ;
- }
- else
- {
- result += <library>/boost/chrono//boost_chrono ;
- }
+ result += <library>/boost/chrono//boost_chrono ;
 
     return $(result) ;
 }
@@ -225,7 +211,7 @@
 explicit thread_sources ;
 
 lib boost_thread
- : thread_sources future.cpp
+ : thread_sources future.cpp shared_mutex.cpp
     : <conditional>@requirements
     :
     : <link>shared:<define>BOOST_THREAD_USE_DLL=1

Modified: trunk/libs/thread/doc/changes.qbk
==============================================================================
--- trunk/libs/thread/doc/changes.qbk (original)
+++ trunk/libs/thread/doc/changes.qbk 2012-04-01 17:52:47 EDT (Sun, 01 Apr 2012)
@@ -30,7 +30,6 @@
 * [@http://svn.boost.org/trac/boost/ticket/6672 #6672] upgrade_lock:: missing constructors from time related types.
 * [@http://svn.boost.org/trac/boost/ticket/6675 #6675] upgrade_lock:: missing non-member swap.
          
-
 Fixed Bugs:
 
 * [@http://svn.boost.org/trac/boost/ticket/2575 #2575] Bug- Boost 1.36.0 on Itanium platform.
@@ -185,11 +184,6 @@
   * [@http://svn.boost.org/trac/boost/ticket/6270 #6270] Add thread constructor from movable callable and movable arguments following C++11.
          
 
-# Add the shared locking upward conversions.
-
- * [@http://svn.boost.org/trac/boost/ticket/6217 #6217] Enhance Boost.Thread shared mutex interface following Howard Hinnant proposal.
-
-# Try to fix the thread specific storage issues.
 
 [endsect]
 

Modified: trunk/libs/thread/doc/compliance.qbk
==============================================================================
--- trunk/libs/thread/doc/compliance.qbk (original)
+++ trunk/libs/thread/doc/compliance.qbk 2012-04-01 17:52:47 EDT (Sun, 01 Apr 2012)
@@ -91,17 +91,17 @@
 
 [table Compliance with Howard's Shared Locking proposal
     [[Section] [Description] [Status] [Comments]]
- [[X] [Shared Locking] [Partial] [Missing some upwards conversions]]
- [[X.1] [Shared Lockables Concepts] [Partial] [ - ]]
- [[X.1.1] [SharedLockable concept] [Yes] [ Missing some upwards ownership conversions ]]
- [[X.1.2] [UpgradeLockable concept] [Yes] [ Missing some upwards ownership conversions ]]
+ [[X] [Shared Locking] [Yes] [Needs BOOST_THREAD_SHARED_MUTEX_PROVIDES_UPWARDS_CONVERSION]]
+ [[X.1] [Shared Lockables Concepts] [Yes] [ - ]]
+ [[X.1.1] [SharedLockable concept] [Yes] [ - ]]
+ [[X.1.2] [UpgradeLockable concept] [Yes] [ - ]]
     [[X.2] [Shared Mutex Types] [Yes] [ - ]]
- [[X.2.1] [shared_mutex class] [Partial] [ Missing some upwards ownership conversions ]]
- [[X.2.2] [upgrade_mutex class] [Partial] [ Missing some upwards ownership conversions ]]
- [[X.3] [Locks] [Partial] [Missing some timed conversions]]
- [[X.3.1] [unique_lock class adaptations] [Partial] [Missing some upwards conversions]]
+ [[X.2.1] [shared_mutex class] [Yes] [ - ]]
+ [[X.2.2] [upgrade_mutex class] [Yes] [ - ]]
+ [[X.3] [Locks] [Yes] [-]]
+ [[X.3.1] [unique_lock class adaptations] [Yes] [-]]
     [[X.3.2] [shared_lock class] [Yes] [ - ]]
- [[X.3.3] [upgrade_lock class] [Partial] [Missing some upwards conversions]]
+ [[X.3.3] [upgrade_lock class] [Yes] [-]]
 ]
 
 [endsect]

Added: trunk/libs/thread/doc/configuration.qbk
==============================================================================
--- (empty file)
+++ trunk/libs/thread/doc/configuration.qbk 2012-04-01 17:52:47 EDT (Sun, 01 Apr 2012)
@@ -0,0 +1,138 @@
+[/
+ (C) Copyright 20012 Vicente J. Botet Escriba.
+ Distributed under the Boost Software License, Version 1.0.
+ (See accompanying file LICENSE_1_0.txt or copy at
+ http://www.boost.org/LICENSE_1_0.txt).
+]
+
+
+[section:configuration Configuration]
+
+[section:system Boost.System]
+
+Boost.Thread uses by default Boost.System to define the exceptions. For backward compatibility and also for compilers that don't work well with Boost.System the user can define `BOOST_THREAD_DONT_USE_SYSTEM `.
+
+`BOOST_THREAD_DONT_USE_MOVE` is defined when Boost.Thread uses Boost.Move.
+
+[endsect]
+
+[section:chrono Boost.Chrono]
+
+Boost.Thread uses by default Boost.Chrono for the time related functions. For backward compatibility and also for compilers that don't work well with Boost.Chrono the user can define `BOOST_THREAD_DONT_USE_CHRONO`. If `BOOST_THREAD_DONT_USE_SYSTEM` is defined then `BOOST_THREAD_DONT_USE_CHRONO` is defined implicitly.
+
+`BOOST_THREAD_USE_CHRONO` is defined when Boost.Thread uses Boost.Move.
+
+[endsect]
+
+[section:move Boost.Move]
+
+Boost.Thread uses by default Boost.Move emulation on compilers that don't support Rvalue references. For backward compatibility and also for compilers that don't work well with Boost.Move the user can define `BOOST_THREAD_DONT_USE_MOVE`.
+
+`BOOST_THREAD_USE_MOVE` is defined when Boost.Thread uses Boost.Move.
+
+[endsect]
+
+[section:shared_gen Shared Locking Generic]
+
+The shared mutex implementation on Windows platform provides currently less functionality than the generic one that is used for PTheads based platforms. In order to have access to these functions, the user needs to define `BOOST_THREAD_SHARED_MUTEX_GENERIC` to use the generic implementation, that while could be less efficient, provides all the functions.
+
+[endsect]
+
+[section:shared_upwards Shared Locking Upwards Conversion]
+
+Boost.Threads includes in version 2 the Shared Locking Upwards Conversion as defined in [@http://home.roadrunner.com/~hinnant/bloomington/shared_mutex.html Shared Locking].
+These conversions need to be used carefully to avoid deadlock or livelock. The user need to define explicitly `BOOST_THREAD_SHARED_MUTEX_PROVIDES_UPWARDS_CONVERSION` to get these upwards conversions.
+
+[endsect]
+
+[section:explicit_cnv Explicit Lock Conversion]
+
+In [@http://home.roadrunner.com/~hinnant/bloomington/shared_mutex.html Shared Locking] the lock conversions are explicit. As this explicit conversion breaks the lock interfaces, it is provided only if the `BOOST_THREAD_PROVIDES_EXPLICIT_LOCK_CONVERSION` is defined.
+
+[endsect]
+
+[section:deprecated Deprecated]
+
+Version 2.0.0 deprecates some Boost.Thread features.
+
+These deprecated features will be provided by default up to boost 1.52. If you don't want to include the deprecated features you could define `BOOST_THREAD_DONT_PROVIDE_DEPRECATED_FEATURES_SINCE_V2_0_0`. Since 1.53 these features will not be included any more by default. Since this version, if you want to include the deprecated features yet you could define `BOOST_THREAD_PROVIDE_DEPRECATED_FEATURES_SINCE_V2_0_0`. These deprecated features will be only available until boost 1.55, that is you have 1 year and a half to move to the new features.
+
+
+[endsect]
+
+[section:future unique_future versus future]
+
+C++11 uses `std::future`. Versions of Boost.Thread previous to version 2.0.0 uses `boost:unique_future`.
+Since version 2.0.0 `boost::future` replaces `boost::__unique_future` when `BOOST_THREAD_USES_FUTURE` is defined. The documentation doesn't contains anymore however `boost::__unique_future`.
+
+[endsect]
+
+[section:lazy promise lazy initialization]
+
+C++11 promise initialize the associated state at construction time. Versions of Boost.Thread previous to version 2.0.0 initialize it lazily at any point in time in which this associated state is needed.
+
+Since version 2.0.0 this difference in behavior can be configured. When `BOOST_THREAD_PROMISE_LAZY` is defined the backward compatible behavior is provided.
+
+[endsect]
+
+[section:alloc promise Allocator constructor]
+
+
+C++11 std::promise provides constructors with allocators.
+
+ template <typename R>
+ class promise
+ {
+ public:
+ template <class Allocator>
+ explicit promise(allocator_arg_t, Allocator a);
+ // ...
+ };
+ template <class R, class Alloc> struct uses_allocator<promise<R>,Alloc>: true_type {};
+
+where
+
+ struct allocator_arg_t { };
+ constexpr allocator_arg_t allocator_arg = allocator_arg_t();
+
+ template <class T, class Alloc> struct uses_allocator;
+
+Since version 2.0.0 Boost.Thread implements this constructor using the following interface
+
+ namespace boost
+ {
+ typedef container::allocator_arg_t allocator_arg_t;
+ constexpr allocator_arg_t allocator_arg = {};
+
+ namespace container
+ {
+ template <class R, class Alloc>
+ struct uses_allocator<promise<R>,Alloc>: true_type {};
+ }
+ template <class T, class Alloc>
+ struct uses_allocator : public container::uses_allocator<T, Alloc> {};
+ }
+
+which introduces a dependency on Boost.Container. This feature is provided only if `BOOST_THREAD_FUTURE_USES_ALLOCATORS` is defined.
+
+[endsect]
+
+
+
+[section:version `BOOST_THREAD_VERSION` Version]
+
+`BOOST_THREAD_VERSION` defines the Boost.Thread version.
+The default version is 1.
+
+The user can request the version 2 by defining `BOOST_THREAD_VERSION` to 2. In this case the following breaking or extending macros are defined
+
+* Breaking change `BOOST_THREAD_PROVIDES_EXPLICIT_LOCK_CONVERSION `
+* Breaking change `BOOST_THREAD_USES_FUTURE`
+* Uniformity `BOOST_THREAD_SHARED_MUTEX_GENERIC`
+* Extension `BOOST_THREAD_SHARED_MUTEX_PROVIDES_UPWARDS_CONVERSION`
+* Extension `BOOST_THREAD_FUTURE_USES_ALLOCATORS`
+
+
+[endsect]
+
+[endsect]
\ No newline at end of file

Modified: trunk/libs/thread/doc/future_ref.qbk
==============================================================================
--- trunk/libs/thread/doc/future_ref.qbk (original)
+++ trunk/libs/thread/doc/future_ref.qbk 2012-04-01 17:52:47 EDT (Sun, 01 Apr 2012)
@@ -758,6 +758,8 @@
 
 [[Throws:] [Nothing.]]
 
+[[Notes:] [Available only if BOOST_THREAD_FUTURE_USES_ALLOCATORS is defined.]]
+
 ]
 
 [endsect]

Modified: trunk/libs/thread/doc/mutex_concepts.qbk
==============================================================================
--- trunk/libs/thread/doc/mutex_concepts.qbk (original)
+++ trunk/libs/thread/doc/mutex_concepts.qbk 2012-04-01 17:52:47 EDT (Sun, 01 Apr 2012)
@@ -358,13 +358,7 @@
 * `m.__try_lock_upgrade()`
 * `m.__try_lock_upgrade_for(rel_time)`
 * `m.__try_lock_upgrade_until(abs_time)`
-* `m.__try_unlock_shared_and_lock()`
-* `m.__try_unlock_shared_and_lock_for(rel_time)`
-* `m.__try_unlock_shared_and_lock_until(abs_time)`
 * `m.__unlock_and_lock_shared()`
-* `m.__try_unlock_shared_and_lock_upgrade();`
-* `m.__try_unlock_shared_and_lock_upgrade_for(rel_time);`
-* `m.__try_unlock_shared_and_lock_upgrade_until(abs_time);`
 * `m.__unlock_and_lock_upgrade();`
 * `m.__unlock_upgrade_and_lock();`]
 * `m.__try_unlock_upgrade_and_lock()`
@@ -372,6 +366,17 @@
 * `m.__try_unlock_upgrade_and_lock_until(abs_time)`
 * `m.__unlock_upgrade_and_lock_shared();`
 
+
+If BOOST_THREAD_SHARED_MUTEX_PROVIDES_UPWARDS_CONVERSION is defined the following expressions are also required:
+
+* `m.__try_unlock_shared_and_lock();`
+* `m.__try_unlock_shared_and_lock_for(rel_time);`
+* `m.__try_unlock_shared_and_lock_until(abs_time);`
+* `m.__try_unlock_shared_and_lock_upgrade();`
+* `m.__try_unlock_shared_and_lock_upgrade_for(rel_time);`
+* `m.__try_unlock_shared_and_lock_upgrade_until(abs_time);`
+
+
 Lock ownership acquired through a call to __lock_upgrade_ref__ must be released through a call to __unlock_upgrade_ref__. If the
 ownership type is changed through a call to one of the `unlock_xxx_and_lock_yyy()` functions, ownership must be released through a
 call to the unlock function corresponding to the new level of ownership.
@@ -450,6 +455,8 @@
 
 [[Throws:] [Nothing]]
 
+[[Notes:] [Available only if BOOST_THREAD_SHARED_MUTEX_GENERIC is defined on Windows platform]]
+
 ]
 [endsect]
 
@@ -471,6 +478,8 @@
 
 [[Throws:] [Nothing]]
 
+[[Notes:] [Available only if BOOST_THREAD_SHARED_MUTEX_GENERIC is defined on Windows platform]]
+
 ]
 [endsect]
 
@@ -489,10 +498,13 @@
 
 [[Postcondition:] [If the call returns `true`, the current thread has exclusive ownership of `m`.]]
 
-[[Synchronization:] [If `__ try_unlock_shared_and_lock()` returns true, prior `__unlock()` and subsequent lock operations on the same object synchronize with this operation. ]]
+[[Synchronization:] [If `__try_unlock_shared_and_lock()` returns true, prior `__unlock()` and subsequent lock operations on the same object synchronize with this operation. ]]
+
 
 [[Throws:] [Nothing]]
 
+[[Notes:] [Available only if BOOST_THREAD_SHARED_MUTEX_PROVIDES_UPWARDS_CONVERSION and BOOST_THREAD_SHARED_MUTEX_GENERIC is defined on Windows platform]]
+
 ]
 [endsect]
 
@@ -517,6 +529,8 @@
 
 [[Throws:] [Nothing]]
 
+[[Notes:] [Available only if BOOST_THREAD_SHARED_MUTEX_PROVIDES_UPWARDS_CONVERSION and BOOST_THREAD_SHARED_MUTEX_GENERIC is defined on Windows platform]]
+
 ]
 [endsect]
 
@@ -541,6 +555,8 @@
 
 [[Throws:] [Nothing]]
 
+[[Notes:] [Available only if BOOST_THREAD_SHARED_MUTEX_PROVIDES_UPWARDS_CONVERSION and BOOST_THREAD_SHARED_MUTEX_GENERIC is defined on Windows platform]]
+
 ]
 [endsect]
 
@@ -579,6 +595,8 @@
 
 [[Throws:] [Nothing]]
 
+[[Notes:] [Available only if BOOST_THREAD_SHARED_MUTEX_PROVIDES_UPWARDS_CONVERSION and BOOST_THREAD_SHARED_MUTEX_GENERIC is defined on Windows platform]]
+
 ]
 [endsect]
 
@@ -604,6 +622,9 @@
 
 [[Throws:] [Nothing]]
 
+[[Notes:] [Available only if BOOST_THREAD_SHARED_MUTEX_PROVIDES_UPWARDS_CONVERSION and BOOST_THREAD_SHARED_MUTEX_GENERIC is defined on Windows platform]]
+
+
 ]
 [endsect]
 
@@ -627,6 +648,8 @@
 
 [[Throws:] [Nothing]]
 
+[[Notes:] [Available only if BOOST_THREAD_SHARED_MUTEX_PROVIDES_UPWARDS_CONVERSION and BOOST_THREAD_SHARED_MUTEX_GENERIC is defined on Windows platform]]
+
 ]
 [endsect]
 
@@ -685,6 +708,9 @@
 
 [[Throws:] [Nothing]]
 
+[[Notes:] [Available only if BOOST_THREAD_SHARED_MUTEX_GENERIC is defined on Windows platform]]
+
+
 ]
 [endsect]
 
@@ -709,6 +735,8 @@
 
 [[Throws:] [Nothing]]
 
+[[Notes:] [Available only if BOOST_THREAD_SHARED_MUTEX_GENERIC is defined on Windows platform]]
+
 ]
 [endsect]
 
@@ -732,6 +760,8 @@
 
 [[Throws:] [Nothing]]
 
+[[Notes:] [Available only if BOOST_THREAD_SHARED_MUTEX_GENERIC is defined on Windows platform]]
+
 ]
 [endsect]
 
@@ -885,8 +915,18 @@
         unique_lock(Lockable& m_,adopt_lock_t);
         unique_lock(Lockable& m_,defer_lock_t) noexcept;
         unique_lock(Lockable& m_,try_to_lock_t);
- unique_lock(Lockable& m_,system_time const& target_time); // DEPRECATED V2
 
+ #ifdef BOOST_THREAD_SHARED_MUTEX_PROVIDES_UPWARDS_CONVERSION
+ unique_lock(shared_lock<mutex_type>&& sl, try_to_lock_t)
+ template <class Clock, class Duration>
+ unique_lock(shared_lock<mutex_type>&& sl,
+ const chrono::time_point<Clock, Duration>& abs_time);
+ template <class Rep, class Period>
+ unique_lock(shared_lock<mutex_type>&& sl,
+ const chrono::duration<Rep, Period>& rel_time)
+ #endif
+
+ unique_lock(Lockable& m_,system_time const& target_time); // DEPRECATED V2
         template <class Clock, class Duration>
         unique_lock(Mutex& mtx, const chrono::time_point<Clock, Duration>& t);
         template <class Rep, class Period>
@@ -1016,6 +1056,82 @@
 
 [endsect]
 
+[section:constructor_sh_try `unique_lock(shared_lock<mutex_type>&& sl, try_to_lock_t)`]
+
+[variablelist
+
+[[Requires:] [The supplied `Mutex` type must implement `__try_unlock_shared_and_lock()`.]]
+
+[[Effects:] [Constructs an object of type __unique_lock. Let `pm` be and `owns` the ownership state. Initializes `pm` with nullptr and `owns` with false.
+If `sl.__owns_lock()` returns `false`, sets `pm` to the return value of `sl.release()`.
+Else `sl.__owns_lock()` returns `true`, and in this case if `sl.mutex()->try_unlock_shared_and_lock()` returns `true`, sets `pm` to the value returned by `sl.release()` and sets `owns` to `true`.]]
+
+[[Note:] [If `sl.owns_lock()` returns `true` and `sl.mutex()->try_unlock_shared_and_lock()` returns `false`, `sl` is not modified.]]
+
+[[Throws:] [Nothing.]]
+
+[[Notes:] [Available only if BOOST_THREAD_SHARED_MUTEX_PROVIDES_UPWARDS_CONVERSION and BOOST_THREAD_SHARED_MUTEX_GENERIC is defined on Windows platform]]
+
+]
+
+[endsect]
+
+
+[section:constructor_sh_until `unique_lock(shared_lock<mutex_type>&&, const chrono::time_point<Clock, Duration>&)`]
+
+ template <class Clock, class Duration>
+ unique_lock(shared_lock<mutex_type>&& sl,
+ const chrono::time_point<Clock, Duration>& abs_time);
+
+[variablelist
+
+[[Requires:] [The supplied `Mutex` type shall implement `__try_unlock_shared_and_lock_until(abs_time)`.]]
+
+[[Effects:] [Constructs an object of type `__unique_lock`, initializing `pm` with `nullptr` and `owns` with `false`.
+If `sl.__owns_lock()` returns `false`, sets `pm` to the return value of `sl.__release()`.
+Else `sl.owns_lock()` returns `true`, and in this case if `sl.mutex()->__try_unlock_shared_and_lock_until(abs_time)` returns `true`, sets `pm` to the value returned by `sl.release()` and sets `owns` to `true`.]]
+
+[[Note:] [If `sl.owns_lock()` returns `true` and `sl.mutex()-> __try_unlock_shared_and_lock_until(abs_time)` returns `false`, `sl` is not modified.]]
+
+[[Throws:] [Nothing.]]
+
+[[Notes:] [Available only if BOOST_THREAD_SHARED_MUTEX_PROVIDES_UPWARDS_CONVERSION and BOOST_THREAD_SHARED_MUTEX_GENERIC is defined on Windows platform]]
+
+]
+
+[endsect]
+
+[section:constructor_sh_for `unique_lock(shared_lock<mutex_type>&&, const chrono::duration<Rep, Period>&)`]
+
+ template <class Rep, class Period>
+ unique_lock(shared_lock<mutex_type>&& sl,
+ const chrono::duration<Rep, Period>& rel_time)
+
+[variablelist
+
+[[Requires:] [The supplied `Mutex` type shall implement `__try_unlock_shared_and_lock_for(rel_time)`.]]
+
+[[Effects:] [Constructs an object of type `__unique_lock`, initializing `pm` with `nullptr` and `owns` with `false`.
+If `sl.__owns_lock()` returns `false`, sets `pm` to the return value of `sl.__release()`.
+Else `sl.owns_lock()` returns `true`, and in this case if `sl.mutex()-> __try_unlock_shared_and_lock_for(rel_time)` returns `true`, sets `pm` to the value returned by `sl.release()` and sets `owns` to `true`.]]
+
+[[Note:] [If `sl.owns_lock()` returns `true` and `sl.mutex()-> __try_unlock_shared_and_lock_for(rel_time)` returns `false`, `sl` is not modified.]]
+
+
+[[Postcondition:] [.]]
+
+[[Throws:] [Nothing.]]
+
+[[Notes:] [Available only if BOOST_THREAD_SHARED_MUTEX_PROVIDES_UPWARDS_CONVERSION and BOOST_THREAD_SHARED_MUTEX_GENERIC is defined on Windows platform]]
+
+]
+
+[endsect]
+
+
+
+
+
 [section:constructor_abs_time `unique_lock(Lockable & m,boost::system_time const& abs_time)` // DEPRECATED V2]
 
 [variablelist
@@ -1154,6 +1270,8 @@
     {
     public:
         typedef Lockable mutex_type;
+
+ // Shared locking
         shared_lock();
         explicit shared_lock(Lockable& m_);
         shared_lock(Lockable& m_,adopt_lock_t);
@@ -1170,11 +1288,7 @@
         shared_lock& operator=(shared_lock const&) = delete;
 
         shared_lock(shared_lock<Lockable> && other);
- explicit shared_lock(unique_lock<Lockable> && other);
- explicit shared_lock(upgrade_lock<Lockable> && other);
-
         shared_lock& operator=(shared_lock<Lockable> && other);
- void swap(shared_lock& other);
 
         void lock();
         bool try_lock();
@@ -1185,8 +1299,20 @@
         bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time);
         void unlock();
 
+ // Conversion from upgrade locking
+ explicit shared_lock(upgrade_lock<Lockable> && other);
+
+ // Conversion from exclusive locking
+ explicit shared_lock(unique_lock<Lockable> && other);
+
+ // Setters
+ void swap(shared_lock& other);
+ mutex_type* release() noexcept;
+
+ // Getters
         explicit operator bool() const;
         bool owns_lock() const;
+ mutex_type mutex() const;
     };
 
 Like __unique_lock__, __shared_lock__ models the __lockable_concept__, but rather than acquiring unique ownership of the supplied
@@ -1382,20 +1508,28 @@
     {
     public:
         typedef Lockable mutex_type;
- explicit upgrade_lock(Lockable& m_);
 
- upgrade_lock(upgrade_lock<Lockable> && other);
- explicit upgrade_lock(unique_lock<Lockable> && other);
+ // Upgrade locking
 
+ upgrade_lock();
+ explicit upgrade_lock(mutex_type& m_);
+ upgrade_lock(mutex_type& m, defer_lock_t) noexcept;
+ upgrade_lock(mutex_type& m, try_to_lock_t);
+ upgrade_lock(mutex_type& m, adopt_lock_t);
+ template <class Clock, class Duration>
+ upgrade_lock(mutex_type& m,
+ const chrono::time_point<Clock, Duration>& abs_time);
+ template <class Rep, class Period>
+ upgrade_lock(mutex_type& m,
+ const chrono::duration<Rep, Period>& rel_time);
         ~upgrade_lock();
 
         upgrade_lock(const upgrade_lock& other) = delete;
         upgrade_lock& operator=(const upgrade_lock<Lockable> & other) = delete;
 
+ upgrade_lock(upgrade_lock<Lockable> && other);
         upgrade_lock& operator=(upgrade_lock<Lockable> && other);
 
- void swap(upgrade_lock& other);
-
         void lock();
         bool try_lock();
         template <class Rep, class Period>
@@ -1404,8 +1538,28 @@
         bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time);
         void unlock();
 
+ #ifdef BOOST_THREAD_SHARED_MUTEX_PROVIDES_UPWARDS_CONVERSION
+ // Conversion from shared locking
+ upgrade_lock(shared_lock<mutex_type>&& sl, try_to_lock_t);
+ template <class Clock, class Duration>
+ upgrade_lock(shared_lock<mutex_type>&& sl,
+ const chrono::time_point<Clock, Duration>& abs_time);
+ template <class Rep, class Period>
+ upgrade_lock(shared_lock<mutex_type>&& sl,
+ const chrono::duration<Rep, Period>& rel_time);
+ #endif
+
+ // Conversion from exclusive locking
+ explicit upgrade_lock(unique_lock<Lockable> && other);
+
+ // Setters
+ void swap(upgrade_lock& other);
+ mutex_type* release() noexcept;
+
+ // Getters
         explicit operator bool() const;
         bool owns_lock() const;
+ mutex_type mutex() const;
     };
 
 Like __unique_lock__, __upgrade_lock__ models the __lockable_concept__, but rather than acquiring unique ownership of the supplied
@@ -1421,7 +1575,7 @@
 is destroyed, then the destructor will invoke [unlock_upgrade_ref_link `mutex()->unlock_upgrade()`].
 
 The member functions of __upgrade_lock__ are not thread-safe. In particular, __upgrade_lock__ is intended to model the upgrade
-ownership of a __lockable_concept_type__ object by a particular thread, and the member functions that release ownership of the lock
+ownership of a __upgrade_lockable_concept_type__ object by a particular thread, and the member functions that release ownership of the lock
 state (including the destructor) must be called by the same thread that acquired ownership of the lock state.
 
 [endsect]

Modified: trunk/libs/thread/doc/overview.qbk
==============================================================================
--- trunk/libs/thread/doc/overview.qbk (original)
+++ trunk/libs/thread/doc/overview.qbk 2012-04-01 17:52:47 EDT (Sun, 01 Apr 2012)
@@ -20,8 +20,8 @@
 [@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2139.html N2139], and
 [@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2094.html N2094]
 
-Vicente J. Botet Escriba started in version 2 the adaptation to comply with the accepted Thread C++11 library (Make use of Boost.Chrono and Boost.Move) and the [@http://home.roadrunner.com/~hinnant/bloomington/shared_mutex.html Shared Locking] Howard Hinnant proposal except for the upward conversions. Some minor features have been added also
-as thread attributes, reverse_lock, shared_lock_guard.
+Vicente J. Botet Escriba started in version 2 the adaptation to comply with the accepted Thread C++11 library (Make use of Boost.Chrono and Boost.Move) and the [@http://home.roadrunner.com/~hinnant/bloomington/shared_mutex.html Shared Locking] Howard Hinnant proposal except for the upward conversions.
+Some minor features have been added also as thread attributes, reverse_lock, shared_lock_guard.
 
 In order to use the classes and functions described here, you can
 either include the specific headers specified by the descriptions of
@@ -42,5 +42,10 @@
 
 The source code compiled when building the library defines a macros BOOST_THREAD_SOURCE that is used to import or export it. The user must not define this macro in any case.
 
+The following section describes all the macros used to configure Boost.Thread.
+
+[include configuration.qbk]
+
+
 [endsect]
 

Added: trunk/libs/thread/doc/sync_tutorial.qbk
==============================================================================
--- (empty file)
+++ trunk/libs/thread/doc/sync_tutorial.qbk 2012-04-01 17:52:47 EDT (Sun, 01 Apr 2012)
@@ -0,0 +1,14 @@
+[/
+ (C) Copyright 2012 Vicente J. Botet Escriba.
+ Distributed under the Boost Software License, Version 1.0.
+ (See accompanying file LICENSE_1_0.txt or copy at
+ http://www.boost.org/LICENSE_1_0.txt).
+]
+
+[section:tutorial Tutorial]
+
+[@http://home.roadrunner.com/~hinnant/mutexes/locking.html Handling mutexes in C++] is an excellent tutorial. You need just replace std and ting by boost.
+
+[@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2406.html Mutex, Lock, Condition Variable Rationale] adds rationale for the design decisions made for mutexes, locks and condition variables.
+
+[endsect]

Modified: trunk/libs/thread/doc/thread.qbk
==============================================================================
--- trunk/libs/thread/doc/thread.qbk (original)
+++ trunk/libs/thread/doc/thread.qbk 2012-04-01 17:52:47 EDT (Sun, 01 Apr 2012)
@@ -6,7 +6,7 @@
   http://www.boost.org/LICENSE_1_0.txt).
 ]
 
-[article Thread
+[library Thread
     [quickbook 1.5]
     [version 2.0.0]
     [authors [Williams, Anthony] [Botet Escriba, Vicente J.]]
@@ -222,6 +222,7 @@
 [include thread_ref.qbk]
 
 [section:synchronization Synchronization]
+[include sync_tutorial.qbk]
 [include mutex_concepts.qbk]
 [include mutexes.qbk]
 [include condition_variables.qbk]

Modified: trunk/libs/thread/example/shared_mutex.cpp
==============================================================================
--- trunk/libs/thread/example/shared_mutex.cpp (original)
+++ trunk/libs/thread/example/shared_mutex.cpp 2012-04-01 17:52:47 EDT (Sun, 01 Apr 2012)
@@ -5,6 +5,7 @@
 
 #define BOOST_THREAD_SHARED_MUTEX_PROVIDES_UPWARDS_CONVERSION
 #define BOOST_THREAD_PROVIDES_EXPLICIT_LOCK_CONVERSION
+#define BOOST_THREAD_SHARED_MUTEX_GENERIC
 
 #include <iostream>
 #include <boost/thread/mutex.hpp>

Added: trunk/libs/thread/src/shared_mutex.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/thread/src/shared_mutex.cpp 2012-04-01 17:52:47 EDT (Sun, 01 Apr 2012)
@@ -0,0 +1,328 @@
+// Copyright Howard Hinnant 2007-2010.
+// Copyright Vicente J. Botet Escriba 2012.
+// Use, modification and distribution are subject to 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/v2/shared_mutex.hpp>
+#include <boost/thread/locks.hpp>
+
+namespace boost
+{
+
+ namespace thread_v2
+ {
+
+ // 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: trunk/libs/thread/test/sync/mutual_exclusion/locks/reverse_lock/copy_assign_fail.cpp
==============================================================================
--- trunk/libs/thread/test/sync/mutual_exclusion/locks/reverse_lock/copy_assign_fail.cpp (original)
+++ trunk/libs/thread/test/sync/mutual_exclusion/locks/reverse_lock/copy_assign_fail.cpp 2012-04-01 17:52:47 EDT (Sun, 01 Apr 2012)
@@ -10,6 +10,7 @@
 // reverse_lock& operator=(reverse_lock const&) = delete;
 
 #include <boost/thread/locks.hpp>
+#include <boost/thread/reverse_lock.hpp>
 #include <boost/thread/mutex.hpp>
 #include <boost/detail/lightweight_test.hpp>
 
@@ -23,7 +24,7 @@
   {
     boost::reverse_lock<boost::unique_lock<boost::mutex> > lg0(lk0);
     boost::reverse_lock<boost::unique_lock<boost::mutex> > lg1(lk1);
- lk1 = lk0;
+ lg1 = lg0;
   }
 
 }

Modified: trunk/libs/thread/test/sync/mutual_exclusion/locks/reverse_lock/copy_ctor_fail.cpp
==============================================================================
--- trunk/libs/thread/test/sync/mutual_exclusion/locks/reverse_lock/copy_ctor_fail.cpp (original)
+++ trunk/libs/thread/test/sync/mutual_exclusion/locks/reverse_lock/copy_ctor_fail.cpp 2012-04-01 17:52:47 EDT (Sun, 01 Apr 2012)
@@ -11,6 +11,7 @@
 
 
 #include <boost/thread/locks.hpp>
+#include <boost/thread/reverse_lock.hpp>
 #include <boost/thread/mutex.hpp>
 #include <boost/detail/lightweight_test.hpp>
 

Added: trunk/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_shared_lock_for_pass.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_shared_lock_for_pass.cpp 2012-04-01 17:52:47 EDT (Sun, 01 Apr 2012)
@@ -0,0 +1,69 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class unique_lock;
+
+// template <class Rep, class Period>
+// unique_lock(shared_lock<mutex_type>&&,
+// const chrono::duration<Rep, Period>&);
+
+#define BOOST_THREAD_SHARED_MUTEX_PROVIDES_UPWARDS_CONVERSION
+#define BOOST_THREAD_PROVIDES_EXPLICIT_LOCK_CONVERSION
+#define BOOST_THREAD_SHARED_MUTEX_GENERIC
+
+#include <boost/thread/locks.hpp>
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+boost::shared_mutex m;
+
+int main()
+{
+ {
+ boost::shared_lock<boost::shared_mutex> lk0(m);
+ boost::unique_lock<boost::shared_mutex> lk(boost::move(lk0), boost::chrono::milliseconds(1));
+ BOOST_TEST(lk.mutex() == &m);
+ BOOST_TEST(lk.owns_lock() == true);
+ BOOST_TEST(lk0.mutex() == 0);
+ BOOST_TEST(lk0.owns_lock() == false);
+ }
+ {
+ boost::unique_lock<boost::shared_mutex>
+ lk(boost::shared_lock<boost::shared_mutex>(m), boost::chrono::milliseconds(1));
+ BOOST_TEST(lk.mutex() == &m);
+ BOOST_TEST(lk.owns_lock() == true);
+ }
+ {
+ boost::shared_lock<boost::shared_mutex> lk0(m, boost::defer_lock);
+ boost::unique_lock<boost::shared_mutex> lk(boost::move(lk0), boost::chrono::milliseconds(1));
+ BOOST_TEST(lk.mutex() == &m);
+ BOOST_TEST(lk.owns_lock() == false);
+ BOOST_TEST(lk0.mutex() == 0);
+ BOOST_TEST(lk0.owns_lock() == false);
+ }
+ {
+ boost::shared_lock<boost::shared_mutex> lk0(m, boost::defer_lock);
+ lk0.release();
+ boost::unique_lock<boost::shared_mutex> lk(boost::move(lk0), boost::chrono::milliseconds(1));
+ BOOST_TEST(lk.mutex() == 0);
+ BOOST_TEST(lk.owns_lock() == false);
+ BOOST_TEST(lk0.mutex() == 0);
+ BOOST_TEST(lk0.owns_lock() == false);
+ }
+
+ return boost::report_errors();
+}
+

Added: trunk/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_shared_lock_try_pass.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_shared_lock_try_pass.cpp 2012-04-01 17:52:47 EDT (Sun, 01 Apr 2012)
@@ -0,0 +1,66 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class unique_lock;
+
+// unique_lock(shared_lock&& u, try_to_lock);
+
+#define BOOST_THREAD_SHARED_MUTEX_PROVIDES_UPWARDS_CONVERSION
+#define BOOST_THREAD_PROVIDES_EXPLICIT_LOCK_CONVERSION
+#define BOOST_THREAD_SHARED_MUTEX_GENERIC
+
+#include <boost/thread/locks.hpp>
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+boost::shared_mutex m;
+
+int main()
+{
+ {
+ boost::shared_lock<boost::shared_mutex> lk0(m);
+ boost::unique_lock<boost::shared_mutex> lk(boost::move(lk0), boost::try_to_lock );
+ BOOST_TEST(lk.mutex() == &m);
+ BOOST_TEST(lk.owns_lock() == true);
+ BOOST_TEST(lk0.mutex() == 0);
+ BOOST_TEST(lk0.owns_lock() == false);
+ }
+ {
+ boost::unique_lock<boost::shared_mutex> lk(boost::shared_lock<boost::shared_mutex>(m), boost::try_to_lock);
+ BOOST_TEST(lk.mutex() == &m);
+ BOOST_TEST(lk.owns_lock() == true);
+ }
+ {
+ boost::shared_lock<boost::shared_mutex> lk0(m, boost::defer_lock);
+ boost::unique_lock<boost::shared_mutex> lk(boost::move(lk0), boost::try_to_lock);
+ BOOST_TEST(lk.mutex() == &m);
+ BOOST_TEST(lk.owns_lock() == false);
+ BOOST_TEST(lk0.mutex() == 0);
+ BOOST_TEST(lk0.owns_lock() == false);
+ }
+ {
+ boost::shared_lock<boost::shared_mutex> lk0(m, boost::defer_lock);
+ lk0.release();
+ boost::unique_lock<boost::shared_mutex> lk(boost::move(lk0), boost::try_to_lock);
+ BOOST_TEST(lk.mutex() == 0);
+ BOOST_TEST(lk.owns_lock() == false);
+ BOOST_TEST(lk0.mutex() == 0);
+ BOOST_TEST(lk0.owns_lock() == false);
+ }
+
+ return boost::report_errors();
+}
+

Added: trunk/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_shared_lock_until_pass.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_shared_lock_until_pass.cpp 2012-04-01 17:52:47 EDT (Sun, 01 Apr 2012)
@@ -0,0 +1,69 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class unique_lock;
+
+// template <class Clock, class Duration>
+// unique_lock(shared_lock<mutex_type>&&,
+// const chrono::time_point<Clock, Duration>&);
+
+#define BOOST_THREAD_SHARED_MUTEX_PROVIDES_UPWARDS_CONVERSION
+#define BOOST_THREAD_PROVIDES_EXPLICIT_LOCK_CONVERSION
+#define BOOST_THREAD_SHARED_MUTEX_GENERIC
+
+#include <boost/thread/locks.hpp>
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+boost::shared_mutex m;
+
+int main()
+{
+ {
+ boost::shared_lock<boost::shared_mutex> lk0(m);
+ boost::unique_lock<boost::shared_mutex> lk( boost::move(lk0), boost::chrono::steady_clock::now()+boost::chrono::milliseconds(1));
+ BOOST_TEST(lk.mutex() == &m);
+ BOOST_TEST(lk.owns_lock() == true);
+ BOOST_TEST(lk0.mutex() == 0);
+ BOOST_TEST(lk0.owns_lock() == false);
+ }
+ {
+ boost::unique_lock<boost::shared_mutex>
+ lk( boost::shared_lock<boost::shared_mutex>(m), boost::chrono::steady_clock::now()+boost::chrono::milliseconds(1));
+ BOOST_TEST(lk.mutex() == &m);
+ BOOST_TEST(lk.owns_lock() == true);
+ }
+ {
+ boost::shared_lock<boost::shared_mutex> lk0(m, boost::defer_lock);
+ boost::unique_lock<boost::shared_mutex> lk( boost::move(lk0), boost::chrono::steady_clock::now()+boost::chrono::milliseconds(1));
+ BOOST_TEST(lk.mutex() == &m);
+ BOOST_TEST(lk.owns_lock() == false);
+ BOOST_TEST(lk0.mutex() == 0);
+ BOOST_TEST(lk0.owns_lock() == false);
+ }
+ {
+ boost::shared_lock<boost::shared_mutex> lk0(m, boost::defer_lock);
+ lk0.release();
+ boost::unique_lock<boost::shared_mutex> lk( boost::move(lk0), boost::chrono::steady_clock::now()+boost::chrono::milliseconds(1));
+ BOOST_TEST(lk.mutex() == 0);
+ BOOST_TEST(lk.owns_lock() == false);
+ BOOST_TEST(lk0.mutex() == 0);
+ BOOST_TEST(lk0.owns_lock() == false);
+ }
+
+ return boost::report_errors();
+}
+

Added: trunk/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/move_ctor_shared_lock_for_pass.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/move_ctor_shared_lock_for_pass.cpp 2012-04-01 17:52:47 EDT (Sun, 01 Apr 2012)
@@ -0,0 +1,69 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class upgrade_lock;
+
+// template <class Clock, class Duration>
+// upgrade_lock(shared_lock<mutex_type>&&,
+// const chrono::duration<Rep, Period>&);
+
+#define BOOST_THREAD_SHARED_MUTEX_PROVIDES_UPWARDS_CONVERSION
+#define BOOST_THREAD_PROVIDES_EXPLICIT_LOCK_CONVERSION
+#define BOOST_THREAD_SHARED_MUTEX_GENERIC
+
+#include <boost/thread/locks.hpp>
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+boost::shared_mutex m;
+
+int main()
+{
+ {
+ boost::shared_lock<boost::shared_mutex> lk0(m);
+ boost::upgrade_lock<boost::shared_mutex> lk(boost::move(lk0), boost::chrono::milliseconds(1));
+ BOOST_TEST(lk.mutex() == &m);
+ BOOST_TEST(lk.owns_lock() == true);
+ BOOST_TEST(lk0.mutex() == 0);
+ BOOST_TEST(lk0.owns_lock() == false);
+ }
+ {
+ boost::upgrade_lock<boost::shared_mutex>
+ lk(boost::shared_lock<boost::shared_mutex>(m), boost::chrono::milliseconds(1));
+ BOOST_TEST(lk.mutex() == &m);
+ BOOST_TEST(lk.owns_lock() == true);
+ }
+ {
+ boost::shared_lock<boost::shared_mutex> lk0(m, boost::defer_lock);
+ boost::upgrade_lock<boost::shared_mutex> lk(boost::move(lk0), boost::chrono::milliseconds(1));
+ BOOST_TEST(lk.mutex() == &m);
+ BOOST_TEST(lk.owns_lock() == false);
+ BOOST_TEST(lk0.mutex() == 0);
+ BOOST_TEST(lk0.owns_lock() == false);
+ }
+ {
+ boost::shared_lock<boost::shared_mutex> lk0(m, boost::defer_lock);
+ lk0.release();
+ boost::upgrade_lock<boost::shared_mutex> lk(boost::move(lk0), boost::chrono::milliseconds(1));
+ BOOST_TEST(lk.mutex() == 0);
+ BOOST_TEST(lk.owns_lock() == false);
+ BOOST_TEST(lk0.mutex() == 0);
+ BOOST_TEST(lk0.owns_lock() == false);
+ }
+
+ return boost::report_errors();
+}
+

Added: trunk/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/move_ctor_shared_lock_try_pass.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/move_ctor_shared_lock_try_pass.cpp 2012-04-01 17:52:47 EDT (Sun, 01 Apr 2012)
@@ -0,0 +1,66 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class upgrade_lock;
+
+// upgrade_lock(shared_lock&& u, try_to_lock);
+
+#define BOOST_THREAD_SHARED_MUTEX_PROVIDES_UPWARDS_CONVERSION
+#define BOOST_THREAD_PROVIDES_EXPLICIT_LOCK_CONVERSION
+#define BOOST_THREAD_SHARED_MUTEX_GENERIC
+
+#include <boost/thread/locks.hpp>
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+boost::shared_mutex m;
+
+int main()
+{
+ {
+ boost::shared_lock<boost::shared_mutex> lk0(m);
+ boost::upgrade_lock<boost::shared_mutex> lk(boost::move(lk0), boost::try_to_lock );
+ BOOST_TEST(lk.mutex() == &m);
+ BOOST_TEST(lk.owns_lock() == true);
+ BOOST_TEST(lk0.mutex() == 0);
+ BOOST_TEST(lk0.owns_lock() == false);
+ }
+ {
+ boost::upgrade_lock<boost::shared_mutex> lk(boost::shared_lock<boost::shared_mutex>(m), boost::try_to_lock);
+ BOOST_TEST(lk.mutex() == &m);
+ BOOST_TEST(lk.owns_lock() == true);
+ }
+ {
+ boost::shared_lock<boost::shared_mutex> lk0(m, boost::defer_lock);
+ boost::upgrade_lock<boost::shared_mutex> lk(boost::move(lk0), boost::try_to_lock);
+ BOOST_TEST(lk.mutex() == &m);
+ BOOST_TEST(lk.owns_lock() == false);
+ BOOST_TEST(lk0.mutex() == 0);
+ BOOST_TEST(lk0.owns_lock() == false);
+ }
+ {
+ boost::shared_lock<boost::shared_mutex> lk0(m, boost::defer_lock);
+ lk0.release();
+ boost::upgrade_lock<boost::shared_mutex> lk(boost::move(lk0), boost::try_to_lock);
+ BOOST_TEST(lk.mutex() == 0);
+ BOOST_TEST(lk.owns_lock() == false);
+ BOOST_TEST(lk0.mutex() == 0);
+ BOOST_TEST(lk0.owns_lock() == false);
+ }
+
+ return boost::report_errors();
+}
+

Added: trunk/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/move_ctor_shared_lock_until_pass.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/move_ctor_shared_lock_until_pass.cpp 2012-04-01 17:52:47 EDT (Sun, 01 Apr 2012)
@@ -0,0 +1,69 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class upgrade_lock;
+
+// template <class Clock, class Duration>
+// upgrade_lock(shared_lock<mutex_type>&&,
+// const chrono::time_point<Clock, Duration>&);
+
+#define BOOST_THREAD_SHARED_MUTEX_PROVIDES_UPWARDS_CONVERSION
+#define BOOST_THREAD_PROVIDES_EXPLICIT_LOCK_CONVERSION
+#define BOOST_THREAD_SHARED_MUTEX_GENERIC
+
+#include <boost/thread/locks.hpp>
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+boost::shared_mutex m;
+
+int main()
+{
+ {
+ boost::shared_lock<boost::shared_mutex> lk0(m);
+ boost::upgrade_lock<boost::shared_mutex> lk( boost::move(lk0), boost::chrono::steady_clock::now()+boost::chrono::milliseconds(1));
+ BOOST_TEST(lk.mutex() == &m);
+ BOOST_TEST(lk.owns_lock() == true);
+ BOOST_TEST(lk0.mutex() == 0);
+ BOOST_TEST(lk0.owns_lock() == false);
+ }
+ {
+ boost::upgrade_lock<boost::shared_mutex>
+ lk( boost::shared_lock<boost::shared_mutex>(m), boost::chrono::steady_clock::now()+boost::chrono::milliseconds(1));
+ BOOST_TEST(lk.mutex() == &m);
+ BOOST_TEST(lk.owns_lock() == true);
+ }
+ {
+ boost::shared_lock<boost::shared_mutex> lk0(m, boost::defer_lock);
+ boost::upgrade_lock<boost::shared_mutex> lk( boost::move(lk0), boost::chrono::steady_clock::now()+boost::chrono::milliseconds(1));
+ BOOST_TEST(lk.mutex() == &m);
+ BOOST_TEST(lk.owns_lock() == false);
+ BOOST_TEST(lk0.mutex() == 0);
+ BOOST_TEST(lk0.owns_lock() == false);
+ }
+ {
+ boost::shared_lock<boost::shared_mutex> lk0(m, boost::defer_lock);
+ lk0.release();
+ boost::upgrade_lock<boost::shared_mutex> lk( boost::move(lk0), boost::chrono::steady_clock::now()+boost::chrono::milliseconds(1));
+ BOOST_TEST(lk.mutex() == 0);
+ BOOST_TEST(lk.owns_lock() == false);
+ BOOST_TEST(lk0.mutex() == 0);
+ BOOST_TEST(lk0.owns_lock() == false);
+ }
+
+ return boost::report_errors();
+}
+


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