-
Notifications
You must be signed in to change notification settings - Fork 341
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Replace select!/try_select! with Future::{race,try_race} (#405)
* init Future::select Signed-off-by: Yoshua Wuyts <yoshuawuyts@gmail.com> * implement Future::select Signed-off-by: Yoshua Wuyts <yoshuawuyts@gmail.com> * try_select Signed-off-by: Yoshua Wuyts <yoshuawuyts@gmail.com> * fixes Signed-off-by: Yoshua Wuyts <yoshuawuyts@gmail.com> * works Signed-off-by: Yoshua Wuyts <yoshuawuyts@gmail.com> * pass clippy Signed-off-by: Yoshua Wuyts <yoshuawuyts@gmail.com> * please clippy Signed-off-by: Yoshua Wuyts <yoshuawuyts@gmail.com> * implement feedback from stjepan Signed-off-by: Yoshua Wuyts <yoshuawuyts@gmail.com> * rename select to race Signed-off-by: Yoshua Wuyts <yoshuawuyts@gmail.com> * fmt Signed-off-by: Yoshua Wuyts <yoshuawuyts@gmail.com>
- Loading branch information
1 parent
3a2e6d5
commit 735fa69
Showing
5 changed files
with
234 additions
and
17 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
use std::pin::Pin; | ||
|
||
use async_macros::MaybeDone; | ||
use pin_project_lite::pin_project; | ||
|
||
use crate::task::{Context, Poll}; | ||
use std::future::Future; | ||
|
||
pin_project! { | ||
#[allow(missing_docs)] | ||
#[allow(missing_debug_implementations)] | ||
pub struct Race<L, R> | ||
where | ||
L: Future, | ||
R: Future<Output = L::Output> | ||
{ | ||
#[pin] left: MaybeDone<L>, | ||
#[pin] right: MaybeDone<R>, | ||
} | ||
} | ||
|
||
impl<L, R> Race<L, R> | ||
where | ||
L: Future, | ||
R: Future<Output = L::Output>, | ||
{ | ||
pub(crate) fn new(left: L, right: R) -> Self { | ||
Self { | ||
left: MaybeDone::new(left), | ||
right: MaybeDone::new(right), | ||
} | ||
} | ||
} | ||
|
||
impl<L, R> Future for Race<L, R> | ||
where | ||
L: Future, | ||
R: Future<Output = L::Output>, | ||
{ | ||
type Output = L::Output; | ||
|
||
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { | ||
let this = self.project(); | ||
|
||
let mut left = this.left; | ||
if Future::poll(Pin::new(&mut left), cx).is_ready() { | ||
return Poll::Ready(left.take().unwrap()); | ||
} | ||
|
||
let mut right = this.right; | ||
if Future::poll(Pin::new(&mut right), cx).is_ready() { | ||
return Poll::Ready(right.take().unwrap()); | ||
} | ||
|
||
Poll::Pending | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
use std::pin::Pin; | ||
|
||
use async_macros::MaybeDone; | ||
use pin_project_lite::pin_project; | ||
|
||
use crate::task::{Context, Poll}; | ||
use std::future::Future; | ||
|
||
pin_project! { | ||
#[allow(missing_docs)] | ||
#[allow(missing_debug_implementations)] | ||
pub struct TryRace<L, R> | ||
where | ||
L: Future, | ||
R: Future<Output = L::Output> | ||
{ | ||
#[pin] left: MaybeDone<L>, | ||
#[pin] right: MaybeDone<R>, | ||
} | ||
} | ||
|
||
impl<L, R> TryRace<L, R> | ||
where | ||
L: Future, | ||
R: Future<Output = L::Output>, | ||
{ | ||
pub(crate) fn new(left: L, right: R) -> Self { | ||
Self { | ||
left: MaybeDone::new(left), | ||
right: MaybeDone::new(right), | ||
} | ||
} | ||
} | ||
|
||
impl<L, R, T, E> Future for TryRace<L, R> | ||
where | ||
L: Future<Output = Result<T, E>>, | ||
R: Future<Output = L::Output>, | ||
{ | ||
type Output = L::Output; | ||
|
||
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { | ||
let this = self.project(); | ||
let mut left_errored = false; | ||
|
||
// Check if the left future is ready & successful. Continue if not. | ||
let mut left = this.left; | ||
if Future::poll(Pin::new(&mut left), cx).is_ready() { | ||
if left.as_ref().output().unwrap().is_ok() { | ||
return Poll::Ready(left.take().unwrap()); | ||
} else { | ||
left_errored = true; | ||
} | ||
} | ||
|
||
// Check if the right future is ready & successful. Return err if left | ||
// future also resolved to err. Continue if not. | ||
let mut right = this.right; | ||
let is_ready = Future::poll(Pin::new(&mut right), cx).is_ready(); | ||
if is_ready && (right.as_ref().output().unwrap().is_ok() || left_errored) { | ||
return Poll::Ready(right.take().unwrap()); | ||
} | ||
|
||
Poll::Pending | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters