//! An [`AbortOnDropHandle`] is like a [`JoinHandle`], except that it //! will abort the task as soon as it is dropped. use tokio::task::{AbortHandle, JoinError, JoinHandle}; use std::{ future::Future, pin::Pin, task::{Context, Poll}, }; /// A wrapper around a [`tokio::task::JoinHandle`], /// which [aborts] the task when it is dropped. /// /// [aborts]: tokio::task::JoinHandle::abort #[must_use = "Dropping the handle aborts the task immediately"] #[derive(Debug)] pub struct AbortOnDropHandle(JoinHandle); impl Drop for AbortOnDropHandle { fn drop(&mut self) { self.0.abort() } } impl AbortOnDropHandle { /// Create an [`AbortOnDropHandle`] from a [`JoinHandle`]. pub fn new(handle: JoinHandle) -> Self { Self(handle) } /// Abort the task associated with this handle, /// equivalent to [`JoinHandle::abort`]. pub fn abort(&self) { self.0.abort() } /// Checks if the task associated with this handle is finished, /// equivalent to [`JoinHandle::is_finished`]. pub fn is_finished(&self) -> bool { self.0.is_finished() } /// Returns a new [`AbortHandle`] that can be used to remotely abort this task, /// equivalent to [`JoinHandle::abort_handle`]. pub fn abort_handle(&self) -> AbortHandle { self.0.abort_handle() } } impl Future for AbortOnDropHandle { type Output = Result; fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { Pin::new(&mut self.0).poll(cx) } } impl AsRef> for AbortOnDropHandle { fn as_ref(&self) -> &JoinHandle { &self.0 } }