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))] new(handle: &Handle) -> Self19 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(target_os = "wasi")))] 27 scheduler::Handle::MultiThread(_) => {} 28 #[cfg(all(tokio_unstable, feature = "rt-multi-thread", not(target_os = "wasi")))] 29 scheduler::Handle::MultiThreadAlt(_) => {} 30 } 31 } 32 BlockingSchedule { 33 #[cfg(feature = "test-util")] 34 handle: handle.clone(), 35 } 36 } 37 } 38 39 impl task::Schedule for BlockingSchedule { release(&self, _task: &Task<Self>) -> Option<Task<Self>>40 fn release(&self, _task: &Task<Self>) -> Option<Task<Self>> { 41 #[cfg(feature = "test-util")] 42 { 43 match &self.handle.inner { 44 scheduler::Handle::CurrentThread(handle) => { 45 handle.driver.clock.allow_auto_advance(); 46 handle.driver.unpark(); 47 } 48 #[cfg(all(feature = "rt-multi-thread", not(target_os = "wasi")))] 49 scheduler::Handle::MultiThread(_) => {} 50 #[cfg(all(tokio_unstable, feature = "rt-multi-thread", not(target_os = "wasi")))] 51 scheduler::Handle::MultiThreadAlt(_) => {} 52 } 53 } 54 None 55 } 56 schedule(&self, _task: task::Notified<Self>)57 fn schedule(&self, _task: task::Notified<Self>) { 58 unreachable!(); 59 } 60 } 61