summaryrefslogtreecommitdiff
path: root/boost/interprocess/sync/interprocess_upgradable_mutex.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/interprocess/sync/interprocess_upgradable_mutex.hpp')
-rw-r--r--boost/interprocess/sync/interprocess_upgradable_mutex.hpp156
1 files changed, 85 insertions, 71 deletions
diff --git a/boost/interprocess/sync/interprocess_upgradable_mutex.hpp b/boost/interprocess/sync/interprocess_upgradable_mutex.hpp
index 8d5a452626..b90c71ef7f 100644
--- a/boost/interprocess/sync/interprocess_upgradable_mutex.hpp
+++ b/boost/interprocess/sync/interprocess_upgradable_mutex.hpp
@@ -1,6 +1,8 @@
-//////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+//
+// Code based on Howard Hinnant's upgrade_mutex class
//
-// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2012. 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)
//
@@ -11,7 +13,7 @@
#ifndef BOOST_INTERPROCESS_UPGRADABLE_MUTEX_HPP
#define BOOST_INTERPROCESS_UPGRADABLE_MUTEX_HPP
-#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+#if defined(_MSC_VER)
# pragma once
#endif
@@ -195,7 +197,7 @@ class interprocess_upgradable_mutex
//!Throws: An exception derived from interprocess_exception on error.
bool try_unlock_sharable_and_lock_upgradable();
- /// @cond
+ #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
private:
typedef scoped_lock<interprocess_mutex> scoped_lock_t;
@@ -249,7 +251,7 @@ class interprocess_upgradable_mutex
if(mp_ctrl){
//Recover upgradable lock
mp_ctrl->upgradable_in = 1;
- ++mp_ctrl->num_upr_shar;
+ ++mp_ctrl->num_upr_shar;
//Execute the second half of exclusive locking
mp_ctrl->exclusive_in = 0;
}
@@ -264,10 +266,10 @@ class interprocess_upgradable_mutex
= ~(unsigned(3) << (sizeof(unsigned)*CHAR_BIT-2));
};
typedef base_constants_t<0> constants;
- /// @endcond
+ #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
};
-/// @cond
+#if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
template <int Dummy>
const unsigned interprocess_upgradable_mutex::base_constants_t<Dummy>::max_readers;
@@ -284,12 +286,12 @@ inline interprocess_upgradable_mutex::~interprocess_upgradable_mutex()
inline void interprocess_upgradable_mutex::lock()
{
- scoped_lock_t lock(m_mut);
+ scoped_lock_t lck(m_mut);
//The exclusive lock must block in the first gate
//if an exclusive or upgradable lock has been acquired
while (this->m_ctrl.exclusive_in || this->m_ctrl.upgradable_in){
- this->m_first_gate.wait(lock);
+ this->m_first_gate.wait(lck);
}
//Mark that exclusive lock has been acquired
@@ -300,18 +302,18 @@ inline void interprocess_upgradable_mutex::lock()
//Now wait until all readers are gone
while (this->m_ctrl.num_upr_shar){
- this->m_second_gate.wait(lock);
+ this->m_second_gate.wait(lck);
}
rollback.release();
}
inline bool interprocess_upgradable_mutex::try_lock()
{
- scoped_lock_t lock(m_mut, try_to_lock);
+ scoped_lock_t lck(m_mut, try_to_lock);
//If we can't lock or any has there is any exclusive, upgradable
//or sharable mark return false;
- if(!lock.owns()
+ if(!lck.owns()
|| this->m_ctrl.exclusive_in
|| this->m_ctrl.num_upr_shar){
return false;
@@ -323,18 +325,20 @@ inline bool interprocess_upgradable_mutex::try_lock()
inline bool interprocess_upgradable_mutex::timed_lock
(const boost::posix_time::ptime &abs_time)
{
- if(abs_time == boost::posix_time::pos_infin){
- this->lock();
- return true;
- }
- scoped_lock_t lock(m_mut, abs_time);
- if(!lock.owns()) return false;
+ //Mutexes and condvars handle just fine infinite abs_times
+ //so avoid checking it here
+ scoped_lock_t lck(m_mut, abs_time);
+ if(!lck.owns()) return false;
//The exclusive lock must block in the first gate
//if an exclusive or upgradable lock has been acquired
while (this->m_ctrl.exclusive_in || this->m_ctrl.upgradable_in){
- if(!this->m_first_gate.timed_wait(lock, abs_time))
- return !(this->m_ctrl.exclusive_in || this->m_ctrl.upgradable_in);
+ if(!this->m_first_gate.timed_wait(lck, abs_time)){
+ if(this->m_ctrl.exclusive_in || this->m_ctrl.upgradable_in){
+ return false;
+ }
+ break;
+ }
}
//Mark that exclusive lock has been acquired
@@ -345,8 +349,11 @@ inline bool interprocess_upgradable_mutex::timed_lock
//Now wait until all readers are gone
while (this->m_ctrl.num_upr_shar){
- if(!this->m_second_gate.timed_wait(lock, abs_time)){
- return !(this->m_ctrl.num_upr_shar);
+ if(!this->m_second_gate.timed_wait(lck, abs_time)){
+ if(this->m_ctrl.num_upr_shar){
+ return false;
+ }
+ break;
}
}
rollback.release();
@@ -355,7 +362,7 @@ inline bool interprocess_upgradable_mutex::timed_lock
inline void interprocess_upgradable_mutex::unlock()
{
- scoped_lock_t lock(m_mut);
+ scoped_lock_t lck(m_mut);
this->m_ctrl.exclusive_in = 0;
this->m_first_gate.notify_all();
}
@@ -364,14 +371,14 @@ inline void interprocess_upgradable_mutex::unlock()
inline void interprocess_upgradable_mutex::lock_upgradable()
{
- scoped_lock_t lock(m_mut);
+ scoped_lock_t lck(m_mut);
//The upgradable lock must block in the first gate
//if an exclusive or upgradable lock has been acquired
//or there are too many sharable locks
while(this->m_ctrl.exclusive_in || this->m_ctrl.upgradable_in
|| this->m_ctrl.num_upr_shar == constants::max_readers){
- this->m_first_gate.wait(lock);
+ this->m_first_gate.wait(lck);
}
//Mark that upgradable lock has been acquired
@@ -382,12 +389,12 @@ inline void interprocess_upgradable_mutex::lock_upgradable()
inline bool interprocess_upgradable_mutex::try_lock_upgradable()
{
- scoped_lock_t lock(m_mut, try_to_lock);
+ scoped_lock_t lck(m_mut, try_to_lock);
//The upgradable lock must fail
//if an exclusive or upgradable lock has been acquired
//or there are too many sharable locks
- if(!lock.owns()
+ if(!lck.owns()
|| this->m_ctrl.exclusive_in
|| this->m_ctrl.upgradable_in
|| this->m_ctrl.num_upr_shar == constants::max_readers){
@@ -404,12 +411,10 @@ inline bool interprocess_upgradable_mutex::try_lock_upgradable()
inline bool interprocess_upgradable_mutex::timed_lock_upgradable
(const boost::posix_time::ptime &abs_time)
{
- if(abs_time == boost::posix_time::pos_infin){
- this->lock_upgradable();
- return true;
- }
- scoped_lock_t lock(m_mut, abs_time);
- if(!lock.owns()) return false;
+ //Mutexes and condvars handle just fine infinite abs_times
+ //so avoid checking it here
+ scoped_lock_t lck(m_mut, abs_time);
+ if(!lck.owns()) return false;
//The upgradable lock must block in the first gate
//if an exclusive or upgradable lock has been acquired
@@ -417,10 +422,13 @@ inline bool interprocess_upgradable_mutex::timed_lock_upgradable
while(this->m_ctrl.exclusive_in
|| this->m_ctrl.upgradable_in
|| this->m_ctrl.num_upr_shar == constants::max_readers){
- if(!this->m_first_gate.timed_wait(lock, abs_time)){
- return!(this->m_ctrl.exclusive_in
- || this->m_ctrl.upgradable_in
- || this->m_ctrl.num_upr_shar == constants::max_readers);
+ if(!this->m_first_gate.timed_wait(lck, abs_time)){
+ if((this->m_ctrl.exclusive_in
+ || this->m_ctrl.upgradable_in
+ || this->m_ctrl.num_upr_shar == constants::max_readers)){
+ return false;
+ }
+ break;
}
}
@@ -433,7 +441,7 @@ inline bool interprocess_upgradable_mutex::timed_lock_upgradable
inline void interprocess_upgradable_mutex::unlock_upgradable()
{
- scoped_lock_t lock(m_mut);
+ scoped_lock_t lck(m_mut);
//Mark that upgradable lock has been acquired
//And add upgradable to the sharable count
this->m_ctrl.upgradable_in = 0;
@@ -445,14 +453,14 @@ inline void interprocess_upgradable_mutex::unlock_upgradable()
inline void interprocess_upgradable_mutex::lock_sharable()
{
- scoped_lock_t lock(m_mut);
+ scoped_lock_t lck(m_mut);
//The sharable lock must block in the first gate
//if an exclusive lock has been acquired
//or there are too many sharable locks
while(this->m_ctrl.exclusive_in
|| this->m_ctrl.num_upr_shar == constants::max_readers){
- this->m_first_gate.wait(lock);
+ this->m_first_gate.wait(lck);
}
//Increment sharable count
@@ -461,12 +469,12 @@ inline void interprocess_upgradable_mutex::lock_sharable()
inline bool interprocess_upgradable_mutex::try_lock_sharable()
{
- scoped_lock_t lock(m_mut, try_to_lock);
+ scoped_lock_t lck(m_mut, try_to_lock);
//The sharable lock must fail
//if an exclusive lock has been acquired
//or there are too many sharable locks
- if(!lock.owns()
+ if(!lck.owns()
|| this->m_ctrl.exclusive_in
|| this->m_ctrl.num_upr_shar == constants::max_readers){
return false;
@@ -480,21 +488,22 @@ inline bool interprocess_upgradable_mutex::try_lock_sharable()
inline bool interprocess_upgradable_mutex::timed_lock_sharable
(const boost::posix_time::ptime &abs_time)
{
- if(abs_time == boost::posix_time::pos_infin){
- this->lock_sharable();
- return true;
- }
- scoped_lock_t lock(m_mut, abs_time);
- if(!lock.owns()) return false;
+ //Mutexes and condvars handle just fine infinite abs_times
+ //so avoid checking it here
+ scoped_lock_t lck(m_mut, abs_time);
+ if(!lck.owns()) return false;
//The sharable lock must block in the first gate
//if an exclusive lock has been acquired
//or there are too many sharable locks
while (this->m_ctrl.exclusive_in
|| this->m_ctrl.num_upr_shar == constants::max_readers){
- if(!this->m_first_gate.timed_wait(lock, abs_time)){
- return!(this->m_ctrl.exclusive_in
- || this->m_ctrl.num_upr_shar == constants::max_readers);
+ if(!this->m_first_gate.timed_wait(lck, abs_time)){
+ if(this->m_ctrl.exclusive_in
+ || this->m_ctrl.num_upr_shar == constants::max_readers){
+ return false;
+ }
+ break;
}
}
@@ -505,7 +514,7 @@ inline bool interprocess_upgradable_mutex::timed_lock_sharable
inline void interprocess_upgradable_mutex::unlock_sharable()
{
- scoped_lock_t lock(m_mut);
+ scoped_lock_t lck(m_mut);
//Decrement sharable count
--this->m_ctrl.num_upr_shar;
if (this->m_ctrl.num_upr_shar == 0){
@@ -522,7 +531,7 @@ inline void interprocess_upgradable_mutex::unlock_sharable()
inline void interprocess_upgradable_mutex::unlock_and_lock_upgradable()
{
- scoped_lock_t lock(m_mut);
+ scoped_lock_t lck(m_mut);
//Unmark it as exclusive
this->m_ctrl.exclusive_in = 0;
//Mark it as upgradable
@@ -535,7 +544,7 @@ inline void interprocess_upgradable_mutex::unlock_and_lock_upgradable()
inline void interprocess_upgradable_mutex::unlock_and_lock_sharable()
{
- scoped_lock_t lock(m_mut);
+ scoped_lock_t lck(m_mut);
//Unmark it as exclusive
this->m_ctrl.exclusive_in = 0;
//The sharable count should be 0 so increment it
@@ -546,7 +555,7 @@ inline void interprocess_upgradable_mutex::unlock_and_lock_sharable()
inline void interprocess_upgradable_mutex::unlock_upgradable_and_lock_sharable()
{
- scoped_lock_t lock(m_mut);
+ scoped_lock_t lck(m_mut);
//Unmark it as upgradable (we don't have to decrement count)
this->m_ctrl.upgradable_in = 0;
//Notify readers/upgradable that they can enter
@@ -557,11 +566,11 @@ inline void interprocess_upgradable_mutex::unlock_upgradable_and_lock_sharable()
inline void interprocess_upgradable_mutex::unlock_upgradable_and_lock()
{
- scoped_lock_t lock(m_mut);
+ scoped_lock_t lck(m_mut);
//Simulate unlock_upgradable() without
//notifying sharables.
this->m_ctrl.upgradable_in = 0;
- --this->m_ctrl.num_upr_shar;
+ --this->m_ctrl.num_upr_shar;
//Execute the second half of exclusive locking
this->m_ctrl.exclusive_in = 1;
@@ -569,22 +578,22 @@ inline void interprocess_upgradable_mutex::unlock_upgradable_and_lock()
upgradable_to_exclusive_rollback rollback(m_ctrl);
while (this->m_ctrl.num_upr_shar){
- this->m_second_gate.wait(lock);
+ this->m_second_gate.wait(lck);
}
rollback.release();
}
inline bool interprocess_upgradable_mutex::try_unlock_upgradable_and_lock()
{
- scoped_lock_t lock(m_mut, try_to_lock);
+ scoped_lock_t lck(m_mut, try_to_lock);
//Check if there are no readers
- if(!lock.owns()
+ if(!lck.owns()
|| this->m_ctrl.num_upr_shar != 1){
return false;
}
//Now unlock upgradable and mark exclusive
this->m_ctrl.upgradable_in = 0;
- --this->m_ctrl.num_upr_shar;
+ --this->m_ctrl.num_upr_shar;
this->m_ctrl.exclusive_in = 1;
return true;
}
@@ -592,13 +601,15 @@ inline bool interprocess_upgradable_mutex::try_unlock_upgradable_and_lock()
inline bool interprocess_upgradable_mutex::timed_unlock_upgradable_and_lock
(const boost::posix_time::ptime &abs_time)
{
- scoped_lock_t lock(m_mut, abs_time);
- if(!lock.owns()) return false;
+ //Mutexes and condvars handle just fine infinite abs_times
+ //so avoid checking it here
+ scoped_lock_t lck(m_mut, abs_time);
+ if(!lck.owns()) return false;
//Simulate unlock_upgradable() without
//notifying sharables.
this->m_ctrl.upgradable_in = 0;
- --this->m_ctrl.num_upr_shar;
+ --this->m_ctrl.num_upr_shar;
//Execute the second half of exclusive locking
this->m_ctrl.exclusive_in = 1;
@@ -606,8 +617,11 @@ inline bool interprocess_upgradable_mutex::timed_unlock_upgradable_and_lock
upgradable_to_exclusive_rollback rollback(m_ctrl);
while (this->m_ctrl.num_upr_shar){
- if(!this->m_second_gate.timed_wait(lock, abs_time)){
- return !(this->m_ctrl.num_upr_shar);
+ if(!this->m_second_gate.timed_wait(lck, abs_time)){
+ if(this->m_ctrl.num_upr_shar){
+ return false;
+ }
+ break;
}
}
rollback.release();
@@ -616,11 +630,11 @@ inline bool interprocess_upgradable_mutex::timed_unlock_upgradable_and_lock
inline bool interprocess_upgradable_mutex::try_unlock_sharable_and_lock()
{
- scoped_lock_t lock(m_mut, try_to_lock);
+ scoped_lock_t lck(m_mut, try_to_lock);
//If we can't lock or any has there is any exclusive, upgradable
//or sharable mark return false;
- if(!lock.owns()
+ if(!lck.owns()
|| this->m_ctrl.exclusive_in
|| this->m_ctrl.upgradable_in
|| this->m_ctrl.num_upr_shar != 1){
@@ -633,11 +647,11 @@ inline bool interprocess_upgradable_mutex::try_unlock_sharable_and_lock()
inline bool interprocess_upgradable_mutex::try_unlock_sharable_and_lock_upgradable()
{
- scoped_lock_t lock(m_mut, try_to_lock);
+ scoped_lock_t lck(m_mut, try_to_lock);
//The upgradable lock must fail
//if an exclusive or upgradable lock has been acquired
- if(!lock.owns()
+ if(!lck.owns()
|| this->m_ctrl.exclusive_in
|| this->m_ctrl.upgradable_in){
return false;
@@ -648,7 +662,7 @@ inline bool interprocess_upgradable_mutex::try_unlock_sharable_and_lock_upgradab
return true;
}
-/// @endcond
+#endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
} //namespace interprocess {
} //namespace boost {