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)
7 #include "boost/fiber/timed_mutex.hpp"
12 #include "boost/fiber/exceptions.hpp"
13 #include "boost/fiber/scheduler.hpp"
15 #ifdef BOOST_HAS_ABI_HEADERS
16 # include BOOST_ABI_PREFIX
23 timed_mutex::try_lock_until_( std::chrono::steady_clock::time_point
const& timeout_time
) noexcept
{
25 if ( std::chrono::steady_clock::now() > timeout_time
) {
28 context
* active_ctx
= context::active();
29 // store this fiber in order to be notified later
30 detail::spinlock_lock lk
{ wait_queue_splk_
};
31 if ( nullptr == owner_
) {
35 BOOST_ASSERT( ! active_ctx
->wait_is_linked() );
36 active_ctx
->wait_link( wait_queue_
);
37 active_ctx
->twstatus
.store( reinterpret_cast< std::intptr_t >( this), std::memory_order_release
);
38 // suspend this fiber until notified or timed-out
39 if ( ! active_ctx
->wait_until( timeout_time
, lk
) ) {
40 // remove fiber from wait-queue
42 wait_queue_
.remove( * active_ctx
);
45 BOOST_ASSERT( ! active_ctx
->wait_is_linked() );
52 context
* active_ctx
= context::active();
53 // store this fiber in order to be notified later
54 detail::spinlock_lock lk
{ wait_queue_splk_
};
55 if ( BOOST_UNLIKELY( active_ctx
== owner_
) ) {
57 std::make_error_code( std::errc::resource_deadlock_would_occur
),
58 "boost fiber: a deadlock is detected" };
60 if ( nullptr == owner_
) {
64 BOOST_ASSERT( ! active_ctx
->wait_is_linked() );
65 active_ctx
->wait_link( wait_queue_
);
66 active_ctx
->twstatus
.store( static_cast< std::intptr_t >( 0), std::memory_order_release
);
68 active_ctx
->suspend( lk
);
69 BOOST_ASSERT( ! active_ctx
->wait_is_linked() );
74 timed_mutex::try_lock() {
75 context
* active_ctx
= context::active();
76 detail::spinlock_lock lk
{ wait_queue_splk_
};
77 if ( BOOST_UNLIKELY( active_ctx
== owner_
) ) {
79 std::make_error_code( std::errc::resource_deadlock_would_occur
),
80 "boost fiber: a deadlock is detected" };
82 if ( nullptr == owner_
) {
86 // let other fiber release the lock
88 return active_ctx
== owner_
;
92 timed_mutex::unlock() {
93 context
* active_ctx
= context::active();
94 detail::spinlock_lock lk
{ wait_queue_splk_
};
95 if ( BOOST_UNLIKELY( active_ctx
!= owner_
) ) {
97 std::make_error_code( std::errc::operation_not_permitted
),
98 "boost fiber: no privilege to perform the operation" };
101 if ( ! wait_queue_
.empty() ) {
102 context
* ctx
= & wait_queue_
.front();
103 wait_queue_
.pop_front();
104 auto expected
= reinterpret_cast< std::intptr_t >( this);
105 if ( ctx
->twstatus
.compare_exchange_strong( expected
, static_cast< std::intptr_t >( -1), std::memory_order_acq_rel
) ) {
107 active_ctx
->schedule( ctx
);
108 } else if ( static_cast< std::intptr_t >( 0) == expected
) {
111 active_ctx
->schedule( ctx
);
118 #ifdef BOOST_HAS_ABI_HEADERS
119 # include BOOST_ABI_SUFFIX