1 //! Thread local runtime context 2 use crate::runtime::Handle; 3 4 use std::cell::RefCell; 5 6 thread_local! { 7 static CONTEXT: RefCell<Option<Handle>> = RefCell::new(None) 8 } 9 current() -> Option<Handle>10pub(crate) fn current() -> Option<Handle> { 11 CONTEXT.with(|ctx| ctx.borrow().clone()) 12 } 13 14 cfg_io_driver! { 15 pub(crate) fn io_handle() -> crate::runtime::driver::IoHandle { 16 CONTEXT.with(|ctx| { 17 let ctx = ctx.borrow(); 18 ctx.as_ref().expect(crate::util::error::CONTEXT_MISSING_ERROR).io_handle.clone() 19 }) 20 } 21 } 22 23 cfg_signal_internal! { 24 #[cfg(unix)] 25 pub(crate) fn signal_handle() -> crate::runtime::driver::SignalHandle { 26 CONTEXT.with(|ctx| { 27 let ctx = ctx.borrow(); 28 ctx.as_ref().expect(crate::util::error::CONTEXT_MISSING_ERROR).signal_handle.clone() 29 }) 30 } 31 } 32 33 cfg_time! { 34 pub(crate) fn time_handle() -> crate::runtime::driver::TimeHandle { 35 CONTEXT.with(|ctx| { 36 let ctx = ctx.borrow(); 37 ctx.as_ref().expect(crate::util::error::CONTEXT_MISSING_ERROR).time_handle.clone() 38 }) 39 } 40 41 cfg_test_util! { 42 pub(crate) fn clock() -> Option<crate::runtime::driver::Clock> { 43 CONTEXT.with(|ctx| (*ctx.borrow()).as_ref().map(|ctx| ctx.clock.clone())) 44 } 45 } 46 } 47 48 cfg_rt! { 49 pub(crate) fn spawn_handle() -> Option<crate::runtime::Spawner> { 50 CONTEXT.with(|ctx| (*ctx.borrow()).as_ref().map(|ctx| ctx.spawner.clone())) 51 } 52 } 53 54 /// Set this [`Handle`] as the current active [`Handle`]. 55 /// 56 /// [`Handle`]: Handle enter(new: Handle) -> EnterGuard57pub(crate) fn enter(new: Handle) -> EnterGuard { 58 CONTEXT.with(|ctx| { 59 let old = ctx.borrow_mut().replace(new); 60 EnterGuard(old) 61 }) 62 } 63 64 #[derive(Debug)] 65 pub(crate) struct EnterGuard(Option<Handle>); 66 67 impl Drop for EnterGuard { drop(&mut self)68 fn drop(&mut self) { 69 CONTEXT.with(|ctx| { 70 *ctx.borrow_mut() = self.0.take(); 71 }); 72 } 73 } 74