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