| 500 | |
| 501 | |
| 502 | bool Pipe::Reader::close() |
| 503 | { |
| 504 | bool closed = false; |
| 505 | bool notify = false; |
| 506 | queue<Owned<Promise<string>>> reads; |
| 507 | |
| 508 | synchronized (data->lock) { |
| 509 | if (data->readEnd == Reader::OPEN) { |
| 510 | // Throw away outstanding data. |
| 511 | while (!data->writes.empty()) { |
| 512 | data->writes.pop(); |
| 513 | } |
| 514 | |
| 515 | // Extract the pending reads so we can fail them. |
| 516 | std::swap(data->reads, reads); |
| 517 | |
| 518 | closed = true; |
| 519 | data->readEnd = Reader::CLOSED; |
| 520 | |
| 521 | // Notify if write-end is still open! |
| 522 | notify = data->writeEnd == Writer::OPEN; |
| 523 | } |
| 524 | } |
| 525 | |
| 526 | // NOTE: We transition the promises outside the critical section |
| 527 | // to avoid triggering callbacks that try to reacquire the lock. |
| 528 | if (closed) { |
| 529 | while (!reads.empty()) { |
| 530 | reads.front()->fail("closed"); |
| 531 | reads.pop(); |
| 532 | } |
| 533 | |
| 534 | if (notify) { |
| 535 | data->readerClosure.set(Nothing()); |
| 536 | } else { |
| 537 | // This future is only satisifed when the reader is closed before |
| 538 | // the write-end of the pipe. In other cases, discard the promise |
| 539 | // in order to clear any associated callbacks. |
| 540 | data->readerClosure.discard(); |
| 541 | } |
| 542 | } |
| 543 | |
| 544 | return closed; |
| 545 | } |
| 546 | |
| 547 | |
| 548 | bool Pipe::Writer::write(string s) |