]> git.lizzy.rs Git - rust.git/blob - src/tools/rust-analyzer/crates/rust-analyzer/src/task_pool.rs
:arrow_up: rust-analyzer
[rust.git] / src / tools / rust-analyzer / crates / rust-analyzer / src / task_pool.rs
1 //! A thin wrapper around `ThreadPool` to make sure that we join all things
2 //! properly.
3 use crossbeam_channel::Sender;
4
5 pub(crate) struct TaskPool<T> {
6     sender: Sender<T>,
7     inner: threadpool::ThreadPool,
8 }
9
10 impl<T> TaskPool<T> {
11     pub(crate) fn new(sender: Sender<T>) -> TaskPool<T> {
12         const STACK_SIZE: usize = 8 * 1024 * 1024;
13
14         let inner = threadpool::Builder::new()
15             .thread_name("Worker".into())
16             .thread_stack_size(STACK_SIZE)
17             .build();
18         TaskPool { sender, inner }
19     }
20
21     pub(crate) fn spawn<F>(&mut self, task: F)
22     where
23         F: FnOnce() -> T + Send + 'static,
24         T: Send + 'static,
25     {
26         self.inner.execute({
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, task: F)
33     where
34         F: FnOnce(Sender<T>) + Send + 'static,
35         T: Send + 'static,
36     {
37         self.inner.execute({
38             let sender = self.sender.clone();
39             move || task(sender)
40         })
41     }
42
43     pub(crate) fn len(&self) -> usize {
44         self.inner.queued_count()
45     }
46 }
47
48 impl<T> Drop for TaskPool<T> {
49     fn drop(&mut self) {
50         self.inner.join()
51     }
52 }