Imported Upstream version 1.64.0
[platform/upstream/boost.git] / boost / fiber / condition_variable.hpp
index 0dca7ef..cd0e7cb 100644 (file)
@@ -45,8 +45,8 @@ class BOOST_FIBERS_DECL condition_variable_any {
 private:
     typedef context::wait_queue_t   wait_queue_t;
 
-    wait_queue_t        wait_queue_{};
     detail::spinlock    wait_queue_splk_{};
+    wait_queue_t        wait_queue_{};
 
 public:
     condition_variable_any() = default;
@@ -64,22 +64,16 @@ public:
 
     template< typename LockType >
     void wait( LockType & lt) {
-        context * ctx = context::active();
+        context * active_ctx = context::active();
         // atomically call lt.unlock() and block on *this
         // store this fiber in waiting-queue
-        detail::spinlock_lock lk( wait_queue_splk_);
-        BOOST_ASSERT( ! ctx->wait_is_linked() );
-        ctx->wait_link( wait_queue_);
+        detail::spinlock_lock lk{ wait_queue_splk_ };
+        BOOST_ASSERT( ! active_ctx->wait_is_linked() );
+        active_ctx->wait_link( wait_queue_);
         // unlock external lt
         lt.unlock();
         // suspend this fiber
-        ctx->suspend( lk);
-        // relock local lk
-        lk.lock();
-        // remove from waiting-queue
-        ctx->wait_unlink();
-        // unlock local lk
-        lk.unlock();
+        active_ctx->suspend( lk);
         // relock external again before returning
         try {
             lt.lock();
@@ -87,7 +81,7 @@ public:
             std::terminate();
         }
         // post-conditions
-        BOOST_ASSERT( ! ctx->wait_is_linked() );
+        BOOST_ASSERT( ! active_ctx->wait_is_linked() );
     }
 
     template< typename LockType, typename Pred >
@@ -99,27 +93,26 @@ public:
 
     template< typename LockType, typename Clock, typename Duration >
     cv_status wait_until( LockType & lt, std::chrono::time_point< Clock, Duration > const& timeout_time_) {
+        context * active_ctx = context::active();
         cv_status status = cv_status::no_timeout;
-        std::chrono::steady_clock::time_point timeout_time(
-                detail::convert( timeout_time_) );
-        context * ctx = context::active();
+        std::chrono::steady_clock::time_point timeout_time = detail::convert( timeout_time_);
         // atomically call lt.unlock() and block on *this
         // store this fiber in waiting-queue
-        detail::spinlock_lock lk( wait_queue_splk_);
-        BOOST_ASSERT( ! ctx->wait_is_linked() );
-        ctx->wait_link( wait_queue_);
+        detail::spinlock_lock lk{ wait_queue_splk_ };
+        BOOST_ASSERT( ! active_ctx->wait_is_linked() );
+        active_ctx->wait_link( wait_queue_);
         // unlock external lt
         lt.unlock();
         // suspend this fiber
-        if ( ! ctx->wait_until( timeout_time, lk) ) {
+        if ( ! active_ctx->wait_until( timeout_time, lk) ) {
             status = cv_status::timeout;
+            // relock local lk
+            lk.lock();
+            // remove from waiting-queue
+            wait_queue_.remove( * active_ctx);
+            // unlock local lk
+            lk.unlock();
         }
-        // relock local lk
-        lk.lock();
-        // remove from waiting-queue
-        ctx->wait_unlink();
-        // unlock local lk
-        lk.unlock();
         // relock external again before returning
         try {
             lt.lock();
@@ -127,7 +120,7 @@ public:
             std::terminate();
         }
         // post-conditions
-        BOOST_ASSERT( ! ctx->wait_is_linked() );
+        BOOST_ASSERT( ! active_ctx->wait_is_linked() );
         return status;
     }