@@ -138,7 +138,23 @@ fn supervise_stderr(
138138 Some ( err) => Err ( err) ,
139139 None => match res {
140140 Ok ( n) if n == wanted => Ok ( n) ,
141- Ok ( n) => self . recv . recv ( ) . ok ( ) . map ( Err ) . unwrap_or ( Ok ( n) ) ,
141+ Ok ( n) => {
142+ // TODO: fix this
143+ // When parsing refs this seems to happen legitimately
144+ // (even though we read packet lines only and should always know exactly how much to read)
145+ // Maybe this still happens in `read_exact()` as sometimes we just don't get enough bytes
146+ // despite knowing how many.
147+ // To prevent deadlock, we have to set a timeout which slows down legitimate parts of the protocol.
148+ // This code was specifically written to make the `cargo` test-suite pass, and we can reduce
149+ // the timeouts even more once there is a native ssh transport that is used by `cargo`, it will
150+ // be able to handle these properly.
151+ // Alternatively, one could implement something like `read2` to avoid blocking on stderr entirely.
152+ self . recv
153+ . recv_timeout ( std:: time:: Duration :: from_millis ( 5 ) )
154+ . ok ( )
155+ . map ( Err )
156+ . unwrap_or ( Ok ( n) )
157+ }
142158 Err ( err) => Err ( self . recv . recv ( ) . ok ( ) . unwrap_or ( err) ) ,
143159 } ,
144160 }
@@ -153,7 +169,7 @@ fn supervise_stderr(
153169
154170 let ( send, recv) = std:: sync:: mpsc:: sync_channel ( 1 ) ;
155171 std:: thread:: Builder :: new ( )
156- . name ( "supervise ssh" . into ( ) )
172+ . name ( "supervise ssh stderr " . into ( ) )
157173 . stack_size ( 128 * 1024 )
158174 . spawn ( move || -> std:: io:: Result < ( ) > {
159175 let mut process_stderr = std:: io:: stderr ( ) ;
0 commit comments