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:
parent
e288fc6a99
commit
31eb00c022
2 changed files with 26 additions and 1 deletions
|
@ -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()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
|
@ -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(())
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue