diff options
author | Edwin Cheng <[email protected]> | 2020-03-31 14:51:43 +0100 |
---|---|---|
committer | Edwin Cheng <[email protected]> | 2020-03-31 15:20:19 +0100 |
commit | f461dc48d116a97188ae6d9934c8e3b421c335ac (patch) | |
tree | 68b9ed76ec68766bc27f91328594bc8cd450be5a /crates | |
parent | b929d05c74702f44d2d59eede5e3379c6b725b4f (diff) |
Use a weak ptr to hold the send end of channel
Diffstat (limited to 'crates')
-rw-r--r-- | crates/ra_proc_macro/src/process.rs | 46 |
1 files changed, 18 insertions, 28 deletions
diff --git a/crates/ra_proc_macro/src/process.rs b/crates/ra_proc_macro/src/process.rs index 07dc1bf9e..b44d6763c 100644 --- a/crates/ra_proc_macro/src/process.rs +++ b/crates/ra_proc_macro/src/process.rs | |||
@@ -12,32 +12,24 @@ use std::{ | |||
12 | io::{self, Write}, | 12 | io::{self, Write}, |
13 | path::{Path, PathBuf}, | 13 | path::{Path, PathBuf}, |
14 | process::{Child, Command, Stdio}, | 14 | process::{Child, Command, Stdio}, |
15 | sync::{Arc, Weak}, | ||
15 | }; | 16 | }; |
16 | 17 | ||
17 | #[derive(Debug, Default)] | 18 | #[derive(Debug, Default)] |
18 | pub(crate) struct ProcMacroProcessSrv { | 19 | pub(crate) struct ProcMacroProcessSrv { |
19 | inner: Option<Sender<Task>>, | 20 | inner: Option<Weak<Sender<Task>>>, |
20 | } | 21 | } |
21 | 22 | ||
22 | #[derive(Debug)] | 23 | #[derive(Debug)] |
23 | pub(crate) struct ProcMacroProcessThread { | 24 | pub(crate) struct ProcMacroProcessThread { |
24 | // XXX: drop order is significant | 25 | // XXX: drop order is significant |
25 | sender: SenderGuard, | 26 | sender: Arc<Sender<Task>>, |
26 | handle: jod_thread::JoinHandle<()>, | 27 | handle: jod_thread::JoinHandle<()>, |
27 | } | 28 | } |
28 | 29 | ||
29 | #[derive(Debug)] | 30 | struct Task { |
30 | struct SenderGuard(pub Sender<Task>); | 31 | req: Request, |
31 | 32 | result_tx: Sender<Response>, | |
32 | impl std::ops::Drop for SenderGuard { | ||
33 | fn drop(&mut self) { | ||
34 | self.0.send(Task::Close).unwrap(); | ||
35 | } | ||
36 | } | ||
37 | |||
38 | enum Task { | ||
39 | Request { req: Request, result_tx: Sender<Response> }, | ||
40 | Close, | ||
41 | } | 33 | } |
42 | 34 | ||
43 | struct Process { | 35 | struct Process { |
@@ -88,8 +80,9 @@ impl ProcMacroProcessSrv { | |||
88 | client_loop(task_rx, process); | 80 | client_loop(task_rx, process); |
89 | }); | 81 | }); |
90 | 82 | ||
91 | let srv = ProcMacroProcessSrv { inner: Some(task_tx.clone()) }; | 83 | let task_tx = Arc::new(task_tx); |
92 | let thread = ProcMacroProcessThread { handle, sender: SenderGuard(task_tx) }; | 84 | let srv = ProcMacroProcessSrv { inner: Some(Arc::downgrade(&task_tx)) }; |
85 | let thread = ProcMacroProcessThread { handle, sender: task_tx }; | ||
93 | 86 | ||
94 | Ok((thread, srv)) | 87 | Ok((thread, srv)) |
95 | } | 88 | } |
@@ -131,8 +124,13 @@ impl ProcMacroProcessSrv { | |||
131 | }; | 124 | }; |
132 | 125 | ||
133 | let (result_tx, result_rx) = bounded(0); | 126 | let (result_tx, result_rx) = bounded(0); |
134 | 127 | let sender = match sender.upgrade() { | |
135 | sender.send(Task::Request { req: req.into(), result_tx }).unwrap(); | 128 | None => { |
129 | return Err(ra_tt::ExpansionError::Unknown("Proc macro process is closed.".into())) | ||
130 | } | ||
131 | Some(it) => it, | ||
132 | }; | ||
133 | sender.send(Task { req: req.into(), result_tx }).unwrap(); | ||
136 | 134 | ||
137 | let res = result_rx.recv().unwrap(); | 135 | let res = result_rx.recv().unwrap(); |
138 | match res { | 136 | match res { |
@@ -155,16 +153,8 @@ fn client_loop(task_rx: Receiver<Task>, mut process: Process) { | |||
155 | Some(it) => it, | 153 | Some(it) => it, |
156 | }; | 154 | }; |
157 | 155 | ||
158 | loop { | 156 | for task in task_rx { |
159 | let task = match task_rx.recv() { | 157 | let Task { req, result_tx } = task; |
160 | Ok(task) => task, | ||
161 | Err(_) => break, | ||
162 | }; | ||
163 | |||
164 | let (req, result_tx) = match task { | ||
165 | Task::Request { req, result_tx } => (req, result_tx), | ||
166 | Task::Close => break, | ||
167 | }; | ||
168 | 158 | ||
169 | let res = match send_request(&mut stdin, &mut stdout, req) { | 159 | let res = match send_request(&mut stdin, &mut stdout, req) { |
170 | Ok(res) => res, | 160 | Ok(res) => res, |