Chris@16: #ifndef BOOST_BASIC_RECURSIVE_MUTEX_WIN32_HPP Chris@16: #define BOOST_BASIC_RECURSIVE_MUTEX_WIN32_HPP Chris@16: Chris@16: // basic_recursive_mutex.hpp Chris@16: // Chris@16: // (C) Copyright 2006-8 Anthony Williams Chris@16: // (C) Copyright 2011-2012 Vicente J. Botet Escriba Chris@16: // Chris@16: // Distributed under the Boost Software License, Version 1.0. (See Chris@16: // accompanying file LICENSE_1_0.txt or copy at Chris@16: // http://www.boost.org/LICENSE_1_0.txt) Chris@16: Chris@16: #include Chris@16: #include Chris@16: #ifdef BOOST_THREAD_USES_CHRONO Chris@16: #include Chris@16: #include Chris@16: #endif Chris@16: Chris@16: #include Chris@16: Chris@16: namespace boost Chris@16: { Chris@16: namespace detail Chris@16: { Chris@16: template Chris@16: struct basic_recursive_mutex_impl Chris@16: { Chris@16: long recursion_count; Chris@16: long locking_thread_id; Chris@16: underlying_mutex_type mutex; Chris@16: Chris@16: void initialize() Chris@16: { Chris@16: recursion_count=0; Chris@16: locking_thread_id=0; Chris@16: mutex.initialize(); Chris@16: } Chris@16: Chris@16: void destroy() Chris@16: { Chris@16: mutex.destroy(); Chris@16: } Chris@16: Chris@16: bool try_lock() BOOST_NOEXCEPT Chris@16: { Chris@16: long const current_thread_id=win32::GetCurrentThreadId(); Chris@16: return try_recursive_lock(current_thread_id) || try_basic_lock(current_thread_id); Chris@16: } Chris@16: Chris@16: void lock() Chris@16: { Chris@16: long const current_thread_id=win32::GetCurrentThreadId(); Chris@16: if(!try_recursive_lock(current_thread_id)) Chris@16: { Chris@16: mutex.lock(); Chris@16: BOOST_INTERLOCKED_EXCHANGE(&locking_thread_id,current_thread_id); Chris@16: recursion_count=1; Chris@16: } Chris@16: } Chris@16: #if defined BOOST_THREAD_USES_DATETIME Chris@16: bool timed_lock(::boost::system_time const& target) Chris@16: { Chris@16: long const current_thread_id=win32::GetCurrentThreadId(); Chris@16: return try_recursive_lock(current_thread_id) || try_timed_lock(current_thread_id,target); Chris@16: } Chris@16: template Chris@16: bool timed_lock(Duration const& timeout) Chris@16: { Chris@16: return timed_lock(get_system_time()+timeout); Chris@16: } Chris@16: #endif Chris@16: Chris@16: #ifdef BOOST_THREAD_USES_CHRONO Chris@16: template Chris@16: bool try_lock_for(const chrono::duration& rel_time) Chris@16: { Chris@16: long const current_thread_id=win32::GetCurrentThreadId(); Chris@16: return try_recursive_lock(current_thread_id) || try_timed_lock_for(current_thread_id,rel_time); Chris@16: } Chris@16: template Chris@16: bool try_lock_until(const chrono::time_point& t) Chris@16: { Chris@16: long const current_thread_id=win32::GetCurrentThreadId(); Chris@16: return try_recursive_lock(current_thread_id) || try_timed_lock_until(current_thread_id,t); Chris@16: } Chris@16: #endif Chris@16: void unlock() Chris@16: { Chris@16: if(!--recursion_count) Chris@16: { Chris@16: BOOST_INTERLOCKED_EXCHANGE(&locking_thread_id,0); Chris@16: mutex.unlock(); Chris@16: } Chris@16: } Chris@16: Chris@16: private: Chris@16: bool try_recursive_lock(long current_thread_id) BOOST_NOEXCEPT Chris@16: { Chris@16: if(::boost::detail::interlocked_read_acquire(&locking_thread_id)==current_thread_id) Chris@16: { Chris@16: ++recursion_count; Chris@16: return true; Chris@16: } Chris@16: return false; Chris@16: } Chris@16: Chris@16: bool try_basic_lock(long current_thread_id) BOOST_NOEXCEPT Chris@16: { Chris@16: if(mutex.try_lock()) Chris@16: { Chris@16: BOOST_INTERLOCKED_EXCHANGE(&locking_thread_id,current_thread_id); Chris@16: recursion_count=1; Chris@16: return true; Chris@16: } Chris@16: return false; Chris@16: } Chris@16: Chris@16: #if defined BOOST_THREAD_USES_DATETIME Chris@16: bool try_timed_lock(long current_thread_id,::boost::system_time const& target) Chris@16: { Chris@16: if(mutex.timed_lock(target)) Chris@16: { Chris@16: BOOST_INTERLOCKED_EXCHANGE(&locking_thread_id,current_thread_id); Chris@16: recursion_count=1; Chris@16: return true; Chris@16: } Chris@16: return false; Chris@16: } Chris@16: #endif Chris@16: template Chris@16: bool try_timed_lock_until(long current_thread_id,TP const& target) Chris@16: { Chris@16: if(mutex.try_lock_until(target)) Chris@16: { Chris@16: BOOST_INTERLOCKED_EXCHANGE(&locking_thread_id,current_thread_id); Chris@16: recursion_count=1; Chris@16: return true; Chris@16: } Chris@16: return false; Chris@16: } Chris@16: template Chris@16: bool try_timed_lock_for(long current_thread_id,D const& target) Chris@16: { Chris@16: if(mutex.try_lock_for(target)) Chris@16: { Chris@16: BOOST_INTERLOCKED_EXCHANGE(&locking_thread_id,current_thread_id); Chris@16: recursion_count=1; Chris@16: return true; Chris@16: } Chris@16: return false; Chris@16: } Chris@16: }; Chris@16: Chris@16: typedef basic_recursive_mutex_impl basic_recursive_mutex; Chris@16: typedef basic_recursive_mutex_impl basic_recursive_timed_mutex; Chris@16: } Chris@16: } Chris@16: Chris@16: #define BOOST_BASIC_RECURSIVE_MUTEX_INITIALIZER {0} Chris@16: Chris@16: #include Chris@16: Chris@16: #endif