diff options
| author | Alex Crichton <alex@alexcrichton.com> | 2014-07-17 17:23:38 -0700 |
|---|---|---|
| committer | Alex Crichton <alex@alexcrichton.com> | 2014-07-17 18:32:25 -0700 |
| commit | 31eb00c022aba208921046cdec046f77a96ec98c (patch) | |
| tree | 8f85973a73a7078c9bd276892854ea40c33eec76 /src/libsync | |
| parent | e288fc6a996562c5e4aca46e22c1da46eb3d086b (diff) | |
| download | rust-31eb00c022aba208921046cdec046f77a96ec98c.tar.gz rust-31eb00c022aba208921046cdec046f77a96ec98c.zip | |
sync: Ensure try_send() wakes up receivers
This branch of try_send() just forgot to wake up any receiver waiting for data. Closes #15761
Diffstat (limited to 'src/libsync')
| -rw-r--r-- | src/libsync/comm/mod.rs | 19 | ||||
| -rw-r--r-- | src/libsync/comm/sync.rs | 8 |
2 files changed, 26 insertions, 1 deletions
diff --git a/src/libsync/comm/mod.rs b/src/libsync/comm/mod.rs index e9a303634fe..2aec3952125 100644 --- a/src/libsync/comm/mod.rs +++ b/src/libsync/comm/mod.rs @@ -2098,4 +2098,23 @@ mod sync_tests { }); assert_eq!(rx.recv(), 1); } #[ignore(reason = "flaky on libnative")]) + + test!(fn issue_15761() { + fn repro() { + let (tx1, rx1) = sync_channel::<()>(3); + let (tx2, rx2) = sync_channel::<()>(3); + + spawn(proc() { + rx1.recv(); + tx2.try_send(()).unwrap(); + }); + + tx1.try_send(()).unwrap(); + rx2.recv(); + } + + for _ in range(0u, 100) { + repro() + } + }) } diff --git a/src/libsync/comm/sync.rs b/src/libsync/comm/sync.rs index cc3c2197c13..1d5a7d6ed9f 100644 --- a/src/libsync/comm/sync.rs +++ b/src/libsync/comm/sync.rs @@ -218,9 +218,15 @@ impl<T: Send> Packet<T> { } } else { // If the buffer has some space and the capacity isn't 0, then we - // just enqueue the data for later retrieval. + // just enqueue the data for later retrieval, ensuring to wake up + // any blocked receiver if there is one. assert!(state.buf.size() < state.buf.cap()); state.buf.enqueue(t); + match mem::replace(&mut state.blocker, NoneBlocked) { + BlockedReceiver(task) => wakeup(task, guard), + NoneBlocked => {} + BlockedSender(..) => unreachable!(), + } Ok(()) } } |
