sync: fix mem leak in oneshot on task migration (#1649)

When polling the task, the current waker is saved to the oneshot state.
When the handle is migrated to a new task and polled again, the waker
must be swaped from the old waker to the new waker. In some cases, there
is a potential for the old waker to leak.

This bug was caught by loom with the recently added memory leak
detection.

Backport of #1648.
This commit is contained in:
Carl Lerche
2019-10-10 12:47:53 -07:00
committed by GitHub
parent 39f369f686
commit 2117ce7bac
+5
View File
@@ -198,6 +198,8 @@ impl<T> Sender<T> {
state = State::unset_tx_task(&inner.state);
if state.is_closed() {
// Set the flag again so that the waker is released in drop
State::set_tx_task(&inner.state);
return Ok(Async::Ready(()));
} else {
unsafe { inner.drop_tx_task() };
@@ -363,6 +365,9 @@ impl<T> Inner<T> {
// Unset the task
state = State::unset_rx_task(&self.state);
if state.is_complete() {
// Set the flag again so that the waker is released in drop
State::set_rx_task(&self.state);
return match unsafe { self.consume_value() } {
Some(value) => Ok(Ready(value)),
None => Err(RecvError(())),