@@ -192,9 +192,19 @@ def _read(data):
192192_OUT = POLLOUT | POLLHUP | POLLERR
193193# The event mask for which to poll for a read channel (such as stdout).
194194_IN = POLLPRI | POLLHUP | POLLIN
195- # The event mask describing all error events on which we close the
196- # respective file descriptor.
197- _ERR = POLLHUP | POLLERR | POLLNVAL
195+
196+
197+ def eventToString (events ):
198+ """Convert an event set to a human readable string."""
199+ errors = {
200+ POLLERR : "ERR" ,
201+ POLLHUP : "HUP" ,
202+ POLLIN : "IN" ,
203+ POLLNVAL : "NVAL" ,
204+ POLLOUT : "OUT" ,
205+ POLLPRI : "PRI" ,
206+ }
207+ return "|" .join ([v for k , v in errors .items () if k & events ])
198208
199209
200210class _PipelineFileDescriptors :
@@ -294,17 +304,39 @@ def pollRead(data):
294304 if event & POLLOUT :
295305 close = _write (data )
296306 elif event & POLLIN or event & POLLPRI :
297- close = _read (data )
307+ if event & POLLHUP :
308+ # In case we received a combination of a data-is-available
309+ # and a HUP event we need to make sure that we flush the
310+ # entire pipe buffer before we stop the polling. Otherwise
311+ # we might leave data unread that was successfully sent to
312+ # us.
313+ # Note that from a logical point of view this problem
314+ # occurs only in the receive case. In the write case we
315+ # have full control over the file descriptor ourselves and
316+ # if the remote side closes its part there is no point in
317+ # sending any more data.
318+ while not _read (data ):
319+ pass
320+ else :
321+ close = _read (data )
298322
299323 # We explicitly (and early, compared to the defers we
300- # scheduled previously) close the file descriptor on all error
301- # events and POLLHUP, or when we received EOF (for reading) or
302- # run out of data to send (for writing).
303- if event & _ERR or close :
324+ # scheduled previously) close the file descriptor on POLLHUP,
325+ # when we received EOF (for reading), or run out of data to
326+ # send (for writing).
327+ if event & POLLHUP or close :
304328 data ["close" ]()
305329 data ["unreg" ]()
306330 del polls [fd ]
307331
332+ # All error codes are reported to clients such that they can
333+ # deal with potentially incomplete data.
334+ if event & (POLLERR | POLLNVAL ):
335+ string = eventToString (event )
336+ error = "Error while polling for new data, event: {s} ({e})"
337+ error = error .format (s = string , e = event )
338+ raise ConnectionError (error )
339+
308340 return self ._stdout ["data" ] if self ._stdout else b"" ,\
309341 self ._stderr ["data" ] if self ._stderr else b""
310342
0 commit comments