| 425 | typename T |
| 426 | > |
| 427 | bool pipe<T>:: |
| 428 | dequeue ( |
| 429 | T& item |
| 430 | ) |
| 431 | { |
| 432 | auto_mutex M(m); |
| 433 | ++dequeue_waiters; |
| 434 | |
| 435 | if (pipe_size == 0) |
| 436 | { |
| 437 | // notify wait_for_num_blocked_dequeues() |
| 438 | if (unblock_sig_waiters > 0) |
| 439 | unblock_sig.broadcast(); |
| 440 | |
| 441 | // notify any blocked enqueue_or_timeout() calls |
| 442 | if (enqueue_waiters > 0) |
| 443 | enqueue_sig.broadcast(); |
| 444 | } |
| 445 | |
| 446 | // wait until there is something in the pipe or we are disabled |
| 447 | while (pipe_size == 0 && enabled && dequeue_enabled && |
| 448 | !(pipe_max_size == 0 && first == 0 && last == 0) ) |
| 449 | dequeue_sig.wait(); |
| 450 | |
| 451 | if (enabled == false || dequeue_enabled == false) |
| 452 | { |
| 453 | --dequeue_waiters; |
| 454 | // let the destructor know we are unblocking |
| 455 | unblock_sig.broadcast(); |
| 456 | return false; |
| 457 | } |
| 458 | |
| 459 | exchange(item,data[first]); |
| 460 | |
| 461 | if (pipe_max_size > 0) |
| 462 | { |
| 463 | // set the appropriate values for first |
| 464 | first = (first+1)%pipe_max_size; |
| 465 | |
| 466 | --pipe_size; |
| 467 | } |
| 468 | else |
| 469 | { |
| 470 | // let the enqueue waiting on us know that we took the |
| 471 | // item out already. |
| 472 | last = 1; |
| 473 | } |
| 474 | |
| 475 | // wake up a call to enqueue() if there are any currently blocked |
| 476 | if (enqueue_waiters > 0) |
| 477 | enqueue_sig.broadcast(); |
| 478 | |
| 479 | --dequeue_waiters; |
| 480 | return true; |
| 481 | } |
| 482 | |
| 483 | // ---------------------------------------------------------------------------------------- |
| 484 | |