1 | #[cfg (feature = "test-util" )] |
2 | use crate::runtime::scheduler; |
3 | use crate::runtime::task::{self, Task}; |
4 | use crate::runtime::Handle; |
5 | |
6 | /// `task::Schedule` implementation that does nothing (except some bookkeeping |
7 | /// in test-util builds). This is unique to the blocking scheduler as tasks |
8 | /// scheduled are not really futures but blocking operations. |
9 | /// |
10 | /// We avoid storing the task by forgetting it in `bind` and re-materializing it |
11 | /// in `release`. |
12 | pub(crate) struct BlockingSchedule { |
13 | #[cfg (feature = "test-util" )] |
14 | handle: Handle, |
15 | } |
16 | |
17 | impl BlockingSchedule { |
18 | #[cfg_attr (not(feature = "test-util" ), allow(unused_variables))] |
19 | pub(crate) fn new(handle: &Handle) -> Self { |
20 | #[cfg (feature = "test-util" )] |
21 | { |
22 | match &handle.inner { |
23 | scheduler::Handle::CurrentThread(handle) => { |
24 | handle.driver.clock.inhibit_auto_advance(); |
25 | } |
26 | #[cfg (all(feature = "rt-multi-thread" , not(tokio_wasi)))] |
27 | scheduler::Handle::MultiThread(_) => {} |
28 | } |
29 | } |
30 | BlockingSchedule { |
31 | #[cfg (feature = "test-util" )] |
32 | handle: handle.clone(), |
33 | } |
34 | } |
35 | } |
36 | |
37 | impl task::Schedule for BlockingSchedule { |
38 | fn release(&self, _task: &Task<Self>) -> Option<Task<Self>> { |
39 | #[cfg (feature = "test-util" )] |
40 | { |
41 | match &self.handle.inner { |
42 | scheduler::Handle::CurrentThread(handle) => { |
43 | handle.driver.clock.allow_auto_advance(); |
44 | handle.driver.unpark(); |
45 | } |
46 | #[cfg (all(feature = "rt-multi-thread" , not(tokio_wasi)))] |
47 | scheduler::Handle::MultiThread(_) => {} |
48 | } |
49 | } |
50 | None |
51 | } |
52 | |
53 | fn schedule(&self, _task: task::Notified<Self>) { |
54 | unreachable!(); |
55 | } |
56 | } |
57 | |