• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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