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 /// Be aware that tasks spawned using [`spawn_blocking`] cannot be aborted 15 /// because they are not async. If you call `abort` on a `spawn_blocking` task, 16 /// then this *will not have any effect*, and the task will continue running 17 /// normally. The exception is if the task has not started running yet; in that 18 /// case, calling `abort` may prevent the task from starting. 19 /// 20 /// [`JoinHandle`]: crate::task::JoinHandle 21 /// [`spawn_blocking`]: crate::task::spawn_blocking 22 #[cfg_attr(docsrs, doc(cfg(feature = "rt")))] 23 pub struct AbortHandle { 24 raw: RawTask, 25 } 26 27 impl AbortHandle { new(raw: RawTask) -> Self28 pub(super) fn new(raw: RawTask) -> Self { 29 Self { raw } 30 } 31 32 /// Abort the task associated with the handle. 33 /// 34 /// Awaiting a cancelled task might complete as usual if the task was 35 /// already completed at the time it was cancelled, but most likely it 36 /// will fail with a [cancelled] `JoinError`. 37 /// 38 /// If the task was already cancelled, such as by [`JoinHandle::abort`], 39 /// this method will do nothing. 40 /// 41 /// Be aware that tasks spawned using [`spawn_blocking`] cannot be aborted 42 /// because they are not async. If you call `abort` on a `spawn_blocking` 43 /// task, then this *will not have any effect*, and the task will continue 44 /// running normally. The exception is if the task has not started running 45 /// yet; in that case, calling `abort` may prevent the task from starting. 46 /// 47 /// See also [the module level docs] for more information on cancellation. 48 /// 49 /// [cancelled]: method@super::error::JoinError::is_cancelled 50 /// [`JoinHandle::abort`]: method@super::JoinHandle::abort 51 /// [the module level docs]: crate::task#cancellation 52 /// [`spawn_blocking`]: crate::task::spawn_blocking abort(&self)53 pub fn abort(&self) { 54 self.raw.remote_abort(); 55 } 56 57 /// Checks if the task associated with this `AbortHandle` has finished. 58 /// 59 /// Please note that this method can return `false` even if `abort` has been 60 /// called on the task. This is because the cancellation process may take 61 /// some time, and this method does not return `true` until it has 62 /// completed. is_finished(&self) -> bool63 pub fn is_finished(&self) -> bool { 64 let state = self.raw.state().load(); 65 state.is_complete() 66 } 67 68 /// Returns a [task ID] that uniquely identifies this task relative to other 69 /// currently spawned tasks. 70 /// 71 /// [task ID]: crate::task::Id id(&self) -> super::Id72 pub fn id(&self) -> super::Id { 73 // Safety: The header pointer is valid. 74 unsafe { Header::get_id(self.raw.header_ptr()) } 75 } 76 } 77 78 unsafe impl Send for AbortHandle {} 79 unsafe impl Sync for AbortHandle {} 80 81 impl UnwindSafe for AbortHandle {} 82 impl RefUnwindSafe for AbortHandle {} 83 84 impl fmt::Debug for AbortHandle { fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result85 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { 86 // Safety: The header pointer is valid. 87 let id_ptr = unsafe { Header::get_id_ptr(self.raw.header_ptr()) }; 88 let id = unsafe { id_ptr.as_ref() }; 89 fmt.debug_struct("AbortHandle").field("id", id).finish() 90 } 91 } 92 93 impl Drop for AbortHandle { drop(&mut self)94 fn drop(&mut self) { 95 self.raw.drop_abort_handle(); 96 } 97 } 98 99 impl Clone for AbortHandle { 100 /// Returns a cloned `AbortHandle` that can be used to remotely abort this task. clone(&self) -> Self101 fn clone(&self) -> Self { 102 self.raw.ref_inc(); 103 Self::new(self.raw) 104 } 105 } 106