]> git.proxmox.com Git - ceph.git/blobdiff - ceph/src/boost/libs/fiber/src/timed_mutex.cpp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / libs / fiber / src / timed_mutex.cpp
index e9addae4317f69333be0c6862c8fe19e06a6f62d..12750369fb15d1e43ee94ec13400d15de58f50b7 100644 (file)
@@ -21,83 +21,102 @@ namespace fibers {
 
 bool
 timed_mutex::try_lock_until_( std::chrono::steady_clock::time_point const& timeout_time) noexcept {
-    if ( std::chrono::steady_clock::now() > timeout_time) {
-        return false;
+    while ( true) {
+        if ( std::chrono::steady_clock::now() > timeout_time) {
+            return false;
+        }
+        context * active_ctx = context::active();
+        // store this fiber in order to be notified later
+        detail::spinlock_lock lk{ wait_queue_splk_ };
+        if ( nullptr == owner_) {
+            owner_ = active_ctx;
+            return true;
+        }
+        BOOST_ASSERT( ! active_ctx->wait_is_linked() );
+        active_ctx->wait_link( wait_queue_);
+        intrusive_ptr_add_ref( active_ctx);
+        active_ctx->twstatus.store( reinterpret_cast< std::intptr_t >( this), std::memory_order_release);
+        // suspend this fiber until notified or timed-out
+        if ( ! active_ctx->wait_until( timeout_time, lk) ) {
+            // remove fiber from wait-queue 
+            lk.lock();
+            wait_queue_.remove( * active_ctx);
+            return false;
+        }
+        BOOST_ASSERT( ! active_ctx->wait_is_linked() );
     }
-    context * ctx = context::active();
-    // store this fiber in order to be notified later
-    detail::spinlock_lock lk( wait_queue_splk_);
-    if ( nullptr == owner_) {
-        owner_ = ctx;
-        return true;
-    }
-    BOOST_ASSERT( ! ctx->wait_is_linked() );
-    ctx->wait_link( wait_queue_);
-    // suspend this fiber until notified or timed-out
-    if ( ! context::active()->wait_until( timeout_time, lk) ) {
-        // remove fiber from wait-queue 
-        lk.lock();
-        ctx->wait_unlink();
-        return false;
-    }
-    BOOST_ASSERT( ! ctx->wait_is_linked() );
-    return true;
 }
 
 void
 timed_mutex::lock() {
-    context * ctx = context::active();
-    // store this fiber in order to be notified later
-    detail::spinlock_lock lk( wait_queue_splk_);
-    if ( ctx == owner_) {
-        throw lock_error(
-                std::make_error_code( std::errc::resource_deadlock_would_occur),
-                "boost fiber: a deadlock is detected");
-    } else if ( nullptr == owner_) {
-        owner_ = ctx;
-        return;
+    while ( true) {
+        context * active_ctx = context::active();
+        // store this fiber in order to be notified later
+        detail::spinlock_lock lk{ wait_queue_splk_ };
+        if ( BOOST_UNLIKELY( active_ctx == owner_) ) {
+            throw lock_error{
+                    std::make_error_code( std::errc::resource_deadlock_would_occur),
+                    "boost fiber: a deadlock is detected" };
+        } else if ( nullptr == owner_) {
+            owner_ = active_ctx;
+            return;
+        }
+        BOOST_ASSERT( ! active_ctx->wait_is_linked() );
+        active_ctx->wait_link( wait_queue_);
+        active_ctx->twstatus.store( static_cast< std::intptr_t >( 0), std::memory_order_release);
+        // suspend this fiber
+        active_ctx->suspend( lk);
+        BOOST_ASSERT( ! active_ctx->wait_is_linked() );
     }
-    BOOST_ASSERT( ! ctx->wait_is_linked() );
-    ctx->wait_link( wait_queue_);
-    // suspend this fiber
-    ctx->suspend( lk);
-    BOOST_ASSERT( ! ctx->wait_is_linked() );
 }
 
 bool
 timed_mutex::try_lock() {
-    context * ctx = context::active();
-    detail::spinlock_lock lk( wait_queue_splk_);
-    if ( ctx == owner_) {
-        throw lock_error(
+    context * active_ctx = context::active();
+    detail::spinlock_lock lk{ wait_queue_splk_ };
+    if ( BOOST_UNLIKELY( active_ctx == owner_) ) {
+        throw lock_error{
                 std::make_error_code( std::errc::resource_deadlock_would_occur),
-                "boost fiber: a deadlock is detected");
+                "boost fiber: a deadlock is detected" };
     } else if ( nullptr == owner_) {
-        owner_ = ctx;
+        owner_ = active_ctx;
     }
     lk.unlock();
     // let other fiber release the lock
-    context::active()->yield();
-    return ctx == owner_;
+    active_ctx->yield();
+    return active_ctx == owner_;
 }
 
 void
 timed_mutex::unlock() {
-    context * ctx = context::active();
-    detail::spinlock_lock lk( wait_queue_splk_);
-    if ( ctx != owner_) {
-        throw lock_error(
+    context * active_ctx = context::active();
+    detail::spinlock_lock lk{ wait_queue_splk_ };
+    if ( BOOST_UNLIKELY( active_ctx != owner_) ) {
+        throw lock_error{
                 std::make_error_code( std::errc::operation_not_permitted),
-                "boost fiber: no  privilege to perform the operation");
+                "boost fiber: no  privilege to perform the operation" };
     }
+    owner_ = nullptr;
     if ( ! wait_queue_.empty() ) {
         context * ctx = & wait_queue_.front();
         wait_queue_.pop_front();
-        owner_ = ctx;
-        context::active()->set_ready( ctx);
-    } else {
-        owner_ = nullptr;
-        return;
+        std::intptr_t expected = reinterpret_cast< std::intptr_t >( this);
+        if ( ctx->twstatus.compare_exchange_strong( expected, static_cast< std::intptr_t >( -1), std::memory_order_acq_rel) ) {
+            // notify before timeout
+            intrusive_ptr_release( ctx);
+            // notify context
+            active_ctx->schedule( ctx);
+        } else if ( static_cast< std::intptr_t >( 0) == expected) {
+            // no timed-wait op.
+            // notify context
+            active_ctx->schedule( ctx);
+        } else {
+            // timed-wait op.
+            // expected == -1: notify after timeout, same timed-wait op.
+            // expected == <any>: notify after timeout, another timed-wait op. was already started
+            intrusive_ptr_release( ctx);
+            // re-schedule next
+        }
     }
 }