22
33use std:: {
44 io:: { self , BufRead , BufReader , Read , Write } ,
5+ panic:: AssertUnwindSafe ,
56 process:: { Child , ChildStdin , ChildStdout , Command , Stdio } ,
6- sync:: { Arc , Mutex } ,
7+ sync:: { Arc , Mutex , OnceLock } ,
78} ;
89
910use paths:: AbsPath ;
@@ -22,15 +23,15 @@ pub(crate) struct ProcMacroProcessSrv {
2223 state : Mutex < ProcessSrvState > ,
2324 version : u32 ,
2425 mode : SpanMode ,
26+ /// Populated when the server exits.
27+ exited : OnceLock < AssertUnwindSafe < ServerError > > ,
2528}
2629
2730#[ derive( Debug ) ]
2831struct ProcessSrvState {
2932 process : Process ,
3033 stdin : ChildStdin ,
3134 stdout : BufReader < ChildStdout > ,
32- /// Populated when the server exits.
33- server_exited : Option < ServerError > ,
3435}
3536
3637impl ProcMacroProcessSrv {
@@ -44,9 +45,10 @@ impl ProcMacroProcessSrv {
4445 let ( stdin, stdout) = process. stdio ( ) . expect ( "couldn't access child stdio" ) ;
4546
4647 io:: Result :: Ok ( ProcMacroProcessSrv {
47- state : Mutex :: new ( ProcessSrvState { process, stdin, stdout, server_exited : None } ) ,
48+ state : Mutex :: new ( ProcessSrvState { process, stdin, stdout } ) ,
4849 version : 0 ,
4950 mode : SpanMode :: Id ,
51+ exited : OnceLock :: new ( ) ,
5052 } )
5153 } ;
5254 let mut srv = create_srv ( true ) ?;
@@ -77,6 +79,10 @@ impl ProcMacroProcessSrv {
7779 }
7880 }
7981
82+ pub ( crate ) fn exited ( & self ) -> Option < & ServerError > {
83+ self . exited . get ( ) . map ( |it| & it. 0 )
84+ }
85+
8086 pub ( crate ) fn version ( & self ) -> u32 {
8187 self . version
8288 }
@@ -118,36 +124,52 @@ impl ProcMacroProcessSrv {
118124 }
119125
120126 pub ( crate ) fn send_task ( & self , req : Request ) -> Result < Response , ServerError > {
121- let state = & mut * self . state . lock ( ) . unwrap ( ) ;
122- if let Some ( server_error) = & state. server_exited {
123- return Err ( server_error. clone ( ) ) ;
127+ if let Some ( server_error) = self . exited . get ( ) {
128+ return Err ( server_error. 0 . clone ( ) ) ;
124129 }
125130
131+ let state = & mut * self . state . lock ( ) . unwrap ( ) ;
126132 let mut buf = String :: new ( ) ;
127- send_request ( & mut state. stdin , & mut state. stdout , req, & mut buf) . map_err ( |e| {
128- if e. io . as_ref ( ) . map ( |it| it. kind ( ) ) == Some ( io:: ErrorKind :: BrokenPipe ) {
129- match state. process . child . try_wait ( ) {
130- Ok ( None ) => e,
131- Ok ( Some ( status) ) => {
132- let mut msg = String :: new ( ) ;
133- if !status. success ( ) {
134- if let Some ( stderr) = state. process . child . stderr . as_mut ( ) {
135- _ = stderr. read_to_string ( & mut msg) ;
133+ send_request ( & mut state. stdin , & mut state. stdout , req, & mut buf)
134+ . and_then ( |res| {
135+ res. ok_or_else ( || {
136+ let message = "proc-macro server did not respond with data" . to_owned ( ) ;
137+ ServerError {
138+ io : Some ( Arc :: new ( io:: Error :: new (
139+ io:: ErrorKind :: BrokenPipe ,
140+ message. clone ( ) ,
141+ ) ) ) ,
142+ message,
143+ }
144+ } )
145+ } )
146+ . map_err ( |e| {
147+ if e. io . as_ref ( ) . map ( |it| it. kind ( ) ) == Some ( io:: ErrorKind :: BrokenPipe ) {
148+ match state. process . child . try_wait ( ) {
149+ Ok ( None ) | Err ( _) => e,
150+ Ok ( Some ( status) ) => {
151+ let mut msg = String :: new ( ) ;
152+ if !status. success ( ) {
153+ if let Some ( stderr) = state. process . child . stderr . as_mut ( ) {
154+ _ = stderr. read_to_string ( & mut msg) ;
155+ }
136156 }
157+ let server_error = ServerError {
158+ message : format ! (
159+ "proc-macro server exited with {status}{}{msg}" ,
160+ if msg. is_empty( ) { "" } else { ": " }
161+ ) ,
162+ io : None ,
163+ } ;
164+ // `AssertUnwindSafe` is fine here, we already correct initialized
165+ // server_error at this point.
166+ self . exited . get_or_init ( || AssertUnwindSafe ( server_error) ) . 0 . clone ( )
137167 }
138- let server_error = ServerError {
139- message : format ! ( "server exited with {status}: {msg}" ) ,
140- io : None ,
141- } ;
142- state. server_exited = Some ( server_error. clone ( ) ) ;
143- server_error
144168 }
145- Err ( _) => e,
169+ } else {
170+ e
146171 }
147- } else {
148- e
149- }
150- } )
172+ } )
151173 }
152174}
153175
@@ -201,7 +223,7 @@ fn send_request(
201223 mut reader : & mut impl BufRead ,
202224 req : Request ,
203225 buf : & mut String ,
204- ) -> Result < Response , ServerError > {
226+ ) -> Result < Option < Response > , ServerError > {
205227 req. write ( write_json, & mut writer) . map_err ( |err| ServerError {
206228 message : "failed to write request" . into ( ) ,
207229 io : Some ( Arc :: new ( err) ) ,
@@ -210,5 +232,5 @@ fn send_request(
210232 message : "failed to read response" . into ( ) ,
211233 io : Some ( Arc :: new ( err) ) ,
212234 } ) ?;
213- res . ok_or_else ( || ServerError { message : "server exited" . into ( ) , io : None } )
235+ Ok ( res )
214236}
0 commit comments