Author eryksun
Recipients eryksun, jeremy.kloth, jkloth, nanjekyejoannah, vstinner
Date 2019-08-23.19:19:05
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <>
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 or 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.
Date User Action Args
2019-08-23 19:19:06eryksunsetrecipients: + eryksun, vstinner, jkloth, jeremy.kloth, nanjekyejoannah
2019-08-23 19:19:06eryksunsetmessageid: <>
2019-08-23 19:19:06eryksunlinkissue37531 messages
2019-08-23 19:19:05eryksuncreate