Boost logo

Boost-Commit :

From: anthony_at_[hidden]
Date: 2008-04-10 09:14:43


Author: anthonyw
Date: 2008-04-10 09:14:43 EDT (Thu, 10 Apr 2008)
New Revision: 44146
URL: http://svn.boost.org/trac/boost/changeset/44146

Log:
fix for notify problem in trac ticket #1803
Text files modified:
   trunk/boost/thread/win32/condition_variable.hpp | 64 +++++++++++++++++++++++++++++++++------
   1 files changed, 53 insertions(+), 11 deletions(-)

Modified: trunk/boost/thread/win32/condition_variable.hpp
==============================================================================
--- trunk/boost/thread/win32/condition_variable.hpp (original)
+++ trunk/boost/thread/win32/condition_variable.hpp 2008-04-10 09:14:43 EDT (Thu, 10 Apr 2008)
@@ -34,6 +34,12 @@
                 list_entry():
                     semaphore(0),count(0),notified(0)
                 {}
+
+ void release(unsigned count=1)
+ {
+ detail::win32::ReleaseSemaphore(semaphore,count,0);
+ }
+
             };
 
             BOOST_STATIC_CONSTANT(unsigned,generation_count=3);
@@ -77,7 +83,7 @@
                 {
                     detail::win32::ReleaseSemaphore(wake_sem,count_to_wake,0);
                 }
- detail::win32::ReleaseSemaphore(entry.semaphore,count_to_wake,0);
+ entry.release(count_to_wake);
                 entry.count=0;
                 dispose_entry(entry);
             }
@@ -124,6 +130,7 @@
             void start_wait_loop_first_time(relocker<lock_type>& locker,
                                             detail::win32::handle_manager& local_wake_sem)
             {
+ detail::interlocked_write_release(&total_count,total_count+1);
                 locker.unlock();
                 if(!wake_sem)
                 {
@@ -141,6 +148,15 @@
                     active_generation_count=1;
                 }
             }
+
+ void ensure_generation_present()
+ {
+ if(!generations[0].semaphore)
+ {
+ generations[0].semaphore=detail::win32::create_anonymous_semaphore(0,LONG_MAX);
+ BOOST_ASSERT(generations[0].semaphore);
+ }
+ }
             
             template<typename lock_type>
             void start_wait_loop(relocker<lock_type>& locker,
@@ -148,16 +164,11 @@
                                  detail::win32::handle_manager& sem)
             {
                 boost::mutex::scoped_lock internal_lock(internal_mutex);
- detail::interlocked_write_release(&total_count,total_count+1);
                 if(!local_wake_sem)
                 {
                     start_wait_loop_first_time(locker,local_wake_sem);
                 }
- if(!generations[0].semaphore)
- {
- generations[0].semaphore=detail::win32::create_anonymous_semaphore(0,LONG_MAX);
- BOOST_ASSERT(generations[0].semaphore);
- }
+ ensure_generation_present();
                 ++generations[0].count;
                 sem=detail::win32::duplicate_handle(generations[0].semaphore);
             }
@@ -222,15 +233,23 @@
                 if(detail::interlocked_read_acquire(&total_count))
                 {
                     boost::mutex::scoped_lock internal_lock(internal_mutex);
+ if(!total_count)
+ {
+ return;
+ }
                     detail::win32::ReleaseSemaphore(wake_sem,1,0);
+ detail::interlocked_write_release(&total_count,total_count-1);
+
+ unsigned waiting_count=0;
+
                     for(unsigned generation=active_generation_count;generation!=0;--generation)
                     {
                         list_entry& entry=generations[generation-1];
+ waiting_count+=entry.count;
                         if(entry.count)
                         {
- detail::interlocked_write_release(&total_count,total_count-1);
                             entry.notified=true;
- detail::win32::ReleaseSemaphore(entry.semaphore,1,0);
+ entry.release();
                             if(!--entry.count)
                             {
                                 dispose_entry(entry);
@@ -241,6 +260,11 @@
                             }
                         }
                     }
+ if(waiting_count<=total_count)
+ {
+ ensure_generation_present();
+ generations[0].release();
+ }
                 }
             }
         
@@ -265,9 +289,18 @@
     }
 
     class condition_variable:
- public detail::basic_condition_variable
+ private detail::basic_condition_variable
     {
+ private:
+ condition_variable(condition_variable&);
+ void operator=(condition_variable&);
     public:
+ condition_variable()
+ {}
+
+ using detail::basic_condition_variable::notify_one;
+ using detail::basic_condition_variable::notify_all;
+
         void wait(unique_lock<mutex>& m)
         {
             do_wait(m,detail::timeout::sentinel());
@@ -313,9 +346,18 @@
     };
     
     class condition_variable_any:
- public detail::basic_condition_variable
+ private detail::basic_condition_variable
     {
+ private:
+ condition_variable_any(condition_variable_any&);
+ void operator=(condition_variable_any&);
     public:
+ condition_variable_any()
+ {}
+
+ using detail::basic_condition_variable::notify_one;
+ using detail::basic_condition_variable::notify_all;
+
         template<typename lock_type>
         void wait(lock_type& m)
         {


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