- if( !p_condvar->semaphore )
- {
- /* Increase our wait count */
- p_condvar->i_waiting_threads++;
-
- if( p_mutex->mutex )
- {
- /* It is only possible to atomically release the mutex and
- * initiate the waiting on WinNT/2K/XP. Win9x doesn't have
- * SignalObjectAndWait(). */
- result = p_condvar->SignalObjectAndWait( p_mutex->mutex,
- p_condvar->event,
- delay_ms, FALSE );
- }
- else
- {
- LeaveCriticalSection( &p_mutex->csection );
- result = WaitForSingleObject( p_condvar->event, delay_ms );
- }
-
- p_condvar->i_waiting_threads--;
- }
- else if( p_condvar->i_win9x_cv == 1 )
- {
- int i_waiting_threads;
-
- /* Wait for the gate to be open */
- result = WaitForSingleObject( p_condvar->event, delay_ms );
-
- /* Increase our wait count */
- p_condvar->i_waiting_threads++;
-
- LeaveCriticalSection( &p_mutex->csection );
- if( !result )
- {
- /* recaculate remaining delay */
- delay_ms = (deadline - mdate())/1000;
- if( delay_ms < 0 )
- delay_ms = 0;
-
- result = WaitForSingleObject( p_condvar->semaphore, delay_ms );
- }
-
- /* Decrement and test must be atomic */
- EnterCriticalSection( &p_condvar->csection );
-
- /* Decrease our wait count */
- i_waiting_threads = --p_condvar->i_waiting_threads;
-
- LeaveCriticalSection( &p_condvar->csection );
-
- /* Reopen the gate if we were the last waiting thread */
- if( !i_waiting_threads )
- SetEvent( p_condvar->event );
- }
- else
- {
- int i_waiting_threads;
-
- /* Increase our wait count */
- p_condvar->i_waiting_threads++;
-
- LeaveCriticalSection( &p_mutex->csection );
- result = WaitForSingleObject( p_condvar->semaphore, delay_ms );
-
- /* Decrement and test must be atomic */
- EnterCriticalSection( &p_condvar->csection );
-
- /* Decrease our wait count */
- i_waiting_threads = --p_condvar->i_waiting_threads;
-
- LeaveCriticalSection( &p_condvar->csection );
-
- /* Signal that the last waiting thread just went through */
- if( !i_waiting_threads )
- SetEvent( p_condvar->event );
- }