1 #ifndef BOOST_BASIC_RECURSIVE_MUTEX_WIN32_HPP 2 #define BOOST_BASIC_RECURSIVE_MUTEX_WIN32_HPP 3 4 // basic_recursive_mutex.hpp 5 // 6 // (C) Copyright 2006-8 Anthony Williams 7 // (C) Copyright 2011-2012 Vicente J. Botet Escriba 8 // 9 // Distributed under the Boost Software License, Version 1.0. (See 10 // accompanying file LICENSE_1_0.txt or copy at 11 // http://www.boost.org/LICENSE_1_0.txt) 12 13 #include <boost/thread/win32/thread_primitives.hpp> 14 #include <boost/thread/win32/basic_timed_mutex.hpp> 15 #ifdef BOOST_THREAD_USES_CHRONO 16 #include <boost/chrono/system_clocks.hpp> 17 #include <boost/chrono/ceil.hpp> 18 #endif 19 20 #include <boost/config/abi_prefix.hpp> 21 22 namespace boost 23 { 24 namespace detail 25 { 26 template<typename underlying_mutex_type> 27 struct basic_recursive_mutex_impl 28 { 29 long recursion_count; 30 long locking_thread_id; 31 underlying_mutex_type mutex; 32 initializeboost::detail::basic_recursive_mutex_impl33 void initialize() 34 { 35 recursion_count=0; 36 locking_thread_id=0; 37 mutex.initialize(); 38 } 39 destroyboost::detail::basic_recursive_mutex_impl40 void destroy() 41 { 42 mutex.destroy(); 43 } 44 try_lockboost::detail::basic_recursive_mutex_impl45 bool try_lock() BOOST_NOEXCEPT 46 { 47 long const current_thread_id=win32::GetCurrentThreadId(); 48 return try_recursive_lock(current_thread_id) || try_basic_lock(current_thread_id); 49 } 50 lockboost::detail::basic_recursive_mutex_impl51 void lock() 52 { 53 long const current_thread_id=win32::GetCurrentThreadId(); 54 if(!try_recursive_lock(current_thread_id)) 55 { 56 mutex.lock(); 57 BOOST_INTERLOCKED_EXCHANGE(&locking_thread_id,current_thread_id); 58 recursion_count=1; 59 } 60 } 61 #if defined BOOST_THREAD_USES_DATETIME timed_lockboost::detail::basic_recursive_mutex_impl62 bool timed_lock(::boost::system_time const& target) 63 { 64 long const current_thread_id=win32::GetCurrentThreadId(); 65 return try_recursive_lock(current_thread_id) || try_timed_lock(current_thread_id,target); 66 } 67 template<typename Duration> timed_lockboost::detail::basic_recursive_mutex_impl68 bool timed_lock(Duration const& timeout) 69 { 70 return timed_lock(get_system_time()+timeout); 71 } 72 #endif 73 74 #ifdef BOOST_THREAD_USES_CHRONO 75 template <class Rep, class Period> try_lock_forboost::detail::basic_recursive_mutex_impl76 bool try_lock_for(const chrono::duration<Rep, Period>& rel_time) 77 { 78 long const current_thread_id=win32::GetCurrentThreadId(); 79 return try_recursive_lock(current_thread_id) || try_timed_lock_for(current_thread_id,rel_time); 80 } 81 template <class Clock, class Duration> try_lock_untilboost::detail::basic_recursive_mutex_impl82 bool try_lock_until(const chrono::time_point<Clock, Duration>& t) 83 { 84 long const current_thread_id=win32::GetCurrentThreadId(); 85 return try_recursive_lock(current_thread_id) || try_timed_lock_until(current_thread_id,t); 86 } 87 #endif unlockboost::detail::basic_recursive_mutex_impl88 void unlock() 89 { 90 if(!--recursion_count) 91 { 92 BOOST_INTERLOCKED_EXCHANGE(&locking_thread_id,0); 93 mutex.unlock(); 94 } 95 } 96 97 private: try_recursive_lockboost::detail::basic_recursive_mutex_impl98 bool try_recursive_lock(long current_thread_id) BOOST_NOEXCEPT 99 { 100 if(::boost::detail::interlocked_read_acquire(&locking_thread_id)==current_thread_id) 101 { 102 ++recursion_count; 103 return true; 104 } 105 return false; 106 } 107 try_basic_lockboost::detail::basic_recursive_mutex_impl108 bool try_basic_lock(long current_thread_id) BOOST_NOEXCEPT 109 { 110 if(mutex.try_lock()) 111 { 112 BOOST_INTERLOCKED_EXCHANGE(&locking_thread_id,current_thread_id); 113 recursion_count=1; 114 return true; 115 } 116 return false; 117 } 118 119 #if defined BOOST_THREAD_USES_DATETIME try_timed_lockboost::detail::basic_recursive_mutex_impl120 bool try_timed_lock(long current_thread_id,::boost::system_time const& target) 121 { 122 if(mutex.timed_lock(target)) 123 { 124 BOOST_INTERLOCKED_EXCHANGE(&locking_thread_id,current_thread_id); 125 recursion_count=1; 126 return true; 127 } 128 return false; 129 } 130 #endif 131 template <typename TP> try_timed_lock_untilboost::detail::basic_recursive_mutex_impl132 bool try_timed_lock_until(long current_thread_id,TP const& target) 133 { 134 if(mutex.try_lock_until(target)) 135 { 136 BOOST_INTERLOCKED_EXCHANGE(&locking_thread_id,current_thread_id); 137 recursion_count=1; 138 return true; 139 } 140 return false; 141 } 142 template <typename D> try_timed_lock_forboost::detail::basic_recursive_mutex_impl143 bool try_timed_lock_for(long current_thread_id,D const& target) 144 { 145 if(mutex.try_lock_for(target)) 146 { 147 BOOST_INTERLOCKED_EXCHANGE(&locking_thread_id,current_thread_id); 148 recursion_count=1; 149 return true; 150 } 151 return false; 152 } 153 }; 154 155 typedef basic_recursive_mutex_impl<basic_timed_mutex> basic_recursive_mutex; 156 typedef basic_recursive_mutex_impl<basic_timed_mutex> basic_recursive_timed_mutex; 157 } 158 } 159 160 #define BOOST_BASIC_RECURSIVE_MUTEX_INITIALIZER {0} 161 162 #include <boost/config/abi_suffix.hpp> 163 164 #endif 165