| 189 | | if( !p_condvar->semaphore ) |
|---|
| 190 | | { |
|---|
| 191 | | /* PulseEvent() only works if none of the waiting threads is suspended. |
|---|
| 192 | | * This is particularily problematic under a debug session. |
|---|
| 193 | | * as documented in http://support.microsoft.com/kb/q173260/ */ |
|---|
| 194 | | PulseEvent( p_condvar->event ); |
|---|
| 195 | | } |
|---|
| 196 | | else if( p_condvar->i_win9x_cv == 1 ) |
|---|
| 197 | | { |
|---|
| 198 | | /* Wait for the gate to be open */ |
|---|
| 199 | | WaitForSingleObject( p_condvar->event, INFINITE ); |
|---|
| 200 | | |
|---|
| 201 | | if( p_condvar->i_waiting_threads ) |
|---|
| 202 | | { |
|---|
| 203 | | /* Using a semaphore exposes us to a race condition. It is |
|---|
| 204 | | * possible for another thread to start waiting on the semaphore |
|---|
| 205 | | * just after we signaled it and thus steal the signal. |
|---|
| 206 | | * We have to prevent new threads from entering the cond_wait(). */ |
|---|
| 207 | | ResetEvent( p_condvar->event ); |
|---|
| 208 | | |
|---|
| 209 | | /* A semaphore is used here because Win9x doesn't have |
|---|
| 210 | | * SignalObjectAndWait() and thus a race condition exists |
|---|
| 211 | | * during the time we release the mutex and the time we start |
|---|
| 212 | | * waiting on the event (more precisely, the signal can sometimes |
|---|
| 213 | | * be missed by the waiting thread if we use PulseEvent()). */ |
|---|
| 214 | | ReleaseSemaphore( p_condvar->semaphore, 1, 0 ); |
|---|
| 215 | | } |
|---|
| 216 | | } |
|---|
| 217 | | else |
|---|
| 218 | | { |
|---|
| 219 | | if( p_condvar->i_waiting_threads ) |
|---|
| 220 | | { |
|---|
| 221 | | ReleaseSemaphore( p_condvar->semaphore, 1, 0 ); |
|---|
| 222 | | |
|---|
| 223 | | /* Wait for the last thread to be awakened */ |
|---|
| 224 | | WaitForSingleObject( p_condvar->event, INFINITE ); |
|---|
| 225 | | } |
|---|
| 226 | | } |
|---|
| | 178 | /* PulseEvent() only works if none of the waiting threads is suspended. |
|---|
| | 179 | * This is particularily problematic under a debug session. |
|---|
| | 180 | * as documented in http://support.microsoft.com/kb/q173260/ */ |
|---|
| | 181 | PulseEvent( p_condvar->event ); |
|---|
| 278 | | if( !p_condvar->semaphore ) |
|---|
| 279 | | { |
|---|
| 280 | | /* Increase our wait count */ |
|---|
| 281 | | p_condvar->i_waiting_threads++; |
|---|
| 282 | | |
|---|
| 283 | | if( p_mutex->mutex ) |
|---|
| 284 | | { |
|---|
| 285 | | SignalObjectAndWait( p_mutex->mutex, p_condvar->event, |
|---|
| 286 | | INFINITE, FALSE ); |
|---|
| 287 | | } |
|---|
| 288 | | else |
|---|
| 289 | | { |
|---|
| 290 | | LeaveCriticalSection( &p_mutex->csection ); |
|---|
| 291 | | WaitForSingleObject( p_condvar->event, INFINITE ); |
|---|
| 292 | | } |
|---|
| 293 | | |
|---|
| 294 | | p_condvar->i_waiting_threads--; |
|---|
| 295 | | } |
|---|
| 296 | | else if( p_condvar->i_win9x_cv == 1 ) |
|---|
| 297 | | { |
|---|
| 298 | | int i_waiting_threads; |
|---|
| 299 | | |
|---|
| 300 | | /* Wait for the gate to be open */ |
|---|
| 301 | | WaitForSingleObject( p_condvar->event, INFINITE ); |
|---|
| 302 | | |
|---|
| 303 | | /* Increase our wait count */ |
|---|
| 304 | | p_condvar->i_waiting_threads++; |
|---|
| 305 | | |
|---|
| 306 | | LeaveCriticalSection( &p_mutex->csection ); |
|---|
| 307 | | WaitForSingleObject( p_condvar->semaphore, INFINITE ); |
|---|
| 308 | | |
|---|
| 309 | | /* Decrement and test must be atomic */ |
|---|
| 310 | | EnterCriticalSection( &p_condvar->csection ); |
|---|
| 311 | | |
|---|
| 312 | | /* Decrease our wait count */ |
|---|
| 313 | | i_waiting_threads = --p_condvar->i_waiting_threads; |
|---|
| 314 | | |
|---|
| 315 | | LeaveCriticalSection( &p_condvar->csection ); |
|---|
| 316 | | |
|---|
| 317 | | /* Reopen the gate if we were the last waiting thread */ |
|---|
| 318 | | if( !i_waiting_threads ) |
|---|
| 319 | | SetEvent( p_condvar->event ); |
|---|
| 320 | | } |
|---|
| 321 | | else |
|---|
| 322 | | { |
|---|
| 323 | | int i_waiting_threads; |
|---|
| 324 | | |
|---|
| 325 | | /* Increase our wait count */ |
|---|
| 326 | | p_condvar->i_waiting_threads++; |
|---|
| 327 | | |
|---|
| 328 | | LeaveCriticalSection( &p_mutex->csection ); |
|---|
| 329 | | WaitForSingleObject( p_condvar->semaphore, INFINITE ); |
|---|
| 330 | | |
|---|
| 331 | | /* Decrement and test must be atomic */ |
|---|
| 332 | | EnterCriticalSection( &p_condvar->csection ); |
|---|
| 333 | | |
|---|
| 334 | | /* Decrease our wait count */ |
|---|
| 335 | | i_waiting_threads = --p_condvar->i_waiting_threads; |
|---|
| 336 | | |
|---|
| 337 | | LeaveCriticalSection( &p_condvar->csection ); |
|---|
| 338 | | |
|---|
| 339 | | /* Signal that the last waiting thread just went through */ |
|---|
| 340 | | if( !i_waiting_threads ) |
|---|
| 341 | | SetEvent( p_condvar->event ); |
|---|
| 342 | | } |
|---|
| | 233 | /* Increase our wait count */ |
|---|
| | 234 | p_condvar->i_waiting_threads++; |
|---|
| | 235 | SignalObjectAndWait( p_mutex->mutex, p_condvar->event, INFINITE, FALSE ); |
|---|
| | 236 | p_condvar->i_waiting_threads--; |
|---|
| 406 | | if( !p_condvar->semaphore ) |
|---|
| 407 | | { |
|---|
| 408 | | /* Increase our wait count */ |
|---|
| 409 | | p_condvar->i_waiting_threads++; |
|---|
| 410 | | |
|---|
| 411 | | if( p_mutex->mutex ) |
|---|
| 412 | | { |
|---|
| 413 | | result = SignalObjectAndWait( p_mutex->mutex, p_condvar->event, |
|---|
| 414 | | delay_ms, FALSE ); |
|---|
| 415 | | } |
|---|
| 416 | | else |
|---|
| 417 | | { |
|---|
| 418 | | LeaveCriticalSection( &p_mutex->csection ); |
|---|
| 419 | | result = WaitForSingleObject( p_condvar->event, delay_ms ); |
|---|
| 420 | | } |
|---|
| 421 | | |
|---|
| 422 | | p_condvar->i_waiting_threads--; |
|---|
| 423 | | } |
|---|
| 424 | | else if( p_condvar->i_win9x_cv == 1 ) |
|---|
| 425 | | { |
|---|
| 426 | | int i_waiting_threads; |
|---|
| 427 | | |
|---|
| 428 | | /* Wait for the gate to be open */ |
|---|
| 429 | | result = WaitForSingleObject( p_condvar->event, delay_ms ); |
|---|
| 430 | | |
|---|
| 431 | | /* Increase our wait count */ |
|---|
| 432 | | p_condvar->i_waiting_threads++; |
|---|
| 433 | | |
|---|
| 434 | | LeaveCriticalSection( &p_mutex->csection ); |
|---|
| 435 | | if( !result ) |
|---|
| 436 | | { |
|---|
| 437 | | /* recaculate remaining delay */ |
|---|
| 438 | | delay_ms = (deadline - mdate())/1000; |
|---|
| 439 | | if( delay_ms < 0 ) |
|---|
| 440 | | delay_ms = 0; |
|---|
| 441 | | |
|---|
| 442 | | result = WaitForSingleObject( p_condvar->semaphore, delay_ms ); |
|---|
| 443 | | } |
|---|
| 444 | | |
|---|
| 445 | | /* Decrement and test must be atomic */ |
|---|
| 446 | | EnterCriticalSection( &p_condvar->csection ); |
|---|
| 447 | | |
|---|
| 448 | | /* Decrease our wait count */ |
|---|
| 449 | | i_waiting_threads = --p_condvar->i_waiting_threads; |
|---|
| 450 | | |
|---|
| 451 | | LeaveCriticalSection( &p_condvar->csection ); |
|---|
| 452 | | |
|---|
| 453 | | /* Reopen the gate if we were the last waiting thread */ |
|---|
| 454 | | if( !i_waiting_threads ) |
|---|
| 455 | | SetEvent( p_condvar->event ); |
|---|
| 456 | | } |
|---|
| 457 | | else |
|---|
| 458 | | { |
|---|
| 459 | | int i_waiting_threads; |
|---|
| 460 | | |
|---|
| 461 | | /* Increase our wait count */ |
|---|
| 462 | | p_condvar->i_waiting_threads++; |
|---|
| 463 | | |
|---|
| 464 | | LeaveCriticalSection( &p_mutex->csection ); |
|---|
| 465 | | result = WaitForSingleObject( p_condvar->semaphore, delay_ms ); |
|---|
| 466 | | |
|---|
| 467 | | /* Decrement and test must be atomic */ |
|---|
| 468 | | EnterCriticalSection( &p_condvar->csection ); |
|---|
| 469 | | |
|---|
| 470 | | /* Decrease our wait count */ |
|---|
| 471 | | i_waiting_threads = --p_condvar->i_waiting_threads; |
|---|
| 472 | | |
|---|
| 473 | | LeaveCriticalSection( &p_condvar->csection ); |
|---|
| 474 | | |
|---|
| 475 | | /* Signal that the last waiting thread just went through */ |
|---|
| 476 | | if( !i_waiting_threads ) |
|---|
| 477 | | SetEvent( p_condvar->event ); |
|---|
| 478 | | } |
|---|
| | 300 | /* Increase our wait count */ |
|---|
| | 301 | p_condvar->i_waiting_threads++; |
|---|
| | 302 | result = SignalObjectAndWait( p_mutex->mutex, p_condvar->event, |
|---|
| | 303 | delay_ms, FALSE ); |
|---|
| | 304 | p_condvar->i_waiting_threads--; |
|---|