Warning, file /include/boost/interprocess/sync/spin/recursive_mutex.hpp was not indexed
or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027 #ifndef BOOST_INTERPROCESS_DETAIL_SPIN_RECURSIVE_MUTEX_HPP
0028 #define BOOST_INTERPROCESS_DETAIL_SPIN_RECURSIVE_MUTEX_HPP
0029
0030 #ifndef BOOST_CONFIG_HPP
0031 # include <boost/config.hpp>
0032 #endif
0033 #
0034 #if defined(BOOST_HAS_PRAGMA_ONCE)
0035 # pragma once
0036 #endif
0037
0038 #include <boost/interprocess/detail/config_begin.hpp>
0039 #include <boost/interprocess/detail/workaround.hpp>
0040
0041 #include <boost/interprocess/detail/os_thread_functions.hpp>
0042 #include <boost/interprocess/exceptions.hpp>
0043 #include <boost/interprocess/detail/atomic.hpp>
0044 #include <boost/cstdint.hpp>
0045 #include <boost/interprocess/detail/os_thread_functions.hpp>
0046 #include <boost/interprocess/sync/spin/mutex.hpp>
0047 #include <boost/interprocess/timed_utils.hpp>
0048 #include <boost/assert.hpp>
0049
0050 namespace boost {
0051 namespace interprocess {
0052 namespace ipcdetail {
0053
0054 class spin_recursive_mutex
0055 {
0056 spin_recursive_mutex(const spin_recursive_mutex &);
0057 spin_recursive_mutex &operator=(const spin_recursive_mutex &);
0058 public:
0059
0060 spin_recursive_mutex();
0061 ~spin_recursive_mutex();
0062
0063 void lock();
0064 bool try_lock();
0065 template<class TimePoint>
0066 bool timed_lock(const TimePoint &abs_time);
0067
0068 template<class TimePoint> bool try_lock_until(const TimePoint &abs_time)
0069 { return this->timed_lock(abs_time); }
0070
0071 template<class Duration> bool try_lock_for(const Duration &dur)
0072 { return this->timed_lock(duration_to_ustime(dur)); }
0073
0074 void unlock();
0075 void take_ownership();
0076 private:
0077 spin_mutex m_mutex;
0078 unsigned int m_nLockCount;
0079 volatile ipcdetail::OS_systemwide_thread_id_t m_nOwner;
0080 volatile boost::uint32_t m_s;
0081 };
0082
0083 inline spin_recursive_mutex::spin_recursive_mutex()
0084 : m_nLockCount(0), m_nOwner(ipcdetail::get_invalid_systemwide_thread_id()){}
0085
0086 inline spin_recursive_mutex::~spin_recursive_mutex(){}
0087
0088 inline void spin_recursive_mutex::lock()
0089 {
0090 typedef ipcdetail::OS_systemwide_thread_id_t handle_t;
0091 const handle_t thr_id(ipcdetail::get_current_systemwide_thread_id());
0092 handle_t old_id;
0093 ipcdetail::systemwide_thread_id_copy(m_nOwner, old_id);
0094 if(ipcdetail::equal_systemwide_thread_id(thr_id , old_id)){
0095 if((unsigned int)(m_nLockCount+1) == 0){
0096
0097 throw interprocess_exception("boost::interprocess::spin_recursive_mutex recursive lock overflow");
0098 }
0099 ++m_nLockCount;
0100 }
0101 else{
0102 m_mutex.lock();
0103 ipcdetail::systemwide_thread_id_copy(thr_id, m_nOwner);
0104 m_nLockCount = 1;
0105 }
0106 }
0107
0108 inline bool spin_recursive_mutex::try_lock()
0109 {
0110 typedef ipcdetail::OS_systemwide_thread_id_t handle_t;
0111 handle_t thr_id(ipcdetail::get_current_systemwide_thread_id());
0112 handle_t old_id;
0113 ipcdetail::systemwide_thread_id_copy(m_nOwner, old_id);
0114 if(ipcdetail::equal_systemwide_thread_id(thr_id , old_id)) {
0115 if((unsigned int)(m_nLockCount+1) == 0){
0116
0117 throw interprocess_exception("boost::interprocess::spin_recursive_mutex recursive lock overflow");
0118 }
0119 ++m_nLockCount;
0120 return true;
0121 }
0122 if(m_mutex.try_lock()){
0123 ipcdetail::systemwide_thread_id_copy(thr_id, m_nOwner);
0124 m_nLockCount = 1;
0125 return true;
0126 }
0127 return false;
0128 }
0129
0130 template<class TimePoint>
0131 inline bool spin_recursive_mutex::timed_lock(const TimePoint &abs_time)
0132 {
0133 typedef ipcdetail::OS_systemwide_thread_id_t handle_t;
0134 const handle_t thr_id(ipcdetail::get_current_systemwide_thread_id());
0135 handle_t old_id;
0136 ipcdetail::systemwide_thread_id_copy(m_nOwner, old_id);
0137 if(ipcdetail::equal_systemwide_thread_id(thr_id , old_id)) {
0138 if((unsigned int)(m_nLockCount+1) == 0){
0139
0140 throw interprocess_exception("boost::interprocess::spin_recursive_mutex recursive lock overflow");
0141 }
0142 ++m_nLockCount;
0143 return true;
0144 }
0145
0146 if(m_mutex.timed_lock(abs_time)){
0147 ipcdetail::systemwide_thread_id_copy(thr_id, m_nOwner);
0148 m_nLockCount = 1;
0149 return true;
0150 }
0151 return false;
0152 }
0153
0154 inline void spin_recursive_mutex::unlock()
0155 {
0156 typedef ipcdetail::OS_systemwide_thread_id_t handle_t;
0157 handle_t old_id;
0158 ipcdetail::systemwide_thread_id_copy(m_nOwner, old_id);
0159 const handle_t thr_id(ipcdetail::get_current_systemwide_thread_id());
0160 (void)old_id;
0161 (void)thr_id;
0162 BOOST_ASSERT(ipcdetail::equal_systemwide_thread_id(thr_id, old_id));
0163 --m_nLockCount;
0164 if(!m_nLockCount){
0165 const handle_t new_id(ipcdetail::get_invalid_systemwide_thread_id());
0166 ipcdetail::systemwide_thread_id_copy(new_id, m_nOwner);
0167 m_mutex.unlock();
0168 }
0169 }
0170
0171 inline void spin_recursive_mutex::take_ownership()
0172 {
0173 typedef ipcdetail::OS_systemwide_thread_id_t handle_t;
0174 this->m_nLockCount = 1;
0175 const handle_t thr_id(ipcdetail::get_current_systemwide_thread_id());
0176 ipcdetail::systemwide_thread_id_copy(thr_id, m_nOwner);
0177 }
0178
0179 }
0180 }
0181 }
0182
0183 #include <boost/interprocess/detail/config_end.hpp>
0184
0185 #endif