@@ -5,54 +5,38 @@ use std::{
5
5
ffi:: { OsStr , OsString } ,
6
6
io:: { self , BufRead , BufReader , Write } ,
7
7
path:: { Path , PathBuf } ,
8
- process:: { Child , Command , Stdio } ,
9
- sync:: { Arc , Weak } ,
8
+ process:: { Child , ChildStdin , ChildStdout , Command , Stdio } ,
10
9
} ;
11
10
12
- use crossbeam_channel:: { bounded, Receiver , Sender } ;
13
11
use stdx:: JodChild ;
14
12
15
13
use crate :: {
16
14
msg:: { ErrorCode , Message , Request , Response , ResponseError } ,
17
15
rpc:: { ListMacrosResult , ListMacrosTask , ProcMacroKind } ,
18
16
} ;
19
17
20
- #[ derive( Debug , Default ) ]
21
- pub ( crate ) struct ProcMacroProcessSrv {
22
- inner : Weak < Sender < Task > > ,
23
- }
24
-
25
18
#[ derive( Debug ) ]
26
- pub ( crate ) struct ProcMacroProcessThread {
27
- // XXX: drop order is significant
28
- sender : Arc < Sender < Task > > ,
29
- handle : jod_thread :: JoinHandle < ( ) > ,
19
+ pub ( crate ) struct ProcMacroProcessSrv {
20
+ process : Process ,
21
+ stdin : ChildStdin ,
22
+ stdout : BufReader < ChildStdout > ,
30
23
}
31
24
32
25
impl ProcMacroProcessSrv {
33
26
pub ( crate ) fn run (
34
27
process_path : PathBuf ,
35
28
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) )
29
+ ) -> io:: Result < ProcMacroProcessSrv > {
30
+ let mut process = Process :: run ( process_path, args) ?;
31
+ let ( stdin, stdout) = process. stdio ( ) . expect ( "couldn't access child stdio" ) ;
32
+
33
+ let srv = ProcMacroProcessSrv { process, stdin, stdout } ;
34
+
35
+ Ok ( srv)
52
36
}
53
37
54
38
pub ( crate ) fn find_proc_macros (
55
- & self ,
39
+ & mut self ,
56
40
dylib_path : & Path ,
57
41
) -> Result < Vec < ( String , ProcMacroKind ) > , tt:: ExpansionError > {
58
42
let task = ListMacrosTask { lib : dylib_path. to_path_buf ( ) } ;
@@ -61,64 +45,39 @@ impl ProcMacroProcessSrv {
61
45
Ok ( result. macros )
62
46
}
63
47
64
- pub ( crate ) fn send_task < R > ( & self , req : Request ) -> Result < R , tt:: ExpansionError >
48
+ pub ( crate ) fn send_task < R > ( & mut self , req : Request ) -> Result < R , tt:: ExpansionError >
65
49
where
66
50
R : TryFrom < Response , Error = & ' static str > ,
67
51
{
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 ( ) ) ) ?;
76
-
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 ( ) ,
52
+ let mut buf = String :: new ( ) ;
53
+ let res = match send_request ( & mut self . stdin , & mut self . stdout , req, & mut buf) {
54
+ Ok ( res) => res,
99
55
Err ( err) => {
56
+ let result = self . process . child . try_wait ( ) ;
100
57
log:: error!(
101
58
"proc macro server crashed, server process state: {:?}, server request error: {:?}" ,
102
- process . child . try_wait ( ) ,
59
+ result ,
103
60
err
104
61
) ;
105
62
let res = Response :: Error ( ResponseError {
106
63
code : ErrorCode :: ServerErrorEnd ,
107
64
message : "proc macro server crashed" . into ( ) ,
108
65
} ) ;
109
- result_tx. send ( res. into ( ) ) . unwrap ( ) ;
110
- // Exit the thread.
111
- break ;
66
+ Some ( res)
112
67
}
68
+ } ;
69
+
70
+ match res {
71
+ Some ( Response :: Error ( err) ) => Err ( tt:: ExpansionError :: ExpansionError ( err. message ) ) ,
72
+ Some ( res) => Ok ( res. try_into ( ) . map_err ( |err| {
73
+ tt:: ExpansionError :: Unknown ( format ! ( "Fail to get response, reason : {:#?} " , err) )
74
+ } ) ?) ,
75
+ None => Err ( tt:: ExpansionError :: Unknown ( "Empty result" . into ( ) ) ) ,
113
76
}
114
77
}
115
78
}
116
79
117
- struct Task {
118
- req : Request ,
119
- result_tx : Sender < Option < Response > > ,
120
- }
121
-
80
+ #[ derive( Debug ) ]
122
81
struct Process {
123
82
child : JodChild ,
124
83
}
@@ -133,7 +92,7 @@ impl Process {
133
92
Ok ( Process { child } )
134
93
}
135
94
136
- fn stdio ( & mut self ) -> Option < ( impl Write , impl BufRead ) > {
95
+ fn stdio ( & mut self ) -> Option < ( ChildStdin , BufReader < ChildStdout > ) > {
137
96
let stdin = self . child . stdin . take ( ) ?;
138
97
let stdout = self . child . stdout . take ( ) ?;
139
98
let read = BufReader :: new ( stdout) ;
0 commit comments