Yielding for fairness

This commit is contained in:
Stjepan Glavina 2020-09-01 04:53:48 +02:00
parent 8c68db78f6
commit d7536a669c
2 changed files with 29 additions and 0 deletions

View File

@ -15,6 +15,7 @@ readme = "README.md"
[dependencies]
concurrent-queue = "1.2.2"
event-listener = "2.4.0"
fastrand = "1.3.4"
futures-core = "0.3.5"
[dev-dependencies]

View File

@ -235,6 +235,10 @@ impl<T> Sender<T> {
let mut listener = None;
let mut msg = msg;
if fastrand::usize(..100) == 0 {
yield_now().await;
}
loop {
// Attempt to send a message.
match self.try_send(msg) {
@ -490,6 +494,10 @@ impl<T> Receiver<T> {
pub async fn recv(&self) -> Result<T, RecvError> {
let mut listener = None;
if fastrand::usize(..100) == 0 {
yield_now().await;
}
loop {
// Attempt to receive a message.
match self.try_recv() {
@ -850,3 +858,23 @@ impl fmt::Display for TryRecvError {
}
}
}
async fn yield_now() {
pub struct YieldNow(bool);
impl Future for YieldNow {
type Output = ();
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
if !self.0 {
self.0 = true;
cx.waker().wake_by_ref();
Poll::Pending
} else {
Poll::Ready(())
}
}
}
YieldNow(false).await
}