File indexing completed on 2025-06-30 08:17:16
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