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);
|
assert_eq!(rx.recv(), 1);
|
||||||
} #[ignore(reason = "flaky on libnative")])
|
} #[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 {
|
} else {
|
||||||
// If the buffer has some space and the capacity isn't 0, then we
|
// 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());
|
assert!(state.buf.size() < state.buf.cap());
|
||||||
state.buf.enqueue(t);
|
state.buf.enqueue(t);
|
||||||
|
match mem::replace(&mut state.blocker, NoneBlocked) {
|
||||||
|
BlockedReceiver(task) => wakeup(task, guard),
|
||||||
|
NoneBlocked => {}
|
||||||
|
BlockedSender(..) => unreachable!(),
|
||||||
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue