]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/fiber/src/timed_mutex.cpp
add subtree-ish sources for 12.0.3
[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 if ( std::chrono::steady_clock::now() > timeout_time) {
25 return false;
26 }
27 context * ctx = context::active();
28 // store this fiber in order to be notified later
29 detail::spinlock_lock lk( wait_queue_splk_);
30 if ( nullptr == owner_) {
31 owner_ = ctx;
32 return true;
33 }
34 BOOST_ASSERT( ! ctx->wait_is_linked() );
35 ctx->wait_link( wait_queue_);
36 // suspend this fiber until notified or timed-out
37 if ( ! context::active()->wait_until( timeout_time, lk) ) {
38 // remove fiber from wait-queue
39 lk.lock();
40 ctx->wait_unlink();
41 return false;
42 }
43 BOOST_ASSERT( ! ctx->wait_is_linked() );
44 return true;
45 }
46
47 void
48 timed_mutex::lock() {
49 context * ctx = context::active();
50 // store this fiber in order to be notified later
51 detail::spinlock_lock lk( wait_queue_splk_);
52 if ( ctx == owner_) {
53 throw lock_error(
54 std::make_error_code( std::errc::resource_deadlock_would_occur),
55 "boost fiber: a deadlock is detected");
56 } else if ( nullptr == owner_) {
57 owner_ = ctx;
58 return;
59 }
60 BOOST_ASSERT( ! ctx->wait_is_linked() );
61 ctx->wait_link( wait_queue_);
62 // suspend this fiber
63 ctx->suspend( lk);
64 BOOST_ASSERT( ! ctx->wait_is_linked() );
65 }
66
67 bool
68 timed_mutex::try_lock() {
69 context * ctx = context::active();
70 detail::spinlock_lock lk( wait_queue_splk_);
71 if ( ctx == owner_) {
72 throw lock_error(
73 std::make_error_code( std::errc::resource_deadlock_would_occur),
74 "boost fiber: a deadlock is detected");
75 } else if ( nullptr == owner_) {
76 owner_ = ctx;
77 }
78 lk.unlock();
79 // let other fiber release the lock
80 context::active()->yield();
81 return ctx == owner_;
82 }
83
84 void
85 timed_mutex::unlock() {
86 context * ctx = context::active();
87 detail::spinlock_lock lk( wait_queue_splk_);
88 if ( ctx != owner_) {
89 throw lock_error(
90 std::make_error_code( std::errc::operation_not_permitted),
91 "boost fiber: no privilege to perform the operation");
92 }
93 if ( ! wait_queue_.empty() ) {
94 context * ctx = & wait_queue_.front();
95 wait_queue_.pop_front();
96 owner_ = ctx;
97 context::active()->set_ready( ctx);
98 } else {
99 owner_ = nullptr;
100 return;
101 }
102 }
103
104 }}
105
106 #ifdef BOOST_HAS_ABI_HEADERS
107 # include BOOST_ABI_SUFFIX
108 #endif