mirror of
https://github.com/tokio-rs/tokio.git
synced 2026-08-25 00:00:18 +02:00
task: add AbortOnDropHandle::detach (#7400)
This commit is contained in:
@@ -5,6 +5,7 @@ use tokio::task::{AbortHandle, JoinError, JoinHandle};
|
||||
|
||||
use std::{
|
||||
future::Future,
|
||||
mem::ManuallyDrop,
|
||||
pin::Pin,
|
||||
task::{Context, Poll},
|
||||
};
|
||||
@@ -46,6 +47,15 @@ impl<T> AbortOnDropHandle<T> {
|
||||
pub fn abort_handle(&self) -> AbortHandle {
|
||||
self.0.abort_handle()
|
||||
}
|
||||
|
||||
/// Cancels aborting on drop and returns the original [`JoinHandle`].
|
||||
pub fn detach(self) -> JoinHandle<T> {
|
||||
// Avoid invoking `AbortOnDropHandle`'s `Drop` impl
|
||||
let this = ManuallyDrop::new(self);
|
||||
// SAFETY: `&this.0` is a reference, so it is certainly initialized, and
|
||||
// it won't be double-dropped because it's in a `ManuallyDrop`
|
||||
unsafe { std::ptr::read(&this.0) }
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Future for AbortOnDropHandle<T> {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use tokio::sync::oneshot;
|
||||
use tokio::{sync::oneshot, task::yield_now};
|
||||
use tokio_util::task::AbortOnDropHandle;
|
||||
|
||||
#[tokio::test]
|
||||
@@ -25,3 +25,15 @@ async fn aborts_task_directly() {
|
||||
assert!(tx.is_closed());
|
||||
assert!(handle.is_finished());
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn does_not_abort_after_detach() {
|
||||
let (tx, rx) = oneshot::channel::<bool>();
|
||||
let handle = tokio::spawn(async move {
|
||||
let _ = rx.await;
|
||||
});
|
||||
let handle = AbortOnDropHandle::new(handle);
|
||||
handle.detach(); // returns and drops the original join handle
|
||||
yield_now().await;
|
||||
assert!(!tx.is_closed()); // task is still live
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user