mirror of
https://github.com/rust-lang/rust.git
synced 2026-05-08 09:38:26 +03:00
sync: Ensure try_send() wakes up receivers
This branch of try_send() just forgot to wake up any receiver waiting for data. Closes #15761
This commit is contained in:
@@ -2098,4 +2098,23 @@ fn recv(rx: Receiver<Box<int>>, i: int) {
|
||||
});
|
||||
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()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -218,9 +218,15 @@ pub fn try_send(&self, t: T) -> Result<(), super::TrySendError<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(())
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user