]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/fiber/src/timed_mutex.cpp
d0482c5ca2d51978a1a163138ed3461b23f9a42d
[ceph.git] / ceph / src / boost / libs / fiber / src / timed_mutex.cpp
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 #include "boost/fiber/timed_mutex.hpp"
8
9 #include <algorithm>
10 #include <functional>
11
12 #include "boost/fiber/exceptions.hpp"
13 #include "boost/fiber/scheduler.hpp"
14
15 #ifdef BOOST_HAS_ABI_HEADERS
16 # include BOOST_ABI_PREFIX
17 #endif
18
19 namespace boost {
20 namespace fibers {
21
22 bool
23 timed_mutex::try_lock_until_( std::chrono::steady_clock::time_point const& timeout_time) noexcept {
24 while ( true) {
25 if ( std::chrono::steady_clock::now() > timeout_time) {
26 return false;
27 }
28 context * active_ctx = context::active();
29 detail::spinlock_lock lk{ wait_queue_splk_ };
30 if ( nullptr == owner_) {
31 owner_ = active_ctx;
32 return true;
33 }
34 if ( ! wait_queue_.suspend_and_wait_until( lk, active_ctx, timeout_time)) {
35 return false;
36 }
37 }
38 }
39
40 void
41 timed_mutex::lock() {
42 while ( true) {
43 context * active_ctx = context::active();
44 // store this fiber in order to be notified later
45 detail::spinlock_lock lk{ wait_queue_splk_ };
46 if ( BOOST_UNLIKELY( active_ctx == owner_) ) {
47 throw lock_error{
48 std::make_error_code( std::errc::resource_deadlock_would_occur),
49 "boost fiber: a deadlock is detected" };
50 }
51 if ( nullptr == owner_) {
52 owner_ = active_ctx;
53 return;
54 }
55 wait_queue_.suspend_and_wait( lk, active_ctx);
56 }
57 }
58
59 bool
60 timed_mutex::try_lock() {
61 context * active_ctx = context::active();
62 detail::spinlock_lock lk{ wait_queue_splk_ };
63 if ( BOOST_UNLIKELY( active_ctx == owner_) ) {
64 throw lock_error{
65 std::make_error_code( std::errc::resource_deadlock_would_occur),
66 "boost fiber: a deadlock is detected" };
67 }
68 if ( nullptr == owner_) {
69 owner_ = active_ctx;
70 }
71 lk.unlock();
72 // let other fiber release the lock
73 active_ctx->yield();
74 return active_ctx == owner_;
75 }
76
77 void
78 timed_mutex::unlock() {
79 context * active_ctx = context::active();
80 detail::spinlock_lock lk{ wait_queue_splk_ };
81 if ( BOOST_UNLIKELY( active_ctx != owner_) ) {
82 throw lock_error{
83 std::make_error_code( std::errc::operation_not_permitted),
84 "boost fiber: no privilege to perform the operation" };
85 }
86 owner_ = nullptr;
87
88 wait_queue_.notify_one();
89 }
90
91 }}
92
93 #ifdef BOOST_HAS_ABI_HEADERS
94 # include BOOST_ABI_SUFFIX
95 #endif