diff options
| author | Lukas Wirth <lukastw97@gmail.com> | 2025-02-04 14:20:36 +0000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-02-04 14:20:36 +0000 |
| commit | 21ddcbb836e4ee785cf64fdffa15c0f52503b5d4 (patch) | |
| tree | 67d63bbcea3a2c9edb2e0ec5634cc9e5fccc5aff /src/tools | |
| parent | 1ba7a38e4f95cd7d8666719140650ce551bd1753 (diff) | |
| parent | 1ce2d7eacaca018a741bdf39b852438f38da91ba (diff) | |
| download | rust-21ddcbb836e4ee785cf64fdffa15c0f52503b5d4.tar.gz rust-21ddcbb836e4ee785cf64fdffa15c0f52503b5d4.zip | |
Merge pull request #19093 from Veykril/push-lrvoookylnxp
Prevent panics from tearing down worker threads
Diffstat (limited to 'src/tools')
| -rw-r--r-- | src/tools/rust-analyzer/crates/rust-analyzer/src/task_pool.rs | 6 | ||||
| -rw-r--r-- | src/tools/rust-analyzer/crates/stdx/src/thread/pool.rs | 21 |
2 files changed, 17 insertions, 10 deletions
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/task_pool.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/task_pool.rs index 2bcd8505e81..c5de69bb9fc 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/task_pool.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/task_pool.rs @@ -1,6 +1,8 @@ //! A thin wrapper around [`stdx::thread::Pool`] which threads a sender through spawned jobs. //! It is used in [`crate::global_state::GlobalState`] throughout the main loop. +use std::panic::UnwindSafe; + use crossbeam_channel::Sender; use stdx::thread::{Pool, ThreadIntent}; @@ -18,7 +20,7 @@ impl<T> TaskPool<T> { pub(crate) fn spawn<F>(&mut self, intent: ThreadIntent, task: F) where - F: FnOnce() -> T + Send + 'static, + F: FnOnce() -> T + Send + UnwindSafe + 'static, T: Send + 'static, { self.pool.spawn(intent, { @@ -29,7 +31,7 @@ impl<T> TaskPool<T> { pub(crate) fn spawn_with_sender<F>(&mut self, intent: ThreadIntent, task: F) where - F: FnOnce(Sender<T>) + Send + 'static, + F: FnOnce(Sender<T>) + Send + UnwindSafe + 'static, T: Send + 'static, { self.pool.spawn(intent, { diff --git a/src/tools/rust-analyzer/crates/stdx/src/thread/pool.rs b/src/tools/rust-analyzer/crates/stdx/src/thread/pool.rs index 2ddd7da74c2..9acc1de922a 100644 --- a/src/tools/rust-analyzer/crates/stdx/src/thread/pool.rs +++ b/src/tools/rust-analyzer/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) { |
