aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_proc_macro/src
diff options
context:
space:
mode:
authorEdwin Cheng <[email protected]>2020-03-31 14:51:43 +0100
committerEdwin Cheng <[email protected]>2020-03-31 15:20:19 +0100
commitf461dc48d116a97188ae6d9934c8e3b421c335ac (patch)
tree68b9ed76ec68766bc27f91328594bc8cd450be5a /crates/ra_proc_macro/src
parentb929d05c74702f44d2d59eede5e3379c6b725b4f (diff)
Use a weak ptr to hold the send end of channel
Diffstat (limited to 'crates/ra_proc_macro/src')
-rw-r--r--crates/ra_proc_macro/src/process.rs46
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)]
18pub(crate) struct ProcMacroProcessSrv { 19pub(crate) struct ProcMacroProcessSrv {
19 inner: Option<Sender<Task>>, 20 inner: Option<Weak<Sender<Task>>>,
20} 21}
21 22
22#[derive(Debug)] 23#[derive(Debug)]
23pub(crate) struct ProcMacroProcessThread { 24pub(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)] 30struct Task {
30struct SenderGuard(pub Sender<Task>); 31 req: Request,
31 32 result_tx: Sender<Response>,
32impl std::ops::Drop for SenderGuard {
33 fn drop(&mut self) {
34 self.0.send(Task::Close).unwrap();
35 }
36}
37
38enum Task {
39 Request { req: Request, result_tx: Sender<Response> },
40 Close,
41} 33}
42 34
43struct Process { 35struct 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,