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