1 use crate::loom::sync::Arc;
2 use crate::time::driver::ClockTime;
3 use std::fmt;
4 
5 /// Handle to time driver instance.
6 #[derive(Clone)]
7 pub(crate) struct Handle {
8     time_source: ClockTime,
9     inner: Arc<super::Inner>,
10 }
11 
12 impl Handle {
13     /// Creates a new timer `Handle` from a shared `Inner` timer state.
new(inner: Arc<super::Inner>) -> Self14     pub(super) fn new(inner: Arc<super::Inner>) -> Self {
15         let time_source = inner.state.lock().time_source.clone();
16         Handle { time_source, inner }
17     }
18 
19     /// Returns the time source associated with this handle.
time_source(&self) -> &ClockTime20     pub(super) fn time_source(&self) -> &ClockTime {
21         &self.time_source
22     }
23 
24     /// Access the driver's inner structure.
get(&self) -> &super::Inner25     pub(super) fn get(&self) -> &super::Inner {
26         &*self.inner
27     }
28 
29     /// Checks whether the driver has been shutdown.
is_shutdown(&self) -> bool30     pub(super) fn is_shutdown(&self) -> bool {
31         self.inner.is_shutdown()
32     }
33 }
34 
35 cfg_rt! {
36     impl Handle {
37         /// Tries to get a handle to the current timer.
38         ///
39         /// # Panics
40         ///
41         /// This function panics if there is no current timer set.
42         ///
43         /// It can be triggered when `Builder::enable_time()` or
44         /// `Builder::enable_all()` are not included in the builder.
45         ///
46         /// It can also panic whenever a timer is created outside of a
47         /// Tokio runtime. That is why `rt.block_on(delay_for(...))` will panic,
48         /// since the function is executed outside of the runtime.
49         /// Whereas `rt.block_on(async {delay_for(...).await})` doesn't panic.
50         /// And this is because wrapping the function on an async makes it lazy,
51         /// and so gets executed inside the runtime successfully without
52         /// panicking.
53         pub(crate) fn current() -> Self {
54             crate::runtime::context::time_handle()
55                 .expect("A Tokio 1.x context was found, but timers are disabled. Call `enable_time` on the runtime builder to enable timers.")
56         }
57     }
58 }
59 
60 cfg_not_rt! {
61     impl Handle {
62         /// Tries to get a handle to the current timer.
63         ///
64         /// # Panics
65         ///
66         /// This function panics if there is no current timer set.
67         ///
68         /// It can be triggered when `Builder::enable_time()` or
69         /// `Builder::enable_all()` are not included in the builder.
70         ///
71         /// It can also panic whenever a timer is created outside of a Tokio
72         /// runtime. That is why `rt.block_on(delay_for(...))` will panic,
73         /// since the function is executed outside of the runtime.
74         /// Whereas `rt.block_on(async {delay_for(...).await})` doesn't
75         /// panic. And this is because wrapping the function on an async makes it
76         /// lazy, and so outside executed inside the runtime successfully without
77         /// panicking.
78         pub(crate) fn current() -> Self {
79             panic!("{}", crate::util::error::CONTEXT_MISSING_ERROR)
80         }
81     }
82 }
83 
84 impl fmt::Debug for Handle {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result85     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
86         write!(f, "Handle")
87     }
88 }
89