Skip to content

Commit

Permalink
Catch panics in critical section of thread::scope
Browse files Browse the repository at this point in the history
Replaces #724.

Co-authored-by: Enkelmann <[email protected]>
  • Loading branch information
taiki-e and Enkelmann committed Dec 13, 2023
1 parent 2ffa481 commit 4df330b
Showing 1 changed file with 15 additions and 0 deletions.
15 changes: 15 additions & 0 deletions crossbeam-utils/src/thread.rs
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,15 @@ pub fn scope<'env, F, R>(f: F) -> thread::Result<R>
where
F: FnOnce(&Scope<'env>) -> R,
{
struct AbortOnPanic;
impl Drop for AbortOnPanic {
fn drop(&mut self) {
if thread::panicking() {
std::process::abort();
}
}
}

let wg = WaitGroup::new();
let scope = Scope::<'env> {
handles: SharedVec::default(),
Expand All @@ -162,6 +171,10 @@ where
// Execute the scoped function, but catch any panics.
let result = panic::catch_unwind(panic::AssertUnwindSafe(|| f(&scope)));

// If an unwinding panic occurs before all threads are joined
// promote it to an aborting panic to prevent any threads from escaping the scope.
let guard = AbortOnPanic;

// Wait until all nested scopes are dropped.
drop(scope.wait_group);
wg.wait();
Expand All @@ -177,6 +190,8 @@ where
.filter_map(|handle| handle.join().err())
.collect();

mem::forget(guard);

// If `f` has panicked, resume unwinding.
// If any of the child threads have panicked, return the panic errors.
// Otherwise, everything is OK and return the result of `f`.
Expand Down

0 comments on commit 4df330b

Please sign in to comment.