Skip to content

Commit 5a9ca31

Browse files
Remove proc macro management thread
1 parent 552b50d commit 5a9ca31

File tree

3 files changed

+42
-69
lines changed

3 files changed

+42
-69
lines changed

crates/proc_macro_api/src/lib.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ use std::{
2020

2121
use tt::{SmolStr, Subtree};
2222

23-
use crate::process::{ProcMacroProcessSrv, ProcMacroProcessThread};
23+
use crate::process::ProcMacroProcessSrv;
2424

2525
pub use rpc::{ExpansionResult, ExpansionTask, ListMacrosResult, ListMacrosTask, ProcMacroKind};
2626
pub use version::{read_dylib_info, RustCInfo};
@@ -64,16 +64,16 @@ impl base_db::ProcMacroExpander for ProcMacroProcessExpander {
6464
#[derive(Debug)]
6565
pub struct ProcMacroClient {
6666
process: Arc<ProcMacroProcessSrv>,
67-
thread: ProcMacroProcessThread,
6867
}
6968

7069
impl ProcMacroClient {
70+
/// Spawns an external process as the proc macro server and returns a client connected to it.
7171
pub fn extern_process(
7272
process_path: PathBuf,
7373
args: impl IntoIterator<Item = impl AsRef<OsStr>>,
7474
) -> io::Result<ProcMacroClient> {
75-
let (thread, process) = ProcMacroProcessSrv::run(process_path, args)?;
76-
Ok(ProcMacroClient { process: Arc::new(process), thread })
75+
let process = ProcMacroProcessSrv::run(process_path, args)?;
76+
Ok(ProcMacroClient { process: Arc::new(process) })
7777
}
7878

7979
pub fn by_dylib_path(&self, dylib_path: &Path) -> Vec<ProcMacro> {

crates/proc_macro_api/src/process.rs

Lines changed: 37 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -3,52 +3,45 @@
33
use std::{
44
convert::{TryFrom, TryInto},
55
ffi::{OsStr, OsString},
6+
fmt,
67
io::{self, BufRead, BufReader, Write},
78
path::{Path, PathBuf},
8-
process::{Child, Command, Stdio},
9-
sync::{Arc, Weak},
9+
process::{Child, ChildStdin, ChildStdout, Command, Stdio},
10+
sync::Mutex,
1011
};
1112

12-
use crossbeam_channel::{bounded, Receiver, Sender};
1313
use stdx::JodChild;
1414

1515
use crate::{
1616
msg::{ErrorCode, Message, Request, Response, ResponseError},
1717
rpc::{ListMacrosResult, ListMacrosTask, ProcMacroKind},
1818
};
1919

20-
#[derive(Debug, Default)]
2120
pub(crate) struct ProcMacroProcessSrv {
22-
inner: Weak<Sender<Task>>,
21+
process: Mutex<Process>,
22+
stdio: Mutex<(ChildStdin, BufReader<ChildStdout>)>,
2323
}
2424

25-
#[derive(Debug)]
26-
pub(crate) struct ProcMacroProcessThread {
27-
// XXX: drop order is significant
28-
sender: Arc<Sender<Task>>,
29-
handle: jod_thread::JoinHandle<()>,
25+
impl fmt::Debug for ProcMacroProcessSrv {
26+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
27+
f.debug_struct("ProcMacroProcessSrv").field("process", &self.process).finish()
28+
}
3029
}
3130

3231
impl ProcMacroProcessSrv {
3332
pub(crate) fn run(
3433
process_path: PathBuf,
3534
args: impl IntoIterator<Item = impl AsRef<OsStr>>,
36-
) -> io::Result<(ProcMacroProcessThread, ProcMacroProcessSrv)> {
37-
let process = Process::run(process_path, args)?;
38-
39-
let (task_tx, task_rx) = bounded(0);
40-
let handle = jod_thread::Builder::new()
41-
.name("ProcMacroClient".to_owned())
42-
.spawn(move || {
43-
client_loop(task_rx, process);
44-
})
45-
.expect("failed to spawn thread");
46-
47-
let task_tx = Arc::new(task_tx);
48-
let srv = ProcMacroProcessSrv { inner: Arc::downgrade(&task_tx) };
49-
let thread = ProcMacroProcessThread { handle, sender: task_tx };
50-
51-
Ok((thread, srv))
35+
) -> io::Result<ProcMacroProcessSrv> {
36+
let mut process = Process::run(process_path, args)?;
37+
let (stdin, stdout) = process.stdio().expect("couldn't access child stdio");
38+
39+
let srv = ProcMacroProcessSrv {
40+
process: Mutex::new(process),
41+
stdio: Mutex::new((stdin, stdout)),
42+
};
43+
44+
Ok(srv)
5245
}
5346

5447
pub(crate) fn find_proc_macros(
@@ -65,38 +58,15 @@ impl ProcMacroProcessSrv {
6558
where
6659
R: TryFrom<Response, Error = &'static str>,
6760
{
68-
let (result_tx, result_rx) = bounded(0);
69-
let sender = match self.inner.upgrade() {
70-
None => return Err(tt::ExpansionError::Unknown("proc macro process is closed".into())),
71-
Some(it) => it,
72-
};
73-
sender
74-
.send(Task { req, result_tx })
75-
.map_err(|_| tt::ExpansionError::Unknown("proc macro server crashed".into()))?;
61+
let mut guard = self.stdio.lock().unwrap_or_else(|e| e.into_inner());
62+
let stdio = &mut *guard;
63+
let (stdin, stdout) = (&mut stdio.0, &mut stdio.1);
7664

77-
let res = result_rx
78-
.recv()
79-
.map_err(|_| tt::ExpansionError::Unknown("proc macro server crashed".into()))?;
80-
81-
match res {
82-
Some(Response::Error(err)) => Err(tt::ExpansionError::ExpansionError(err.message)),
83-
Some(res) => Ok(res.try_into().map_err(|err| {
84-
tt::ExpansionError::Unknown(format!("Fail to get response, reason : {:#?} ", err))
85-
})?),
86-
None => Err(tt::ExpansionError::Unknown("Empty result".into())),
87-
}
88-
}
89-
}
90-
91-
fn client_loop(task_rx: Receiver<Task>, mut process: Process) {
92-
let (mut stdin, mut stdout) = process.stdio().expect("couldn't access child stdio");
93-
94-
let mut buf = String::new();
95-
96-
for Task { req, result_tx } in task_rx {
97-
match send_request(&mut stdin, &mut stdout, req, &mut buf) {
98-
Ok(res) => result_tx.send(res).unwrap(),
65+
let mut buf = String::new();
66+
let res = match send_request(stdin, stdout, req, &mut buf) {
67+
Ok(res) => res,
9968
Err(err) => {
69+
let mut process = self.process.lock().unwrap_or_else(|e| e.into_inner());
10070
log::error!(
10171
"proc macro server crashed, server process state: {:?}, server request error: {:?}",
10272
process.child.try_wait(),
@@ -106,19 +76,21 @@ fn client_loop(task_rx: Receiver<Task>, mut process: Process) {
10676
code: ErrorCode::ServerErrorEnd,
10777
message: "proc macro server crashed".into(),
10878
});
109-
result_tx.send(res.into()).unwrap();
110-
// Exit the thread.
111-
break;
79+
Some(res)
11280
}
81+
};
82+
83+
match res {
84+
Some(Response::Error(err)) => Err(tt::ExpansionError::ExpansionError(err.message)),
85+
Some(res) => Ok(res.try_into().map_err(|err| {
86+
tt::ExpansionError::Unknown(format!("Fail to get response, reason : {:#?} ", err))
87+
})?),
88+
None => Err(tt::ExpansionError::Unknown("Empty result".into())),
11389
}
11490
}
11591
}
11692

117-
struct Task {
118-
req: Request,
119-
result_tx: Sender<Option<Response>>,
120-
}
121-
93+
#[derive(Debug)]
12294
struct Process {
12395
child: JodChild,
12496
}
@@ -133,7 +105,7 @@ impl Process {
133105
Ok(Process { child })
134106
}
135107

136-
fn stdio(&mut self) -> Option<(impl Write, impl BufRead)> {
108+
fn stdio(&mut self) -> Option<(ChildStdin, BufReader<ChildStdout>)> {
137109
let stdin = self.child.stdin.take()?;
138110
let stdout = self.child.stdout.take()?;
139111
let read = BufReader::new(stdout);

crates/stdx/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ pub fn defer<F: FnOnce()>(f: F) -> impl Drop {
111111
}
112112

113113
#[cfg_attr(not(target_arch = "wasm32"), repr(transparent))]
114+
#[derive(Debug)]
114115
pub struct JodChild(pub std::process::Child);
115116

116117
impl ops::Deref for JodChild {

0 commit comments

Comments
 (0)