1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
use { super::*, crate::object::*, alloc::sync::{Arc, Weak}, }; /// Suspend the given task. /// /// Currently only thread or process handles may be suspended. /// /// # Example /// ``` /// # use std::sync::Arc; /// # use zircon_object::task::*; /// # use zircon_object::object::{KernelObject, Signal}; /// # kernel_hal_unix::init(); /// let job = Job::root(); /// let proc = Process::create(&job, "proc").unwrap(); /// let thread = Thread::create(&proc, "thread").unwrap(); /// /// // start the thread and never terminate /// thread.start(0, 0, 0, 0, |thread| Box::pin(async move { /// loop { async_std::task::yield_now().await } /// let _ = thread; /// })).unwrap(); /// /// // wait for the thread running /// let object: Arc<dyn KernelObject> = thread.clone(); /// async_std::task::block_on(object.wait_signal(Signal::THREAD_RUNNING)); /// assert_eq!(thread.state(), ThreadState::Running); /// /// // suspend the thread /// { /// let task: Arc<dyn Task> = thread.clone(); /// let suspend_token = SuspendToken::create(&task); /// assert_eq!(thread.state(), ThreadState::Suspended); /// } /// // suspend token dropped, resume the thread /// assert_eq!(thread.state(), ThreadState::Running); /// ``` pub struct SuspendToken { base: KObjectBase, task: Weak<dyn Task>, } impl_kobject!(SuspendToken); impl SuspendToken { /// Create a `SuspendToken` which can suspend the given task. pub fn create(task: &Arc<dyn Task>) -> Arc<Self> { task.suspend(); Arc::new(SuspendToken { base: KObjectBase::new(), task: Arc::downgrade(task), }) } } impl Drop for SuspendToken { fn drop(&mut self) { if let Some(task) = self.task.upgrade() { task.resume(); } } }