Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/stdx/src/thread/pool.rs')
-rw-r--r--crates/stdx/src/thread/pool.rs21
1 files changed, 13 insertions, 8 deletions
diff --git a/crates/stdx/src/thread/pool.rs b/crates/stdx/src/thread/pool.rs
index 2ddd7da74c..9acc1de922 100644
--- a/crates/stdx/src/thread/pool.rs
+++ b/crates/stdx/src/thread/pool.rs
@@ -7,9 +7,12 @@
//! The thread pool is implemented entirely using
//! the threading utilities in [`crate::thread`].
-use std::sync::{
- atomic::{AtomicUsize, Ordering},
- Arc,
+use std::{
+ panic::{self, UnwindSafe},
+ sync::{
+ atomic::{AtomicUsize, Ordering},
+ Arc,
+ },
};
use crossbeam_channel::{Receiver, Sender};
@@ -25,13 +28,13 @@ pub struct Pool {
// so that the channel is actually closed
// before we join the worker threads!
job_sender: Sender<Job>,
- _handles: Vec<JoinHandle>,
+ _handles: Box<[JoinHandle]>,
extant_tasks: Arc<AtomicUsize>,
}
struct Job {
requested_intent: ThreadIntent,
- f: Box<dyn FnOnce() + Send + 'static>,
+ f: Box<dyn FnOnce() + Send + UnwindSafe + 'static>,
}
impl Pool {
@@ -47,6 +50,7 @@ impl Pool {
let handle = Builder::new(INITIAL_INTENT)
.stack_size(STACK_SIZE)
.name("Worker".into())
+ .allow_leak(true)
.spawn({
let extant_tasks = Arc::clone(&extant_tasks);
let job_receiver: Receiver<Job> = job_receiver.clone();
@@ -58,7 +62,8 @@ impl Pool {
current_intent = job.requested_intent;
}
extant_tasks.fetch_add(1, Ordering::SeqCst);
- (job.f)();
+ // discard the panic, we should've logged the backtrace already
+ _ = panic::catch_unwind(job.f);
extant_tasks.fetch_sub(1, Ordering::SeqCst);
}
}
@@ -68,12 +73,12 @@ impl Pool {
handles.push(handle);
}
- Pool { _handles: handles, extant_tasks, job_sender }
+ Pool { _handles: handles.into_boxed_slice(), extant_tasks, job_sender }
}
pub fn spawn<F>(&self, intent: ThreadIntent, f: F)
where
- F: FnOnce() + Send + 'static,
+ F: FnOnce() + Send + UnwindSafe + 'static,
{
let f = Box::new(move || {
if cfg!(debug_assertions) {