diff options
Diffstat (limited to 'crates/thread_worker')
-rw-r--r-- | crates/thread_worker/Cargo.toml | 10 | ||||
-rw-r--r-- | crates/thread_worker/src/lib.rs | 49 |
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] | ||
2 | edition = "2018" | ||
3 | name = "thread_worker" | ||
4 | version = "0.1.0" | ||
5 | authors = ["rust-analyzer developers"] | ||
6 | |||
7 | [dependencies] | ||
8 | jod-thread = "0.1.0" | ||
9 | crossbeam-channel = "0.3.5" | ||
10 | log = "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 | |||
3 | use crossbeam_channel::{bounded, unbounded, Receiver, Sender}; | ||
4 | |||
5 | /// A wrapper around event-processing thread with automatic shutdown semantics. | ||
6 | pub 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 | |||
23 | impl<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 | |||
42 | impl<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 | } | ||