$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
From: igaztanaga_at_[hidden]
Date: 2008-05-27 12:39:26
Author: igaztanaga
Date: 2008-05-27 12:39:25 EDT (Tue, 27 May 2008)
New Revision: 45814
URL: http://svn.boost.org/trac/boost/changeset/45814
Log:
Ticket #1951
Text files modified: 
   trunk/boost/interprocess/sync/named_condition.hpp |    25 ++++++++++++++++---------               
   1 files changed, 16 insertions(+), 9 deletions(-)
Modified: trunk/boost/interprocess/sync/named_condition.hpp
==============================================================================
--- trunk/boost/interprocess/sync/named_condition.hpp	(original)
+++ trunk/boost/interprocess/sync/named_condition.hpp	2008-05-27 12:39:25 EDT (Tue, 27 May 2008)
@@ -146,23 +146,30 @@
    template <class Lock>
    void do_wait(Lock& lock)
    {  
+      //lock internal before unlocking external to avoid race with a notifier
+      scoped_lock<interprocess_mutex>     internal_lock(*this->mutex());
       lock_inverter<Lock> inverted_lock(lock);
-      //unlock internal first to avoid deadlock with near simultaneous waits
       scoped_lock<lock_inverter<Lock> >   external_unlock(inverted_lock);
-      scoped_lock<interprocess_mutex>     internal_lock(*this->mutex());
-      this->condition()->wait(internal_lock);
+
+      //unlock internal first to avoid deadlock with near simultaneous waits
+      scoped_lock<interprocess_mutex>     internal_unlock;
+      internal_lock.swap(internal_unlock);
+      this->condition()->wait(internal_unlock);
    }
 
    template <class Lock>
    bool do_timed_wait(Lock& lock, const boost::posix_time::ptime &abs_time)
    {
-      //unlock internal first to avoid deadlock with near simultaneous waits
-      lock_inverter<Lock> inverted_lock(lock);
-      scoped_lock<lock_inverter<Lock> >   external_unlock(inverted_lock);
+      //lock internal before unlocking external to avoid race with a notifier  
+      scoped_lock<interprocess_mutex>     internal_lock(*this->mutex(), abs_time);  
       if(!external_unlock) return false;
-      scoped_lock<interprocess_mutex>     internal_lock(*this->mutex(), abs_time);
-      if(!internal_lock) return false;
-      return this->condition()->timed_wait(internal_lock, abs_time);
+      lock_inverter<Lock> inverted_lock(lock);  
+      scoped_lock<lock_inverter<Lock> >   external_unlock(inverted_lock);  
+
+      //unlock internal first to avoid deadlock with near simultaneous waits  
+      scoped_lock<interprocess_mutex>     internal_unlock;  
+      internal_lock.swap(internal_unlock);  
+      return this->condition()->timed_wait(internal_unlock, abs_time);  
    }
    #endif