File indexing completed on 2025-12-16 10:10:03
0001 #ifndef BOOST_BASIC_RECURSIVE_MUTEX_WIN32_HPP
0002 #define BOOST_BASIC_RECURSIVE_MUTEX_WIN32_HPP
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #include <boost/thread/win32/thread_primitives.hpp>
0014 #include <boost/thread/win32/basic_timed_mutex.hpp>
0015 #ifdef BOOST_THREAD_USES_CHRONO
0016 #include <boost/chrono/system_clocks.hpp>
0017 #include <boost/chrono/ceil.hpp>
0018 #endif
0019
0020 #include <boost/config/abi_prefix.hpp>
0021
0022 namespace boost
0023 {
0024 namespace detail
0025 {
0026 template<typename underlying_mutex_type>
0027 struct basic_recursive_mutex_impl
0028 {
0029 long recursion_count;
0030 long locking_thread_id;
0031 underlying_mutex_type mutex;
0032
0033 void initialize()
0034 {
0035 recursion_count=0;
0036 locking_thread_id=0;
0037 mutex.initialize();
0038 }
0039
0040 void destroy()
0041 {
0042 mutex.destroy();
0043 }
0044
0045 bool try_lock() BOOST_NOEXCEPT
0046 {
0047 long const current_thread_id=boost::winapi::GetCurrentThreadId();
0048 return try_recursive_lock(current_thread_id) || try_basic_lock(current_thread_id);
0049 }
0050
0051 void lock()
0052 {
0053 long const current_thread_id=boost::winapi::GetCurrentThreadId();
0054 if(!try_recursive_lock(current_thread_id))
0055 {
0056 mutex.lock();
0057 BOOST_INTERLOCKED_EXCHANGE(&locking_thread_id,current_thread_id);
0058 recursion_count=1;
0059 }
0060 }
0061 #if defined BOOST_THREAD_USES_DATETIME
0062 bool timed_lock(::boost::system_time const& target)
0063 {
0064 long const current_thread_id=boost::winapi::GetCurrentThreadId();
0065 return try_recursive_lock(current_thread_id) || try_timed_lock(current_thread_id,target);
0066 }
0067 template<typename Duration>
0068 bool timed_lock(Duration const& target)
0069 {
0070 long const current_thread_id=boost::winapi::GetCurrentThreadId();
0071 return try_recursive_lock(current_thread_id) || try_timed_lock(current_thread_id,target);
0072 }
0073 #endif
0074
0075 #ifdef BOOST_THREAD_USES_CHRONO
0076 template <class Rep, class Period>
0077 bool try_lock_for(const chrono::duration<Rep, Period>& rel_time)
0078 {
0079 long const current_thread_id=boost::winapi::GetCurrentThreadId();
0080 return try_recursive_lock(current_thread_id) || try_timed_lock_for(current_thread_id,rel_time);
0081 }
0082 template <class Clock, class Duration>
0083 bool try_lock_until(const chrono::time_point<Clock, Duration>& t)
0084 {
0085 long const current_thread_id=boost::winapi::GetCurrentThreadId();
0086 return try_recursive_lock(current_thread_id) || try_timed_lock_until(current_thread_id,t);
0087 }
0088 #endif
0089 void unlock()
0090 {
0091 if(!--recursion_count)
0092 {
0093 BOOST_INTERLOCKED_EXCHANGE(&locking_thread_id,0);
0094 mutex.unlock();
0095 }
0096 }
0097
0098 private:
0099 bool try_recursive_lock(long current_thread_id) BOOST_NOEXCEPT
0100 {
0101 if(::boost::detail::interlocked_read_acquire(&locking_thread_id)==current_thread_id)
0102 {
0103 ++recursion_count;
0104 return true;
0105 }
0106 return false;
0107 }
0108
0109 bool try_basic_lock(long current_thread_id) BOOST_NOEXCEPT
0110 {
0111 if(mutex.try_lock())
0112 {
0113 BOOST_INTERLOCKED_EXCHANGE(&locking_thread_id,current_thread_id);
0114 recursion_count=1;
0115 return true;
0116 }
0117 return false;
0118 }
0119
0120 #if defined BOOST_THREAD_USES_DATETIME
0121 bool try_timed_lock(long current_thread_id,::boost::system_time const& target)
0122 {
0123 if(mutex.timed_lock(target))
0124 {
0125 BOOST_INTERLOCKED_EXCHANGE(&locking_thread_id,current_thread_id);
0126 recursion_count=1;
0127 return true;
0128 }
0129 return false;
0130 }
0131 template<typename Duration>
0132 bool try_timed_lock(long current_thread_id,Duration const& target)
0133 {
0134 if(mutex.timed_lock(target))
0135 {
0136 BOOST_INTERLOCKED_EXCHANGE(&locking_thread_id,current_thread_id);
0137 recursion_count=1;
0138 return true;
0139 }
0140 return false;
0141 }
0142 #endif
0143 template <typename TP>
0144 bool try_timed_lock_until(long current_thread_id,TP const& target)
0145 {
0146 if(mutex.try_lock_until(target))
0147 {
0148 BOOST_INTERLOCKED_EXCHANGE(&locking_thread_id,current_thread_id);
0149 recursion_count=1;
0150 return true;
0151 }
0152 return false;
0153 }
0154 template <typename D>
0155 bool try_timed_lock_for(long current_thread_id,D const& target)
0156 {
0157 if(mutex.try_lock_for(target))
0158 {
0159 BOOST_INTERLOCKED_EXCHANGE(&locking_thread_id,current_thread_id);
0160 recursion_count=1;
0161 return true;
0162 }
0163 return false;
0164 }
0165 };
0166
0167 typedef basic_recursive_mutex_impl<basic_timed_mutex> basic_recursive_mutex;
0168 typedef basic_recursive_mutex_impl<basic_timed_mutex> basic_recursive_timed_mutex;
0169 }
0170 }
0171
0172 #define BOOST_BASIC_RECURSIVE_MUTEX_INITIALIZER {0}
0173
0174 #include <boost/config/abi_suffix.hpp>
0175
0176 #endif