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