Skip to content

Commit f461dc4

Browse files
committed
Use a weak ptr to hold the send end of channel
1 parent b929d05 commit f461dc4

File tree

1 file changed

+18
-28
lines changed

1 file changed

+18
-28
lines changed

crates/ra_proc_macro/src/process.rs

Lines changed: 18 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -12,32 +12,24 @@ use std::{
1212
io::{self, Write},
1313
path::{Path, PathBuf},
1414
process::{Child, Command, Stdio},
15+
sync::{Arc, Weak},
1516
};
1617

1718
#[derive(Debug, Default)]
1819
pub(crate) struct ProcMacroProcessSrv {
19-
inner: Option<Sender<Task>>,
20+
inner: Option<Weak<Sender<Task>>>,
2021
}
2122

2223
#[derive(Debug)]
2324
pub(crate) struct ProcMacroProcessThread {
2425
// XXX: drop order is significant
25-
sender: SenderGuard,
26+
sender: Arc<Sender<Task>>,
2627
handle: jod_thread::JoinHandle<()>,
2728
}
2829

29-
#[derive(Debug)]
30-
struct SenderGuard(pub Sender<Task>);
31-
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,
30+
struct Task {
31+
req: Request,
32+
result_tx: Sender<Response>,
4133
}
4234

4335
struct Process {
@@ -88,8 +80,9 @@ impl ProcMacroProcessSrv {
8880
client_loop(task_rx, process);
8981
});
9082

91-
let srv = ProcMacroProcessSrv { inner: Some(task_tx.clone()) };
92-
let thread = ProcMacroProcessThread { handle, sender: SenderGuard(task_tx) };
83+
let task_tx = Arc::new(task_tx);
84+
let srv = ProcMacroProcessSrv { inner: Some(Arc::downgrade(&task_tx)) };
85+
let thread = ProcMacroProcessThread { handle, sender: task_tx };
9386

9487
Ok((thread, srv))
9588
}
@@ -131,8 +124,13 @@ impl ProcMacroProcessSrv {
131124
};
132125

133126
let (result_tx, result_rx) = bounded(0);
134-
135-
sender.send(Task::Request { req: req.into(), result_tx }).unwrap();
127+
let sender = match sender.upgrade() {
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();
136134

137135
let res = result_rx.recv().unwrap();
138136
match res {
@@ -155,16 +153,8 @@ fn client_loop(task_rx: Receiver<Task>, mut process: Process) {
155153
Some(it) => it,
156154
};
157155

158-
loop {
159-
let task = match task_rx.recv() {
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-
};
156+
for task in task_rx {
157+
let Task { req, result_tx } = task;
168158

169159
let res = match send_request(&mut stdin, &mut stdout, req) {
170160
Ok(res) => res,

0 commit comments

Comments
 (0)