/rust/registry/src/index.crates.io-1949cf8c6b5b557f/reblessive-0.4.3/src/stack/runner.rs
Line | Count | Source |
1 | | use std::{ |
2 | | future::Future, |
3 | | marker::PhantomData, |
4 | | pin::Pin, |
5 | | task::{Context, Poll}, |
6 | | }; |
7 | | |
8 | | use crate::{stub_waker, Stack}; |
9 | | |
10 | | use super::StackState; |
11 | | |
12 | | /// Struct returned by [`Stack::enter`] determines how futures should be ran. |
13 | | pub struct Runner<'a, R> { |
14 | | pub(crate) stack: &'a Stack, |
15 | | pub(crate) _marker: PhantomData<R>, |
16 | | } |
17 | | |
18 | | impl<'a, R> Runner<'a, R> { |
19 | | /// Run the spawned future for a single step, returning none if a future either completed or |
20 | | /// spawned a new future onto the stack. Will return some if the root future is finished. |
21 | | /// |
22 | | /// This function supports sleeping or taking ownership of the waker allowing it to be used |
23 | | /// with external async runtimes. |
24 | 0 | pub fn step_async(&mut self) -> StepFuture<'a, R> { |
25 | 0 | StepFuture { |
26 | 0 | stack: self.stack, |
27 | 0 | _marker: PhantomData, |
28 | 0 | } |
29 | 0 | } |
30 | | |
31 | | /// Drive the stack until it completes. |
32 | | /// |
33 | | /// This function supports cloning and awakening allowing it to be used with external async |
34 | | /// runtimes |
35 | 0 | pub fn finish_async(&mut self) -> FinishFuture<'a, R> { |
36 | 0 | FinishFuture { |
37 | 0 | stack: self.stack, |
38 | 0 | _marker: PhantomData, |
39 | 0 | } |
40 | 0 | } |
41 | | |
42 | | /// Run the spawned future for a single step, returning none if a future either completed or |
43 | | /// spawned a new future onto the stack. Will return some if the root future is finished. |
44 | | /// |
45 | | /// # Panics |
46 | | /// |
47 | | /// This function will panic if the waker inside the future running on the stack either tries |
48 | | /// to clone the waker or tries to call wake. This function is not meant to used with any other |
49 | | /// future except those generated with the various function provided by the stack. For the |
50 | | /// async version see [`Runner::step_async`] |
51 | 9.57M | pub fn step(&mut self) -> Option<R> { |
52 | 9.57M | if let Some(x) = unsafe { self.stack.try_get_result::<R>() } { |
53 | 15.7k | return Some(x); |
54 | 9.55M | } |
55 | | |
56 | 9.55M | let waker = stub_waker::get(); |
57 | 9.55M | let mut context = Context::from_waker(&waker); |
58 | 9.55M | let rebless_addr = self.stack.set_rebless_context(&mut context); |
59 | | |
60 | 9.55M | if unsafe { self.stack.drive_top_task(&mut context) }.is_pending() { |
61 | 0 | panic!( |
62 | | "a non-reblessive future was run while running the reblessive runtime as non-async" |
63 | | ) |
64 | 9.55M | } |
65 | | |
66 | 9.55M | self.stack.set_rebless_context_addr(rebless_addr); |
67 | 9.55M | None |
68 | 9.57M | } Unexecuted instantiation: <reblessive::stack::runner::Runner<core::result::Result<surrealdb_types::value::Value, surrealdb_core::syn::error::SyntaxError>>>::step Unexecuted instantiation: <reblessive::stack::runner::Runner<core::result::Result<surrealdb_types::value::record_id::RecordId, surrealdb_core::syn::error::SyntaxError>>>::step <reblessive::stack::runner::Runner<core::result::Result<surrealdb_core::sql::expression::Expr, surrealdb_core::syn::error::SyntaxError>>>::step Line | Count | Source | 51 | 44.3k | pub fn step(&mut self) -> Option<R> { | 52 | 44.3k | if let Some(x) = unsafe { self.stack.try_get_result::<R>() } { | 53 | 10.9k | return Some(x); | 54 | 33.3k | } | 55 | | | 56 | 33.3k | let waker = stub_waker::get(); | 57 | 33.3k | let mut context = Context::from_waker(&waker); | 58 | 33.3k | let rebless_addr = self.stack.set_rebless_context(&mut context); | 59 | | | 60 | 33.3k | if unsafe { self.stack.drive_top_task(&mut context) }.is_pending() { | 61 | 0 | panic!( | 62 | | "a non-reblessive future was run while running the reblessive runtime as non-async" | 63 | | ) | 64 | 33.3k | } | 65 | | | 66 | 33.3k | self.stack.set_rebless_context_addr(rebless_addr); | 67 | 33.3k | None | 68 | 44.3k | } |
Unexecuted instantiation: <reblessive::stack::runner::Runner<core::result::Result<surrealdb_core::sql::ast::TopLevelExpr, surrealdb_core::syn::error::SyntaxError>>>::step <reblessive::stack::runner::Runner<core::result::Result<surrealdb_core::sql::ast::Ast, surrealdb_core::syn::error::SyntaxError>>>::step Line | Count | Source | 51 | 9.52M | pub fn step(&mut self) -> Option<R> { | 52 | 9.52M | if let Some(x) = unsafe { self.stack.try_get_result::<R>() } { | 53 | 4.76k | return Some(x); | 54 | 9.52M | } | 55 | | | 56 | 9.52M | let waker = stub_waker::get(); | 57 | 9.52M | let mut context = Context::from_waker(&waker); | 58 | 9.52M | let rebless_addr = self.stack.set_rebless_context(&mut context); | 59 | | | 60 | 9.52M | if unsafe { self.stack.drive_top_task(&mut context) }.is_pending() { | 61 | 0 | panic!( | 62 | | "a non-reblessive future was run while running the reblessive runtime as non-async" | 63 | | ) | 64 | 9.52M | } | 65 | | | 66 | 9.52M | self.stack.set_rebless_context_addr(rebless_addr); | 67 | 9.52M | None | 68 | 9.52M | } |
Unexecuted instantiation: <reblessive::stack::runner::Runner<core::result::Result<surrealdb_core::sql::kind::Kind, surrealdb_core::syn::error::SyntaxError>>>::step Unexecuted instantiation: <reblessive::stack::runner::Runner<core::result::Result<surrealdb_core::sql::block::Block, surrealdb_core::syn::error::SyntaxError>>>::step Unexecuted instantiation: <reblessive::stack::runner::Runner<core::result::Result<surrealdb_core::sql::idiom::Idiom, surrealdb_core::syn::error::SyntaxError>>>::step Unexecuted instantiation: <reblessive::stack::runner::Runner<core::result::Result<surrealdb_core::sql::function::Function, surrealdb_core::syn::error::SyntaxError>>>::step Unexecuted instantiation: <reblessive::stack::runner::Runner<core::result::Result<surrealdb_core::val::table::TableName, surrealdb_core::syn::error::SyntaxError>>>::step Unexecuted instantiation: <reblessive::stack::runner::Runner<_>>::step |
69 | | |
70 | | /// Drive the stack until it completes. |
71 | | /// |
72 | | /// # Panics |
73 | | /// |
74 | | /// This function will panic if the waker inside the future running on the stack either tries |
75 | | /// to clone the waker or tries to call wake. This function is not meant to used with any other |
76 | | /// future except those generated with the various function provided by the stack. For the |
77 | | /// async version see [`Runner::finish_async`] |
78 | 15.7k | pub fn finish(mut self) -> R { |
79 | | loop { |
80 | 9.57M | if let Some(x) = self.step() { |
81 | 15.7k | return x; |
82 | 9.55M | } |
83 | | } |
84 | 15.7k | } Unexecuted instantiation: <reblessive::stack::runner::Runner<core::result::Result<surrealdb_types::value::Value, surrealdb_core::syn::error::SyntaxError>>>::finish Unexecuted instantiation: <reblessive::stack::runner::Runner<core::result::Result<surrealdb_types::value::record_id::RecordId, surrealdb_core::syn::error::SyntaxError>>>::finish <reblessive::stack::runner::Runner<core::result::Result<surrealdb_core::sql::expression::Expr, surrealdb_core::syn::error::SyntaxError>>>::finish Line | Count | Source | 78 | 10.9k | pub fn finish(mut self) -> R { | 79 | | loop { | 80 | 44.3k | if let Some(x) = self.step() { | 81 | 10.9k | return x; | 82 | 33.3k | } | 83 | | } | 84 | 10.9k | } |
Unexecuted instantiation: <reblessive::stack::runner::Runner<core::result::Result<surrealdb_core::sql::ast::TopLevelExpr, surrealdb_core::syn::error::SyntaxError>>>::finish <reblessive::stack::runner::Runner<core::result::Result<surrealdb_core::sql::ast::Ast, surrealdb_core::syn::error::SyntaxError>>>::finish Line | Count | Source | 78 | 4.76k | pub fn finish(mut self) -> R { | 79 | | loop { | 80 | 9.52M | if let Some(x) = self.step() { | 81 | 4.76k | return x; | 82 | 9.52M | } | 83 | | } | 84 | 4.76k | } |
Unexecuted instantiation: <reblessive::stack::runner::Runner<core::result::Result<surrealdb_core::sql::kind::Kind, surrealdb_core::syn::error::SyntaxError>>>::finish Unexecuted instantiation: <reblessive::stack::runner::Runner<core::result::Result<surrealdb_core::sql::block::Block, surrealdb_core::syn::error::SyntaxError>>>::finish Unexecuted instantiation: <reblessive::stack::runner::Runner<core::result::Result<surrealdb_core::sql::idiom::Idiom, surrealdb_core::syn::error::SyntaxError>>>::finish Unexecuted instantiation: <reblessive::stack::runner::Runner<core::result::Result<surrealdb_core::sql::function::Function, surrealdb_core::syn::error::SyntaxError>>>::finish Unexecuted instantiation: <reblessive::stack::runner::Runner<core::result::Result<surrealdb_core::val::table::TableName, surrealdb_core::syn::error::SyntaxError>>>::finish Unexecuted instantiation: <reblessive::stack::runner::Runner<_>>::finish |
85 | | |
86 | | /// Returns the number of futures currently spawned on the stack. |
87 | 0 | pub fn depth(&self) -> usize { |
88 | 0 | self.stack.pending_tasks() |
89 | 0 | } |
90 | | } |
91 | | |
92 | | impl<R> Drop for Runner<'_, R> { |
93 | 15.7k | fn drop(&mut self) { |
94 | | // The runner is dropped so we need to clear all the futures that might still be present on |
95 | | // the stack, if the runner was dropped before finishing the stack. |
96 | 15.7k | self.stack.state.set(StackState::Cancelled); |
97 | 15.7k | unsafe { self.stack.clear::<R>() } |
98 | 15.7k | self.stack.state.set(StackState::Base); |
99 | 15.7k | } Unexecuted instantiation: <reblessive::stack::runner::Runner<core::result::Result<surrealdb_types::value::Value, surrealdb_core::syn::error::SyntaxError>> as core::ops::drop::Drop>::drop Unexecuted instantiation: <reblessive::stack::runner::Runner<core::result::Result<surrealdb_types::value::record_id::RecordId, surrealdb_core::syn::error::SyntaxError>> as core::ops::drop::Drop>::drop <reblessive::stack::runner::Runner<core::result::Result<surrealdb_core::sql::expression::Expr, surrealdb_core::syn::error::SyntaxError>> as core::ops::drop::Drop>::drop Line | Count | Source | 93 | 10.9k | fn drop(&mut self) { | 94 | | // The runner is dropped so we need to clear all the futures that might still be present on | 95 | | // the stack, if the runner was dropped before finishing the stack. | 96 | 10.9k | self.stack.state.set(StackState::Cancelled); | 97 | 10.9k | unsafe { self.stack.clear::<R>() } | 98 | 10.9k | self.stack.state.set(StackState::Base); | 99 | 10.9k | } |
Unexecuted instantiation: <reblessive::stack::runner::Runner<core::result::Result<surrealdb_core::sql::ast::TopLevelExpr, surrealdb_core::syn::error::SyntaxError>> as core::ops::drop::Drop>::drop <reblessive::stack::runner::Runner<core::result::Result<surrealdb_core::sql::ast::Ast, surrealdb_core::syn::error::SyntaxError>> as core::ops::drop::Drop>::drop Line | Count | Source | 93 | 4.76k | fn drop(&mut self) { | 94 | | // The runner is dropped so we need to clear all the futures that might still be present on | 95 | | // the stack, if the runner was dropped before finishing the stack. | 96 | 4.76k | self.stack.state.set(StackState::Cancelled); | 97 | 4.76k | unsafe { self.stack.clear::<R>() } | 98 | 4.76k | self.stack.state.set(StackState::Base); | 99 | 4.76k | } |
Unexecuted instantiation: <reblessive::stack::runner::Runner<core::result::Result<surrealdb_core::sql::kind::Kind, surrealdb_core::syn::error::SyntaxError>> as core::ops::drop::Drop>::drop Unexecuted instantiation: <reblessive::stack::runner::Runner<core::result::Result<surrealdb_core::sql::block::Block, surrealdb_core::syn::error::SyntaxError>> as core::ops::drop::Drop>::drop Unexecuted instantiation: <reblessive::stack::runner::Runner<core::result::Result<surrealdb_core::sql::idiom::Idiom, surrealdb_core::syn::error::SyntaxError>> as core::ops::drop::Drop>::drop Unexecuted instantiation: <reblessive::stack::runner::Runner<core::result::Result<surrealdb_core::sql::function::Function, surrealdb_core::syn::error::SyntaxError>> as core::ops::drop::Drop>::drop Unexecuted instantiation: <reblessive::stack::runner::Runner<core::result::Result<surrealdb_core::val::table::TableName, surrealdb_core::syn::error::SyntaxError>> as core::ops::drop::Drop>::drop Unexecuted instantiation: <reblessive::stack::runner::Runner<_> as core::ops::drop::Drop>::drop |
100 | | } |
101 | | |
102 | | /// Future returned by [`Runner::step_async`] |
103 | | #[must_use = "futures do nothing unless you `.await` or poll them"] |
104 | | pub struct StepFuture<'a, R> { |
105 | | stack: &'a Stack, |
106 | | _marker: PhantomData<R>, |
107 | | } |
108 | | |
109 | | impl<R> Future for StepFuture<'_, R> { |
110 | | type Output = Option<R>; |
111 | | |
112 | 0 | fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { |
113 | 0 | if let Some(x) = unsafe { self.stack.try_get_result() } { |
114 | 0 | return Poll::Ready(Some(x)); |
115 | 0 | } |
116 | | |
117 | 0 | let rebless_addr = self.stack.set_rebless_context(cx); |
118 | 0 | let r = unsafe { self.stack.drive_top_task(cx) }; |
119 | 0 | self.stack.set_rebless_context_addr(rebless_addr); |
120 | 0 | match r { |
121 | 0 | Poll::Ready(_) => Poll::Ready(None), |
122 | 0 | Poll::Pending => Poll::Pending, |
123 | | } |
124 | 0 | } |
125 | | } |
126 | | |
127 | | /// Future returned by [`Runner::finish_async`] |
128 | | #[must_use = "futures do nothing unless you `.await` or poll them"] |
129 | | pub struct FinishFuture<'a, R> { |
130 | | stack: &'a Stack, |
131 | | _marker: PhantomData<R>, |
132 | | } |
133 | | |
134 | | impl<R> Future for FinishFuture<'_, R> { |
135 | | type Output = R; |
136 | | |
137 | 0 | fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { |
138 | | loop { |
139 | 0 | if let Some(x) = unsafe { self.stack.try_get_result() } { |
140 | 0 | return Poll::Ready(x); |
141 | 0 | } |
142 | | |
143 | 0 | let rebless_addr = self.stack.set_rebless_context(cx); |
144 | 0 | let r = unsafe { self.stack.drive_top_task(cx) }; |
145 | 0 | self.stack.set_rebless_context_addr(rebless_addr); |
146 | 0 | match r { |
147 | 0 | Poll::Ready(_) => {} |
148 | 0 | Poll::Pending => return Poll::Pending, |
149 | | } |
150 | | } |
151 | 0 | } |
152 | | } |