summaryrefslogtreecommitdiff
path: root/core/ops.rs
diff options
context:
space:
mode:
authorDivy Srivastava <dj.srivastava23@gmail.com>2022-09-06 23:08:37 +0530
committerGitHub <noreply@github.com>2022-09-06 23:08:37 +0530
commitd2a408f452db1157a1e6a14810bd1f03fc431d9d (patch)
tree66c45829a78cb3c6cd6e875cca65ce26384fe50d /core/ops.rs
parentc0a684c14ed70717e18b528bb8f366eb593636a7 (diff)
perf(runtime): short-circuit `queue_async_op` for Poll::Ready (#15773)
Diffstat (limited to 'core/ops.rs')
-rw-r--r--core/ops.rs14
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).