summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '3rdParty/Boost/boost/thread/pthread/shared_mutex.hpp')
-rw-r--r--3rdParty/Boost/boost/thread/pthread/shared_mutex.hpp303
1 files changed, 303 insertions, 0 deletions
diff --git a/3rdParty/Boost/boost/thread/pthread/shared_mutex.hpp b/3rdParty/Boost/boost/thread/pthread/shared_mutex.hpp
new file mode 100644
index 0000000..3ce4e23
--- /dev/null
+++ b/3rdParty/Boost/boost/thread/pthread/shared_mutex.hpp
@@ -0,0 +1,303 @@
+#ifndef BOOST_THREAD_PTHREAD_SHARED_MUTEX_HPP
+#define BOOST_THREAD_PTHREAD_SHARED_MUTEX_HPP
+
+// (C) Copyright 2006-8 Anthony Williams
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/assert.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/thread/condition_variable.hpp>
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost
+{
+ class shared_mutex
+ {
+ private:
+ struct state_data
+ {
+ unsigned shared_count;
+ bool exclusive;
+ bool upgrade;
+ bool exclusive_waiting_blocked;
+ };
+
+
+
+ state_data state;
+ boost::mutex state_change;
+ boost::condition_variable shared_cond;
+ boost::condition_variable exclusive_cond;
+ boost::condition_variable upgrade_cond;
+
+ void release_waiters()
+ {
+ exclusive_cond.notify_one();
+ shared_cond.notify_all();
+ }
+
+
+ public:
+ shared_mutex()
+ {
+ state_data state_={0,0,0,0};
+ state=state_;
+ }
+
+ ~shared_mutex()
+ {
+ }
+
+ void lock_shared()
+ {
+ 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);
+ }
+ ++state.shared_count;
+ }
+
+ bool try_lock_shared()
+ {
+ boost::mutex::scoped_lock lk(state_change);
+
+ if(state.exclusive || state.exclusive_waiting_blocked)
+ {
+ return false;
+ }
+ else
+ {
+ ++state.shared_count;
+ return true;
+ }
+ }
+
+ bool timed_lock_shared(system_time const& timeout)
+ {
+ 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))
+ {
+ return false;
+ }
+ }
+ ++state.shared_count;
+ return true;
+ }
+
+ template<typename TimeDuration>
+ bool timed_lock_shared(TimeDuration const & relative_time)
+ {
+ return timed_lock_shared(get_system_time()+relative_time);
+ }
+
+ void unlock_shared()
+ {
+ boost::mutex::scoped_lock lk(state_change);
+ bool const last_reader=!--state.shared_count;
+
+ if(last_reader)
+ {
+ if(state.upgrade)
+ {
+ state.upgrade=false;
+ state.exclusive=true;
+ upgrade_cond.notify_one();
+ }
+ else
+ {
+ state.exclusive_waiting_blocked=false;
+ }
+ release_waiters();
+ }
+ }
+
+ void lock()
+ {
+ 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;
+ exclusive_cond.wait(lk);
+ }
+ state.exclusive=true;
+ }
+
+ bool timed_lock(system_time const& timeout)
+ {
+ 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(!exclusive_cond.timed_wait(lk,timeout))
+ {
+ if(state.shared_count || state.exclusive)
+ {
+ state.exclusive_waiting_blocked=false;
+ exclusive_cond.notify_one();
+ return false;
+ }
+ break;
+ }
+ }
+ state.exclusive=true;
+ return true;
+ }
+
+ template<typename TimeDuration>
+ bool timed_lock(TimeDuration const & relative_time)
+ {
+ return timed_lock(get_system_time()+relative_time);
+ }
+
+ bool try_lock()
+ {
+ boost::mutex::scoped_lock lk(state_change);
+
+ if(state.shared_count || state.exclusive)
+ {
+ return false;
+ }
+ else
+ {
+ state.exclusive=true;
+ return true;
+ }
+
+ }
+
+ void unlock()
+ {
+ boost::mutex::scoped_lock lk(state_change);
+ state.exclusive=false;
+ state.exclusive_waiting_blocked=false;
+ release_waiters();
+ }
+
+ void lock_upgrade()
+ {
+ boost::this_thread::disable_interruption do_not_disturb;
+ boost::mutex::scoped_lock lk(state_change);
+ while(state.exclusive || state.exclusive_waiting_blocked || state.upgrade)
+ {
+ shared_cond.wait(lk);
+ }
+ ++state.shared_count;
+ state.upgrade=true;
+ }
+
+ bool timed_lock_upgrade(system_time const& timeout)
+ {
+ 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(!shared_cond.timed_wait(lk,timeout))
+ {
+ if(state.exclusive || state.exclusive_waiting_blocked || state.upgrade)
+ {
+ return false;
+ }
+ break;
+ }
+ }
+ ++state.shared_count;
+ state.upgrade=true;
+ return true;
+ }
+
+ template<typename TimeDuration>
+ bool timed_lock_upgrade(TimeDuration const & relative_time)
+ {
+ return timed_lock(get_system_time()+relative_time);
+ }
+
+ bool try_lock_upgrade()
+ {
+ boost::mutex::scoped_lock lk(state_change);
+ if(state.exclusive || state.exclusive_waiting_blocked || state.upgrade)
+ {
+ return false;
+ }
+ else
+ {
+ ++state.shared_count;
+ state.upgrade=true;
+ return true;
+ }
+ }
+
+ void unlock_upgrade()
+ {
+ 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();
+ }
+ }
+
+ void unlock_upgrade_and_lock()
+ {
+ boost::this_thread::disable_interruption do_not_disturb;
+ boost::mutex::scoped_lock lk(state_change);
+ --state.shared_count;
+ while(state.shared_count)
+ {
+ upgrade_cond.wait(lk);
+ }
+ state.upgrade=false;
+ state.exclusive=true;
+ }
+
+ void unlock_and_lock_upgrade()
+ {
+ boost::mutex::scoped_lock lk(state_change);
+ state.exclusive=false;
+ state.upgrade=true;
+ ++state.shared_count;
+ state.exclusive_waiting_blocked=false;
+ release_waiters();
+ }
+
+ void unlock_and_lock_shared()
+ {
+ boost::mutex::scoped_lock lk(state_change);
+ state.exclusive=false;
+ ++state.shared_count;
+ state.exclusive_waiting_blocked=false;
+ release_waiters();
+ }
+
+ void unlock_upgrade_and_lock_shared()
+ {
+ boost::mutex::scoped_lock lk(state_change);
+ state.upgrade=false;
+ state.exclusive_waiting_blocked=false;
+ release_waiters();
+ }
+ };
+}
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif