1//! An [`AbortOnDropHandle`] is like a [`JoinHandle`], except that it
2//! will abort the task as soon as it is dropped.
34use tokio::task::{AbortHandle, JoinError, JoinHandle};
56use std::{
7 future::Future,
8 pin::Pin,
9 task::{Context, Poll},
10};
1112/// A wrapper around a [`tokio::task::JoinHandle`],
13/// which [aborts] the task when it is dropped.
14///
15/// [aborts]: tokio::task::JoinHandle::abort
16#[must_use = "Dropping the handle aborts the task immediately"]
17#[derive(Debug)]
18pub struct AbortOnDropHandle<T>(JoinHandle<T>);
1920impl<T> Drop for AbortOnDropHandle<T> {
21fn drop(&mut self) {
22self.0.abort()
23 }
24}
2526impl<T> AbortOnDropHandle<T> {
27/// Create an [`AbortOnDropHandle`] from a [`JoinHandle`].
28pub fn new(handle: JoinHandle<T>) -> Self {
29Self(handle)
30 }
3132/// Abort the task associated with this handle,
33 /// equivalent to [`JoinHandle::abort`].
34pub fn abort(&self) {
35self.0.abort()
36 }
3738/// Checks if the task associated with this handle is finished,
39 /// equivalent to [`JoinHandle::is_finished`].
40pub fn is_finished(&self) -> bool {
41self.0.is_finished()
42 }
4344/// Returns a new [`AbortHandle`] that can be used to remotely abort this task,
45 /// equivalent to [`JoinHandle::abort_handle`].
46pub fn abort_handle(&self) -> AbortHandle {
47self.0.abort_handle()
48 }
49}
5051impl<T> Future for AbortOnDropHandle<T> {
52type Output = Result<T, JoinError>;
5354fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
55 Pin::new(&mut self.0).poll(cx)
56 }
57}
5859impl<T> AsRef<JoinHandle<T>> for AbortOnDropHandle<T> {
60fn as_ref(&self) -> &JoinHandle<T> {
61&self.0
62}
63}