Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r86477 - trunk/boost/sync/detail/condition_variables
From: andrey.semashev_at_[hidden]
Date: 2013-10-27 09:07:25


Author: andysem
Date: 2013-10-27 09:07:25 EDT (Sun, 27 Oct 2013)
New Revision: 86477
URL: http://svn.boost.org/trac/boost/changeset/86477

Log:
Fixed total waiter count updates.

Text files modified:
   trunk/boost/sync/detail/condition_variables/basic_condition_variable_windows.hpp | 34 ++++++++++++++++++++++++++--------
   1 files changed, 26 insertions(+), 8 deletions(-)

Modified: trunk/boost/sync/detail/condition_variables/basic_condition_variable_windows.hpp
==============================================================================
--- trunk/boost/sync/detail/condition_variables/basic_condition_variable_windows.hpp Sun Oct 27 08:28:55 2013 (r86476)
+++ trunk/boost/sync/detail/condition_variables/basic_condition_variable_windows.hpp 2013-10-27 09:07:25 EDT (Sun, 27 Oct 2013) (r86477)
@@ -329,7 +329,7 @@
                     --state->m_waiter_count;
                     if (state->m_notify_count > 0)
                         --state->m_notify_count;
- interlocked_write_release(&m_total_waiter_count, m_total_waiter_count - 1);
+ update_total_waiter_count();
                 }
                 BOOST_SYNC_DETAIL_THROW(wait_error, (err)("condition_variable wait failed in WaitForSingleObject"));
             }
@@ -337,9 +337,9 @@
             boost::sync::lock_guard< mutex_type > internal_lock(m_internal_mutex);
             if (state->m_notify_count > 0)
             {
+ // Total waiter count is already actual here (see wake_waiters)
                 --state->m_notify_count;
                 --state->m_waiter_count;
- interlocked_write_release(&m_total_waiter_count, m_total_waiter_count - 1);
                 return;
             }
         }
@@ -360,9 +360,9 @@
                     boost::sync::lock_guard< mutex_type > internal_lock(m_internal_mutex);
                     if (state->m_notify_count > 0)
                     {
+ // Total waiter count is already actual here (see wake_waiters)
                         --state->m_notify_count;
                         --state->m_waiter_count;
- interlocked_write_release(&m_total_waiter_count, m_total_waiter_count - 1);
                         return sync::cv_status::no_timeout;
                     }
                 }
@@ -380,7 +380,7 @@
                         --state->m_waiter_count;
                         if (state->m_notify_count > 0)
                             --state->m_notify_count;
- interlocked_write_release(&m_total_waiter_count, m_total_waiter_count - 1);
+ update_total_waiter_count();
                     }
                     BOOST_SYNC_DETAIL_THROW(wait_error, (err)("condition_variable timed_wait failed in WaitForSingleObject"));
                 }
@@ -389,12 +389,13 @@
 
         boost::sync::lock_guard< mutex_type > internal_lock(m_internal_mutex);
         --state->m_waiter_count;
- interlocked_write_release(&m_total_waiter_count, m_total_waiter_count - 1);
         if (state->m_notify_count > 0)
         {
+ // Total waiter count is already actual here (see wake_waiters)
             --state->m_notify_count;
             return sync::cv_status::no_timeout;
         }
+ update_total_waiter_count();
         return sync::cv_status::timeout;
     }
 
@@ -415,7 +416,7 @@
                     --state->m_waiter_count;
                     if (state->m_notify_count > 0)
                         --state->m_notify_count;
- interlocked_write_release(&m_total_waiter_count, m_total_waiter_count - 1);
+ update_total_waiter_count();
                 }
                 BOOST_SYNC_DETAIL_THROW(wait_error, (err)("condition_variable timed_wait failed in WaitForMultipleObjects"));
             }
@@ -427,9 +428,9 @@
                     boost::sync::lock_guard< mutex_type > internal_lock(m_internal_mutex);
                     if (state->m_notify_count > 0)
                     {
+ // Total waiter count is already actual here (see wake_waiters)
                         --state->m_notify_count;
                         --state->m_waiter_count;
- interlocked_write_release(&m_total_waiter_count, m_total_waiter_count - 1);
                         return sync::cv_status::no_timeout;
                     }
                 }
@@ -439,12 +440,13 @@
                 {
                     boost::sync::lock_guard< mutex_type > internal_lock(m_internal_mutex);
                     --state->m_waiter_count;
- interlocked_write_release(&m_total_waiter_count, m_total_waiter_count - 1);
                     if (state->m_notify_count > 0)
                     {
+ // Total waiter count is already actual here (see wake_waiters)
                         --state->m_notify_count;
                         return sync::cv_status::no_timeout;
                     }
+ update_total_waiter_count();
                     return sync::cv_status::timeout;
                 }
                 break;
@@ -454,6 +456,22 @@
             }
         }
     }
+
+ void update_total_waiter_count() BOOST_NOEXCEPT
+ {
+ long total_waiter_count = 0;
+ if (waiter_state* p = m_notify_state)
+ {
+ waiter_state* const end = p;
+ do
+ {
+ total_waiter_count += p->m_waiter_count;
+ p = p->m_next;
+ }
+ while (p != end);
+ }
+ interlocked_write_release(&m_total_waiter_count, total_waiter_count);
+ }
 };
 
 } // namespace windows


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk