+ bool Wait( unsigned long timeout_millis );
+
+ void Signal();
+
+ void Broadcast();
+
+private:
+ int m_numWaiters;
+ wxMutex m_mutexNumWaiters;
+
+ wxMutex& m_mutex;
+
+ wxSemaphore m_semaphore;
+
+ DECLARE_NO_COPY_CLASS(wxConditionInternal)
+};
+
+wxConditionInternal::wxConditionInternal(wxMutex& mutex)
+ : m_mutex(mutex)
+{
+
+ m_numWaiters = 0;
+}
+
+void wxConditionInternal::Wait()
+{
+ // increment the number of waiters
+ m_mutexNumWaiters.Lock();
+ m_numWaiters++;
+ m_mutexNumWaiters.Unlock();
+
+ m_mutex.Unlock();
+
+ // a potential race condition can occur here
+ //
+ // after a thread increments nwaiters, and unlocks the mutex and before the
+ // semaphore.Wait() is called, if another thread can cause a signal to be
+ // generated
+ //
+ // this race condition is handled by using a semaphore and incrementing the
+ // semaphore only if 'nwaiters' is greater that zero since the semaphore,
+ // can 'remember' signals the race condition will not occur
+
+ // wait ( if necessary ) and decrement semaphore
+ m_semaphore.Wait();
+
+ m_mutex.Lock();
+}
+
+bool wxConditionInternal::Wait( unsigned long timeout_millis )
+{
+ m_mutexNumWaiters.Lock();
+ m_numWaiters++;
+ m_mutexNumWaiters.Unlock();
+
+ m_mutex.Unlock();
+
+ // a race condition can occur at this point in the code
+ //
+ // please see the comments in Wait(), for details
+
+ bool success = TRUE;
+
+ bool result = m_semaphore.Wait( timeout_millis );
+
+ if ( !result )