1 //! Abstracts out the entire chain of runtime sub-drivers into common types.
2 use crate::park::thread::ParkThread;
3 use crate::park::Park;
4 
5 use std::io;
6 use std::time::Duration;
7 
8 // ===== io driver =====
9 
10 cfg_io_driver! {
11     type IoDriver = crate::io::driver::Driver;
12     type IoStack = crate::park::either::Either<ProcessDriver, ParkThread>;
13     pub(crate) type IoHandle = Option<crate::io::driver::Handle>;
14 
15     fn create_io_stack(enabled: bool) -> io::Result<(IoStack, IoHandle, SignalHandle)> {
16         use crate::park::either::Either;
17 
18         #[cfg(loom)]
19         assert!(!enabled);
20 
21         let ret = if enabled {
22             let io_driver = crate::io::driver::Driver::new()?;
23             let io_handle = io_driver.handle();
24 
25             let (signal_driver, signal_handle) = create_signal_driver(io_driver)?;
26             let process_driver = create_process_driver(signal_driver);
27 
28             (Either::A(process_driver), Some(io_handle), signal_handle)
29         } else {
30             (Either::B(ParkThread::new()), Default::default(), Default::default())
31         };
32 
33         Ok(ret)
34     }
35 }
36 
37 cfg_not_io_driver! {
38     pub(crate) type IoHandle = ();
39     type IoStack = ParkThread;
40 
41     fn create_io_stack(_enabled: bool) -> io::Result<(IoStack, IoHandle, SignalHandle)> {
42         Ok((ParkThread::new(), Default::default(), Default::default()))
43     }
44 }
45 
46 // ===== signal driver =====
47 
48 macro_rules! cfg_signal_internal_and_unix {
49     ($($item:item)*) => {
50         #[cfg(unix)]
51         cfg_signal_internal! { $($item)* }
52     }
53 }
54 
55 cfg_signal_internal_and_unix! {
56     type SignalDriver = crate::signal::unix::driver::Driver;
57     pub(crate) type SignalHandle = Option<crate::signal::unix::driver::Handle>;
58 
59     fn create_signal_driver(io_driver: IoDriver) -> io::Result<(SignalDriver, SignalHandle)> {
60         let driver = crate::signal::unix::driver::Driver::new(io_driver)?;
61         let handle = driver.handle();
62         Ok((driver, Some(handle)))
63     }
64 }
65 
66 cfg_not_signal_internal! {
67     pub(crate) type SignalHandle = ();
68 
69     cfg_io_driver! {
70         type SignalDriver = IoDriver;
71 
72         fn create_signal_driver(io_driver: IoDriver) -> io::Result<(SignalDriver, SignalHandle)> {
73             Ok((io_driver, ()))
74         }
75     }
76 }
77 
78 // ===== process driver =====
79 
80 cfg_process_driver! {
81     type ProcessDriver = crate::process::unix::driver::Driver;
82 
83     fn create_process_driver(signal_driver: SignalDriver) -> ProcessDriver {
84         crate::process::unix::driver::Driver::new(signal_driver)
85     }
86 }
87 
88 cfg_not_process_driver! {
89     cfg_io_driver! {
90         type ProcessDriver = SignalDriver;
91 
92         fn create_process_driver(signal_driver: SignalDriver) -> ProcessDriver {
93             signal_driver
94         }
95     }
96 }
97 
98 // ===== time driver =====
99 
100 cfg_time! {
101     type TimeDriver = crate::park::either::Either<crate::time::driver::Driver<IoStack>, IoStack>;
102 
103     pub(crate) type Clock = crate::time::Clock;
104     pub(crate) type TimeHandle = Option<crate::time::driver::Handle>;
105 
106     fn create_clock(enable_pausing: bool, start_paused: bool) -> Clock {
107         crate::time::Clock::new(enable_pausing, start_paused)
108     }
109 
110     fn create_time_driver(
111         enable: bool,
112         io_stack: IoStack,
113         clock: Clock,
114     ) -> (TimeDriver, TimeHandle) {
115         use crate::park::either::Either;
116 
117         if enable {
118             let driver = crate::time::driver::Driver::new(io_stack, clock);
119             let handle = driver.handle();
120 
121             (Either::A(driver), Some(handle))
122         } else {
123             (Either::B(io_stack), None)
124         }
125     }
126 }
127 
128 cfg_not_time! {
129     type TimeDriver = IoStack;
130 
131     pub(crate) type Clock = ();
132     pub(crate) type TimeHandle = ();
133 
134     fn create_clock(_enable_pausing: bool, _start_paused: bool) -> Clock {
135         ()
136     }
137 
138     fn create_time_driver(
139         _enable: bool,
140         io_stack: IoStack,
141         _clock: Clock,
142     ) -> (TimeDriver, TimeHandle) {
143         (io_stack, ())
144     }
145 }
146 
147 // ===== runtime driver =====
148 
149 #[derive(Debug)]
150 pub(crate) struct Driver {
151     inner: TimeDriver,
152 }
153 
154 pub(crate) struct Resources {
155     pub(crate) io_handle: IoHandle,
156     pub(crate) signal_handle: SignalHandle,
157     pub(crate) time_handle: TimeHandle,
158     pub(crate) clock: Clock,
159 }
160 
161 pub(crate) struct Cfg {
162     pub(crate) enable_io: bool,
163     pub(crate) enable_time: bool,
164     pub(crate) enable_pause_time: bool,
165     pub(crate) start_paused: bool,
166 }
167 
168 impl Driver {
new(cfg: Cfg) -> io::Result<(Self, Resources)>169     pub(crate) fn new(cfg: Cfg) -> io::Result<(Self, Resources)> {
170         let (io_stack, io_handle, signal_handle) = create_io_stack(cfg.enable_io)?;
171 
172         let clock = create_clock(cfg.enable_pause_time, cfg.start_paused);
173 
174         let (time_driver, time_handle) =
175             create_time_driver(cfg.enable_time, io_stack, clock.clone());
176 
177         Ok((
178             Self { inner: time_driver },
179             Resources {
180                 io_handle,
181                 signal_handle,
182                 time_handle,
183                 clock,
184             },
185         ))
186     }
187 }
188 
189 impl Park for Driver {
190     type Unpark = <TimeDriver as Park>::Unpark;
191     type Error = <TimeDriver as Park>::Error;
192 
unpark(&self) -> Self::Unpark193     fn unpark(&self) -> Self::Unpark {
194         self.inner.unpark()
195     }
196 
park(&mut self) -> Result<(), Self::Error>197     fn park(&mut self) -> Result<(), Self::Error> {
198         self.inner.park()
199     }
200 
park_timeout(&mut self, duration: Duration) -> Result<(), Self::Error>201     fn park_timeout(&mut self, duration: Duration) -> Result<(), Self::Error> {
202         self.inner.park_timeout(duration)
203     }
204 
shutdown(&mut self)205     fn shutdown(&mut self) {
206         self.inner.shutdown()
207     }
208 }
209