summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '3rdParty/Boost/src/boost/thread/pthread/shared_mutex.hpp')
-rw-r--r--3rdParty/Boost/src/boost/thread/pthread/shared_mutex.hpp274
1 files changed, 261 insertions, 13 deletions
diff --git a/3rdParty/Boost/src/boost/thread/pthread/shared_mutex.hpp b/3rdParty/Boost/src/boost/thread/pthread/shared_mutex.hpp
index bc26282..cf45188 100644
--- a/3rdParty/Boost/src/boost/thread/pthread/shared_mutex.hpp
+++ b/3rdParty/Boost/src/boost/thread/pthread/shared_mutex.hpp
@@ -2,6 +2,7 @@
#define BOOST_THREAD_PTHREAD_SHARED_MUTEX_HPP
// (C) Copyright 2006-8 Anthony Williams
+// (C) Copyright 2012 Vicente J. Botet Escriba
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
@@ -12,6 +13,11 @@
#include <boost/thread/mutex.hpp>
#include <boost/thread/condition_variable.hpp>
#include <boost/thread/detail/thread_interruption.hpp>
+#ifdef BOOST_THREAD_USES_CHRONO
+#include <boost/chrono/system_clocks.hpp>
+#include <boost/chrono/ceil.hpp>
+#endif
+#include <boost/thread/detail/delete.hpp>
#include <boost/config/abi_prefix.hpp>
@@ -27,7 +33,7 @@ namespace boost
bool upgrade;
bool exclusive_waiting_blocked;
};
-
+
state_data state;
@@ -41,9 +47,10 @@ namespace boost
exclusive_cond.notify_one();
shared_cond.notify_all();
}
-
public:
+ BOOST_THREAD_NO_COPYABLE(shared_mutex)
+
shared_mutex()
{
state_data state_={0,0,0,0};
@@ -58,7 +65,7 @@ namespace boost
{
boost::this_thread::disable_interruption do_not_disturb;
boost::mutex::scoped_lock lk(state_change);
-
+
while(state.exclusive || state.exclusive_waiting_blocked)
{
shared_cond.wait(lk);
@@ -69,7 +76,7 @@ namespace boost
bool try_lock_shared()
{
boost::mutex::scoped_lock lk(state_change);
-
+
if(state.exclusive || state.exclusive_waiting_blocked)
{
return false;
@@ -85,7 +92,7 @@ namespace boost
{
boost::this_thread::disable_interruption do_not_disturb;
boost::mutex::scoped_lock lk(state_change);
-
+
while(state.exclusive || state.exclusive_waiting_blocked)
{
if(!shared_cond.timed_wait(lk,timeout))
@@ -102,12 +109,34 @@ namespace boost
{
return timed_lock_shared(get_system_time()+relative_time);
}
+#ifdef BOOST_THREAD_USES_CHRONO
+ template <class Rep, class Period>
+ bool try_lock_shared_for(const chrono::duration<Rep, Period>& rel_time)
+ {
+ return try_lock_shared_until(chrono::steady_clock::now() + rel_time);
+ }
+ template <class Clock, class Duration>
+ bool try_lock_shared_until(const chrono::time_point<Clock, Duration>& abs_time)
+ {
+ boost::this_thread::disable_interruption do_not_disturb;
+ boost::mutex::scoped_lock lk(state_change);
+ while(state.exclusive || state.exclusive_waiting_blocked)
+ {
+ if(cv_status::timeout==shared_cond.wait_until(lk,abs_time))
+ {
+ return false;
+ }
+ }
+ ++state.shared_count;
+ return true;
+ }
+#endif
void unlock_shared()
{
boost::mutex::scoped_lock lk(state_change);
bool const last_reader=!--state.shared_count;
-
+
if(last_reader)
{
if(state.upgrade)
@@ -128,7 +157,7 @@ namespace boost
{
boost::this_thread::disable_interruption do_not_disturb;
boost::mutex::scoped_lock lk(state_change);
-
+
while(state.shared_count || state.exclusive)
{
state.exclusive_waiting_blocked=true;
@@ -150,7 +179,7 @@ namespace boost
if(state.shared_count || state.exclusive)
{
state.exclusive_waiting_blocked=false;
- exclusive_cond.notify_one();
+ release_waiters();
return false;
}
break;
@@ -166,10 +195,41 @@ namespace boost
return timed_lock(get_system_time()+relative_time);
}
+#ifdef BOOST_THREAD_USES_CHRONO
+ template <class Rep, class Period>
+ bool try_lock_for(const chrono::duration<Rep, Period>& rel_time)
+ {
+ return try_lock_until(chrono::steady_clock::now() + rel_time);
+ }
+ template <class Clock, class Duration>
+ bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time)
+ {
+ boost::this_thread::disable_interruption do_not_disturb;
+ boost::mutex::scoped_lock lk(state_change);
+
+ while(state.shared_count || state.exclusive)
+ {
+ state.exclusive_waiting_blocked=true;
+ if(cv_status::timeout == exclusive_cond.wait_until(lk,abs_time))
+ {
+ if(state.shared_count || state.exclusive)
+ {
+ state.exclusive_waiting_blocked=false;
+ release_waiters();
+ return false;
+ }
+ break;
+ }
+ }
+ state.exclusive=true;
+ return true;
+ }
+#endif
+
bool try_lock()
{
boost::mutex::scoped_lock lk(state_change);
-
+
if(state.shared_count || state.exclusive)
{
return false;
@@ -179,7 +239,7 @@ namespace boost
state.exclusive=true;
return true;
}
-
+
}
void unlock()
@@ -228,6 +288,33 @@ namespace boost
return timed_lock_upgrade(get_system_time()+relative_time);
}
+#ifdef BOOST_THREAD_USES_CHRONO
+ template <class Rep, class Period>
+ bool try_lock_upgrade_for(const chrono::duration<Rep, Period>& rel_time)
+ {
+ return try_lock_upgrade_until(chrono::steady_clock::now() + rel_time);
+ }
+ template <class Clock, class Duration>
+ bool try_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);
+ while(state.exclusive || state.exclusive_waiting_blocked || state.upgrade)
+ {
+ if(cv_status::timeout == shared_cond.wait_until(lk,abs_time))
+ {
+ if(state.exclusive || state.exclusive_waiting_blocked || state.upgrade)
+ {
+ return false;
+ }
+ break;
+ }
+ }
+ ++state.shared_count;
+ state.upgrade=true;
+ return true;
+ }
+#endif
bool try_lock_upgrade()
{
boost::mutex::scoped_lock lk(state_change);
@@ -248,14 +335,17 @@ namespace boost
boost::mutex::scoped_lock lk(state_change);
state.upgrade=false;
bool const last_reader=!--state.shared_count;
-
+
if(last_reader)
{
state.exclusive_waiting_blocked=false;
release_waiters();
+ } else {
+ shared_cond.notify_all();
}
}
+ // Upgrade <-> Exclusive
void unlock_upgrade_and_lock()
{
boost::this_thread::disable_interruption do_not_disturb;
@@ -278,7 +368,58 @@ namespace boost
state.exclusive_waiting_blocked=false;
release_waiters();
}
-
+
+ bool try_unlock_upgrade_and_lock()
+ {
+ boost::mutex::scoped_lock lk(state_change);
+ if( !state.exclusive
+ && !state.exclusive_waiting_blocked
+ && state.upgrade
+ && state.shared_count==1)
+ {
+ state.shared_count=0;
+ state.exclusive=true;
+ state.upgrade=false;
+ return true;
+ }
+ return false;
+ }
+#ifdef BOOST_THREAD_USES_CHRONO
+ template <class Rep, class Period>
+ bool
+ try_unlock_upgrade_and_lock_for(
+ const chrono::duration<Rep, Period>& rel_time)
+ {
+ return try_unlock_upgrade_and_lock_until(
+ chrono::steady_clock::now() + rel_time);
+ }
+ template <class Clock, class Duration>
+ bool
+ try_unlock_upgrade_and_lock_until(
+ const chrono::time_point<Clock, Duration>& abs_time)
+ {
+ boost::this_thread::disable_interruption do_not_disturb;
+ boost::mutex::scoped_lock lk(state_change);
+ if (state.shared_count != 1)
+ {
+ for (;;)
+ {
+ 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
+
+ // Shared <-> Exclusive
void unlock_and_lock_shared()
{
boost::mutex::scoped_lock lk(state_change);
@@ -287,7 +428,59 @@ namespace boost
state.exclusive_waiting_blocked=false;
release_waiters();
}
-
+
+#ifdef BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS
+ 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)
+ {
+ for (;;)
+ {
+ 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()
{
boost::mutex::scoped_lock lk(state_change);
@@ -295,7 +488,62 @@ namespace boost
state.exclusive_waiting_blocked=false;
release_waiters();
}
+
+#ifdef BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS
+ 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
+ )
+ {
+ for (;;)
+ {
+ 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;
}
#include <boost/config/abi_suffix.hpp>