runtime: swallow panics in drop(JoinHandle) (#4430)

This commit is contained in:
Braulio Valdivielso Martínez
2022-01-28 17:21:03 +01:00
committed by GitHub
parent 91b9850505
commit 111dd66f3e
2 changed files with 25 additions and 11 deletions
+5 -11
View File
@@ -165,8 +165,6 @@ where
}
pub(super) fn drop_join_handle_slow(self) {
let mut maybe_panic = None;
// Try to unset `JOIN_INTEREST`. This must be done as a first step in
// case the task concurrently completed.
if self.header().state.unset_join_interested().is_err() {
@@ -175,21 +173,17 @@ where
// the scheduler or `JoinHandle`. i.e. if the output remains in the
// task structure until the task is deallocated, it may be dropped
// by a Waker on any arbitrary thread.
let panic = panic::catch_unwind(panic::AssertUnwindSafe(|| {
//
// Panics are delivered to the user via the `JoinHandle`. Given that
// they are dropping the `JoinHandle`, we assume they are not
// interested in the panic and swallow it.
let _ = panic::catch_unwind(panic::AssertUnwindSafe(|| {
self.core().stage.drop_future_or_output();
}));
if let Err(panic) = panic {
maybe_panic = Some(panic);
}
}
// Drop the `JoinHandle` reference, possibly deallocating the task
self.drop_reference();
if let Some(panic) = maybe_panic {
panic::resume_unwind(panic);
}
}
/// Remotely aborts the task.
+20
View File
@@ -0,0 +1,20 @@
#![warn(rust_2018_idioms)]
#![cfg(feature = "full")]
struct PanicsOnDrop;
impl Drop for PanicsOnDrop {
fn drop(&mut self) {
panic!("I told you so");
}
}
#[tokio::test]
async fn test_panics_do_not_propagate_when_dropping_join_handle() {
let join_handle = tokio::spawn(async move { PanicsOnDrop });
// only drop the JoinHandle when the task has completed
// (which is difficult to synchronize precisely)
tokio::time::sleep(std::time::Duration::from_millis(3)).await;
drop(join_handle);
}