aboutsummaryrefslogtreecommitdiff
path: root/crates/thread_worker
diff options
context:
space:
mode:
Diffstat (limited to 'crates/thread_worker')
-rw-r--r--crates/thread_worker/Cargo.toml10
-rw-r--r--crates/thread_worker/src/lib.rs49
2 files changed, 0 insertions, 59 deletions
diff --git a/crates/thread_worker/Cargo.toml b/crates/thread_worker/Cargo.toml
deleted file mode 100644
index e3babbf8d..000000000
--- a/crates/thread_worker/Cargo.toml
+++ /dev/null
@@ -1,10 +0,0 @@
1[package]
2edition = "2018"
3name = "thread_worker"
4version = "0.1.0"
5authors = ["rust-analyzer developers"]
6
7[dependencies]
8jod-thread = "0.1.0"
9crossbeam-channel = "0.3.5"
10log = "0.4.3"
diff --git a/crates/thread_worker/src/lib.rs b/crates/thread_worker/src/lib.rs
deleted file mode 100644
index 68e5c124d..000000000
--- a/crates/thread_worker/src/lib.rs
+++ /dev/null
@@ -1,49 +0,0 @@
1//! Small utility to correctly spawn crossbeam-channel based worker threads.
2
3use crossbeam_channel::{bounded, unbounded, Receiver, Sender};
4
5/// A wrapper around event-processing thread with automatic shutdown semantics.
6pub struct Worker<I, O> {
7 // XXX: field order is significant here.
8 //
9 // In Rust, fields are dropped in the declaration order, and we rely on this
10 // here. We must close input first, so that the `thread` (who holds the
11 // opposite side of the channel) noticed shutdown. Then, we must join the
12 // thread, but we must keep out alive so that the thread does not panic.
13 //
14 // Note that a potential problem here is that we might drop some messages
15 // from receiver on the floor. This is ok for rust-analyzer: we have only a
16 // single client, so, if we are shutting down, nobody is interested in the
17 // unfinished work anyway!
18 sender: Sender<I>,
19 _thread: jod_thread::JoinHandle<()>,
20 receiver: Receiver<O>,
21}
22
23impl<I, O> Worker<I, O> {
24 pub fn spawn<F>(name: &'static str, buf: usize, f: F) -> Worker<I, O>
25 where
26 F: FnOnce(Receiver<I>, Sender<O>) + Send + 'static,
27 I: Send + 'static,
28 O: Send + 'static,
29 {
30 // Set up worker channels in a deadlock-avoiding way. If one sets both input
31 // and output buffers to a fixed size, a worker might get stuck.
32 let (sender, input_receiver) = bounded::<I>(buf);
33 let (output_sender, receiver) = unbounded::<O>();
34 let _thread = jod_thread::Builder::new()
35 .name(name.to_string())
36 .spawn(move || f(input_receiver, output_sender))
37 .expect("failed to spawn a thread");
38 Worker { sender, _thread, receiver }
39 }
40}
41
42impl<I, O> Worker<I, O> {
43 pub fn sender(&self) -> &Sender<I> {
44 &self.sender
45 }
46 pub fn receiver(&self) -> &Receiver<O> {
47 &self.receiver
48 }
49}