Skip to content

Commit

Permalink
runtime: swallow panics in drop(JoinHandle) (#4430)
Browse files Browse the repository at this point in the history
  • Loading branch information
BraulioVM committed Jan 28, 2022
1 parent 91b9850 commit 111dd66
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 11 deletions.
16 changes: 5 additions & 11 deletions tokio/src/runtime/task/harness.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand All @@ -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.
Expand Down
20 changes: 20 additions & 0 deletions tokio/tests/join_handle_panic.rs
Original file line number Diff line number Diff line change
@@ -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);
}

0 comments on commit 111dd66

Please sign in to comment.