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