diff options
author | Divy Srivastava <dj.srivastava23@gmail.com> | 2022-09-06 23:08:37 +0530 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-09-06 23:08:37 +0530 |
commit | d2a408f452db1157a1e6a14810bd1f03fc431d9d (patch) | |
tree | 66c45829a78cb3c6cd6e875cca65ce26384fe50d /core/ops.rs | |
parent | c0a684c14ed70717e18b528bb8f366eb593636a7 (diff) |
perf(runtime): short-circuit `queue_async_op` for Poll::Ready (#15773)
Diffstat (limited to 'core/ops.rs')
-rw-r--r-- | core/ops.rs | 14 |
1 files changed, 11 insertions, 3 deletions
diff --git a/core/ops.rs b/core/ops.rs index d22a703bd..c14fcdd7b 100644 --- a/core/ops.rs +++ b/core/ops.rs @@ -28,17 +28,25 @@ use std::task::Poll; /// turn of the event loop, which is too late for certain ops. pub struct OpCall<T>(MaybeDone<Pin<Box<dyn Future<Output = T>>>>); +pub enum EagerPollResult<T> { + Ready(T), + Pending(OpCall<T>), +} + impl<T> OpCall<T> { /// Wraps a future, and polls the inner future immediately. /// This should be the default choice for ops. - pub fn eager(fut: impl Future<Output = T> + 'static) -> Self { + pub fn eager(fut: impl Future<Output = T> + 'static) -> EagerPollResult<T> { let boxed = Box::pin(fut) as Pin<Box<dyn Future<Output = T>>>; let mut inner = maybe_done(boxed); let waker = noop_waker(); let mut cx = Context::from_waker(&waker); let mut pinned = Pin::new(&mut inner); - let _ = pinned.as_mut().poll(&mut cx); - Self(inner) + let poll = pinned.as_mut().poll(&mut cx); + match poll { + Poll::Ready(_) => EagerPollResult::Ready(pinned.take_output().unwrap()), + _ => EagerPollResult::Pending(Self(inner)), + } } /// Wraps a future; the inner future is polled the usual way (lazily). |