Eryk Sun <eryk...@gmail.com> added the comment:

Alternatively, instead of special casing the file type and spinning on 
PeekNamedPipe, the workaround could be based on a multiple-object wait that 
includes the child process handle. In this case, communicate() would always 
call _communicate in Windows, regardless of the timeout or number of pipes -- 
because simplistically calling either self.stdout.read() or self.stderr.read() 
could hang. 

The implementation would be moderately complicated. If we stop waiting on the 
reader threads because the process exited, we can give the threads a short time 
to finish reading and close the files -- maybe 250 ms is enough. But if they 
haven't exited at this time, we can't simply raise a TimeoutExpired exception 
if the call hasn't actually timed out.  To finish the _communicate call, we 
would have to cancel the pending reads and join() the threads.

We can force a reader thread to exit by canceling the read via WINAPI 
CancelIoEx. However, _readerthread has to be modified to support this. It could 
be implemented as a loop that calls _winapi.ReadFile to read the output in 
chunks that get appended to the buffer list. The read loop would break for 
either ERROR_BROKEN_PIPE or ERROR_OPERATION_ABORTED (canceled). 

The final step in _communicate would be to concatenate the partial reads. If 
it's text mode, it would also have to decode the bytes and translate newlines. 
The POSIX implementation of _communicate has to do this, so we already have a 
_translate_newlines method for this case.

Note that _winapi.WaitForMultipleObjects is interruptible in the main thread 
via Ctrl+C, which is a bonus improvement since Thread.join() can't be 
interrupted in Windows.

----------

_______________________________________
Python tracker <rep...@bugs.python.org>
<https://bugs.python.org/issue37531>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to