File indexing completed on 2025-01-18 09:38:32
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/assert.hpp>
0048
0049 namespace boost {
0050 namespace interprocess {
0051 namespace ipcdetail {
0052
0053 class spin_recursive_mutex
0054 {
0055 spin_recursive_mutex(const spin_recursive_mutex &);
0056 spin_recursive_mutex &operator=(const spin_recursive_mutex &);
0057 public:
0058
0059 spin_recursive_mutex();
0060 ~spin_recursive_mutex();
0061
0062 void lock();
0063 bool try_lock();
0064 template<class TimePoint>
0065 bool timed_lock(const TimePoint &abs_time);
0066
0067 template<class TimePoint> bool try_lock_until(const TimePoint &abs_time)
0068 { return this->timed_lock(abs_time); }
0069
0070 template<class Duration> bool try_lock_for(const Duration &dur)
0071 { return this->timed_lock(duration_to_ustime(dur)); }
0072
0073 void unlock();
0074 void take_ownership();
0075 private:
0076 spin_mutex m_mutex;
0077 unsigned int m_nLockCount;
0078 volatile ipcdetail::OS_systemwide_thread_id_t m_nOwner;
0079 volatile boost::uint32_t m_s;
0080 };
0081
0082 inline spin_recursive_mutex::spin_recursive_mutex()
0083 : m_nLockCount(0), m_nOwner(ipcdetail::get_invalid_systemwide_thread_id()){}
0084
0085 inline spin_recursive_mutex::~spin_recursive_mutex(){}
0086
0087 inline void spin_recursive_mutex::lock()
0088 {
0089 typedef ipcdetail::OS_systemwide_thread_id_t handle_t;
0090 const handle_t thr_id(ipcdetail::get_current_systemwide_thread_id());
0091 handle_t old_id;
0092 ipcdetail::systemwide_thread_id_copy(m_nOwner, old_id);
0093 if(ipcdetail::equal_systemwide_thread_id(thr_id , old_id)){
0094 if((unsigned int)(m_nLockCount+1) == 0){
0095
0096 throw interprocess_exception("boost::interprocess::spin_recursive_mutex recursive lock overflow");
0097 }
0098 ++m_nLockCount;
0099 }
0100 else{
0101 m_mutex.lock();
0102 ipcdetail::systemwide_thread_id_copy(thr_id, m_nOwner);
0103 m_nLockCount = 1;
0104 }
0105 }
0106
0107 inline bool spin_recursive_mutex::try_lock()
0108 {
0109 typedef ipcdetail::OS_systemwide_thread_id_t handle_t;
0110 handle_t thr_id(ipcdetail::get_current_systemwide_thread_id());
0111 handle_t old_id;
0112 ipcdetail::systemwide_thread_id_copy(m_nOwner, old_id);
0113 if(ipcdetail::equal_systemwide_thread_id(thr_id , old_id)) {
0114 if((unsigned int)(m_nLockCount+1) == 0){
0115
0116 throw interprocess_exception("boost::interprocess::spin_recursive_mutex recursive lock overflow");
0117 }
0118 ++m_nLockCount;
0119 return true;
0120 }
0121 if(m_mutex.try_lock()){
0122 ipcdetail::systemwide_thread_id_copy(thr_id, m_nOwner);
0123 m_nLockCount = 1;
0124 return true;
0125 }
0126 return false;
0127 }
0128
0129 template<class TimePoint>
0130 inline bool spin_recursive_mutex::timed_lock(const TimePoint &abs_time)
0131 {
0132 typedef ipcdetail::OS_systemwide_thread_id_t handle_t;
0133 const handle_t thr_id(ipcdetail::get_current_systemwide_thread_id());
0134 handle_t old_id;
0135 ipcdetail::systemwide_thread_id_copy(m_nOwner, old_id);
0136 if(ipcdetail::equal_systemwide_thread_id(thr_id , old_id)) {
0137 if((unsigned int)(m_nLockCount+1) == 0){
0138
0139 throw interprocess_exception("boost::interprocess::spin_recursive_mutex recursive lock overflow");
0140 }
0141 ++m_nLockCount;
0142 return true;
0143 }
0144
0145 if(m_mutex.timed_lock(abs_time)){
0146 ipcdetail::systemwide_thread_id_copy(thr_id, m_nOwner);
0147 m_nLockCount = 1;
0148 return true;
0149 }
0150 return false;
0151 }
0152
0153 inline void spin_recursive_mutex::unlock()
0154 {
0155 typedef ipcdetail::OS_systemwide_thread_id_t handle_t;
0156 handle_t old_id;
0157 ipcdetail::systemwide_thread_id_copy(m_nOwner, old_id);
0158 const handle_t thr_id(ipcdetail::get_current_systemwide_thread_id());
0159 (void)old_id;
0160 (void)thr_id;
0161 BOOST_ASSERT(ipcdetail::equal_systemwide_thread_id(thr_id, old_id));
0162 --m_nLockCount;
0163 if(!m_nLockCount){
0164 const handle_t new_id(ipcdetail::get_invalid_systemwide_thread_id());
0165 ipcdetail::systemwide_thread_id_copy(new_id, m_nOwner);
0166 m_mutex.unlock();
0167 }
0168 }
0169
0170 inline void spin_recursive_mutex::take_ownership()
0171 {
0172 typedef ipcdetail::OS_systemwide_thread_id_t handle_t;
0173 this->m_nLockCount = 1;
0174 const handle_t thr_id(ipcdetail::get_current_systemwide_thread_id());
0175 ipcdetail::systemwide_thread_id_copy(thr_id, m_nOwner);
0176 }
0177
0178 }
0179 }
0180 }
0181
0182 #include <boost/interprocess/detail/config_end.hpp>
0183
0184 #endif