]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/fiber/src/recursive_mutex.cpp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / libs / fiber / src / recursive_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/recursive_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 void
23 recursive_mutex::lock() {
24 while ( true) {
25 context * active_ctx = context::active();
26 // store this fiber in order to be notified later
27 detail::spinlock_lock lk{ wait_queue_splk_ };
28 if ( active_ctx == owner_) {
29 ++count_;
30 return;
31 } else if ( nullptr == owner_) {
32 owner_ = active_ctx;
33 count_ = 1;
34 return;
35 }
36 BOOST_ASSERT( ! active_ctx->wait_is_linked() );
37 active_ctx->wait_link( wait_queue_);
38 // suspend this fiber
39 active_ctx->suspend( lk);
40 BOOST_ASSERT( ! active_ctx->wait_is_linked() );
41 }
42 }
43
44 bool
45 recursive_mutex::try_lock() noexcept {
46 context * active_ctx = context::active();
47 detail::spinlock_lock lk{ wait_queue_splk_ };
48 if ( nullptr == owner_) {
49 owner_ = active_ctx;
50 count_ = 1;
51 } else if ( active_ctx == owner_) {
52 ++count_;
53 }
54 lk.unlock();
55 // let other fiber release the lock
56 context::active()->yield();
57 return active_ctx == owner_;
58 }
59
60 void
61 recursive_mutex::unlock() {
62 context * active_ctx = context::active();
63 detail::spinlock_lock lk( wait_queue_splk_);
64 if ( BOOST_UNLIKELY( active_ctx != owner_) ) {
65 throw lock_error(
66 std::make_error_code( std::errc::operation_not_permitted),
67 "boost fiber: no privilege to perform the operation");
68 }
69 if ( 0 == --count_) {
70 owner_ = nullptr;
71 if ( ! wait_queue_.empty() ) {
72 context * ctx = & wait_queue_.front();
73 wait_queue_.pop_front();
74 active_ctx->schedule( ctx);
75 }
76 }
77 }
78
79 }}
80
81 #ifdef BOOST_HAS_ABI_HEADERS
82 # include BOOST_ABI_SUFFIX
83 #endif