1 use crate::runtime::task::{Header, RawTask}; 2 use std::fmt; 3 use std::panic::{RefUnwindSafe, UnwindSafe}; 4 5 /// An owned permission to abort a spawned task, without awaiting its completion. 6 /// 7 /// Unlike a [`JoinHandle`], an `AbortHandle` does *not* represent the 8 /// permission to await the task's completion, only to terminate it. 9 /// 10 /// The task may be aborted by calling the [`AbortHandle::abort`] method. 11 /// Dropping an `AbortHandle` releases the permission to terminate the task 12 /// --- it does *not* abort the task. 13 /// 14 /// [`JoinHandle`]: crate::task::JoinHandle 15 #[cfg_attr(docsrs, doc(cfg(feature = "rt")))] 16 pub struct AbortHandle { 17 raw: RawTask, 18 } 19 20 impl AbortHandle { new(raw: RawTask) -> Self21 pub(super) fn new(raw: RawTask) -> Self { 22 Self { raw } 23 } 24 25 /// Abort the task associated with the handle. 26 /// 27 /// Awaiting a cancelled task might complete as usual if the task was 28 /// already completed at the time it was cancelled, but most likely it 29 /// will fail with a [cancelled] `JoinError`. 30 /// 31 /// If the task was already cancelled, such as by [`JoinHandle::abort`], 32 /// this method will do nothing. 33 /// 34 /// [cancelled]: method@super::error::JoinError::is_cancelled 35 /// [`JoinHandle::abort`]: method@super::JoinHandle::abort abort(&self)36 pub fn abort(&self) { 37 self.raw.remote_abort(); 38 } 39 40 /// Checks if the task associated with this `AbortHandle` has finished. 41 /// 42 /// Please note that this method can return `false` even if `abort` has been 43 /// called on the task. This is because the cancellation process may take 44 /// some time, and this method does not return `true` until it has 45 /// completed. is_finished(&self) -> bool46 pub fn is_finished(&self) -> bool { 47 let state = self.raw.state().load(); 48 state.is_complete() 49 } 50 51 /// Returns a [task ID] that uniquely identifies this task relative to other 52 /// currently spawned tasks. 53 /// 54 /// **Note**: This is an [unstable API][unstable]. The public API of this type 55 /// may break in 1.x releases. See [the documentation on unstable 56 /// features][unstable] for details. 57 /// 58 /// [task ID]: crate::task::Id 59 /// [unstable]: crate#unstable-features 60 #[cfg(tokio_unstable)] 61 #[cfg_attr(docsrs, doc(cfg(tokio_unstable)))] id(&self) -> super::Id62 pub fn id(&self) -> super::Id { 63 // Safety: The header pointer is valid. 64 unsafe { Header::get_id(self.raw.header_ptr()) } 65 } 66 } 67 68 unsafe impl Send for AbortHandle {} 69 unsafe impl Sync for AbortHandle {} 70 71 impl UnwindSafe for AbortHandle {} 72 impl RefUnwindSafe for AbortHandle {} 73 74 impl fmt::Debug for AbortHandle { fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result75 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { 76 // Safety: The header pointer is valid. 77 let id_ptr = unsafe { Header::get_id_ptr(self.raw.header_ptr()) }; 78 let id = unsafe { id_ptr.as_ref() }; 79 fmt.debug_struct("AbortHandle").field("id", id).finish() 80 } 81 } 82 83 impl Drop for AbortHandle { drop(&mut self)84 fn drop(&mut self) { 85 self.raw.drop_abort_handle(); 86 } 87 } 88