1 2 // Copyright Oliver Kowalke 2013. 3 // Distributed under the Boost Software License, Version 1.0. 4 // (See accompanying file LICENSE_1_0.txt or copy at 5 // http://www.boost.org/LICENSE_1_0.txt) 6 // 7 // based on boost::interprocess::sync::interprocess_spinlock 8 9 #ifndef BOOST_FIBERS_RECURSIVE_TIMED_MUTEX_H 10 #define BOOST_FIBERS_RECURSIVE_TIMED_MUTEX_H 11 12 #include <chrono> 13 #include <cstddef> 14 15 #include <boost/config.hpp> 16 17 #include <boost/assert.hpp> 18 19 #include <boost/fiber/context.hpp> 20 #include <boost/fiber/detail/config.hpp> 21 #include <boost/fiber/detail/convert.hpp> 22 #include <boost/fiber/detail/spinlock.hpp> 23 24 #ifdef BOOST_HAS_ABI_HEADERS 25 # include BOOST_ABI_PREFIX 26 #endif 27 28 #ifdef _MSC_VER 29 # pragma warning(push) 30 # pragma warning(disable:4251) 31 #endif 32 33 namespace boost { 34 namespace fibers { 35 36 class condition_variable; 37 38 class BOOST_FIBERS_DECL recursive_timed_mutex { 39 private: 40 friend class condition_variable; 41 42 using wait_queue_type = context::wait_queue_t; 43 44 detail::spinlock wait_queue_splk_{}; 45 wait_queue_type wait_queue_{}; 46 context * owner_{ nullptr }; 47 std::size_t count_{ 0 }; 48 49 bool try_lock_until_( std::chrono::steady_clock::time_point const& timeout_time) noexcept; 50 51 public: 52 recursive_timed_mutex() = default; 53 ~recursive_timed_mutex()54 ~recursive_timed_mutex() { 55 BOOST_ASSERT( nullptr == owner_); 56 BOOST_ASSERT( 0 == count_); 57 BOOST_ASSERT( wait_queue_.empty() ); 58 } 59 60 recursive_timed_mutex( recursive_timed_mutex const&) = delete; 61 recursive_timed_mutex & operator=( recursive_timed_mutex const&) = delete; 62 63 void lock(); 64 65 bool try_lock() noexcept; 66 67 template< typename Clock, typename Duration > try_lock_until(std::chrono::time_point<Clock,Duration> const & timeout_time_)68 bool try_lock_until( std::chrono::time_point< Clock, Duration > const& timeout_time_) { 69 std::chrono::steady_clock::time_point timeout_time = detail::convert( timeout_time_); 70 return try_lock_until_( timeout_time); 71 } 72 73 template< typename Rep, typename Period > try_lock_for(std::chrono::duration<Rep,Period> const & timeout_duration)74 bool try_lock_for( std::chrono::duration< Rep, Period > const& timeout_duration) { 75 return try_lock_until_( std::chrono::steady_clock::now() + timeout_duration); 76 } 77 78 void unlock(); 79 }; 80 81 }} 82 83 #ifdef _MSC_VER 84 # pragma warning(pop) 85 #endif 86 87 #ifdef BOOST_HAS_ABI_HEADERS 88 # include BOOST_ABI_SUFFIX 89 #endif 90 91 #endif // BOOST_FIBERS_RECURSIVE_TIMED_MUTEX_H 92