diff options
Diffstat (limited to 'boost/fiber/condition_variable.hpp')
-rw-r--r-- | boost/fiber/condition_variable.hpp | 47 |
1 files changed, 20 insertions, 27 deletions
diff --git a/boost/fiber/condition_variable.hpp b/boost/fiber/condition_variable.hpp index 0dca7ef6a0..cd0e7cb022 100644 --- a/boost/fiber/condition_variable.hpp +++ b/boost/fiber/condition_variable.hpp @@ -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; } |