rust_analyzer/
task_pool.rs1use std::panic::UnwindSafe;
5
6use crossbeam_channel::Sender;
7use stdx::thread::{Pool, ThreadIntent};
8
9use crate::main_loop::DeferredTask;
10
11pub(crate) struct TaskPool<T> {
12 sender: Sender<T>,
13 pool: Pool,
14}
15
16impl<T> TaskPool<T> {
17 pub(crate) fn new_with_threads(sender: Sender<T>, threads: usize) -> TaskPool<T> {
18 TaskPool { sender, pool: Pool::new(threads) }
19 }
20
21 pub(crate) fn spawn<F>(&mut self, intent: ThreadIntent, task: F)
22 where
23 F: FnOnce() -> T + Send + UnwindSafe + 'static,
24 T: Send + 'static,
25 {
26 self.pool.spawn(intent, {
27 let sender = self.sender.clone();
28 move || sender.send(task()).unwrap()
29 })
30 }
31
32 pub(crate) fn spawn_with_sender<F>(&mut self, intent: ThreadIntent, task: F)
33 where
34 F: FnOnce(Sender<T>) + Send + UnwindSafe + 'static,
35 T: Send + 'static,
36 {
37 self.pool.spawn(intent, {
38 let sender = self.sender.clone();
39 move || task(sender)
40 })
41 }
42
43 pub(crate) fn len(&self) -> usize {
44 self.pool.len()
45 }
46
47 pub(crate) fn is_empty(&self) -> bool {
48 self.pool.is_empty()
49 }
50}
51
52pub(crate) struct DeferredTaskQueue {
57 pub(crate) sender: crossbeam_channel::Sender<DeferredTask>,
58 pub(crate) receiver: crossbeam_channel::Receiver<DeferredTask>,
59}