]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/fiber/src/mutex.cpp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / libs / fiber / src / mutex.cpp
CommitLineData
7c673cae
FG
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
20namespace boost {
21namespace fibers {
22
23void
24mutex::lock() {
b32b8144
FG
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 } else if ( nullptr == owner_) {
34 owner_ = active_ctx;
35 return;
36 }
37 BOOST_ASSERT( ! active_ctx->wait_is_linked() );
38 active_ctx->wait_link( wait_queue_);
39 // suspend this fiber
40 active_ctx->suspend( lk);
41 BOOST_ASSERT( ! active_ctx->wait_is_linked() );
7c673cae 42 }
7c673cae
FG
43}
44
45bool
46mutex::try_lock() {
b32b8144
FG
47 context * active_ctx = context::active();
48 detail::spinlock_lock lk{ wait_queue_splk_ };
49 if ( BOOST_UNLIKELY( active_ctx == owner_) ) {
50 throw lock_error{
7c673cae 51 std::make_error_code( std::errc::resource_deadlock_would_occur),
b32b8144 52 "boost fiber: a deadlock is detected" };
7c673cae 53 } else if ( nullptr == owner_) {
b32b8144 54 owner_ = active_ctx;
7c673cae
FG
55 }
56 lk.unlock();
57 // let other fiber release the lock
b32b8144
FG
58 active_ctx->yield();
59 return active_ctx == owner_;
7c673cae
FG
60}
61
62void
63mutex::unlock() {
b32b8144
FG
64 context * active_ctx = context::active();
65 detail::spinlock_lock lk{ wait_queue_splk_ };
66 if ( BOOST_UNLIKELY( active_ctx != owner_) ) {
67 throw lock_error{
7c673cae 68 std::make_error_code( std::errc::operation_not_permitted),
b32b8144 69 "boost fiber: no privilege to perform the operation" };
7c673cae 70 }
b32b8144 71 owner_ = nullptr;
7c673cae
FG
72 if ( ! wait_queue_.empty() ) {
73 context * ctx = & wait_queue_.front();
74 wait_queue_.pop_front();
b32b8144 75 active_ctx->schedule( ctx);
7c673cae
FG
76 }
77}
78
79}}
80
81#ifdef BOOST_HAS_ABI_HEADERS
82# include BOOST_ABI_SUFFIX
83#endif