Redesign pmonitor()
This is tricky to get right, but I think it is correct to drain the buffers like this.
This commit is contained in:
+13
-8
@@ -412,6 +412,11 @@ def pmonitor(popens, timeoutms=500, readline=True,
|
|||||||
# Use non-blocking reads
|
# Use non-blocking reads
|
||||||
flags = fcntl( fd, F_GETFL )
|
flags = fcntl( fd, F_GETFL )
|
||||||
fcntl( fd, F_SETFL, flags | O_NONBLOCK )
|
fcntl( fd, F_SETFL, flags | O_NONBLOCK )
|
||||||
|
def readit( f ):
|
||||||
|
"Helper function - read line or data"
|
||||||
|
# Note this will block if readline is True
|
||||||
|
line = f.readline() if readline else f.read( readmax )
|
||||||
|
return decode( line )
|
||||||
while popens:
|
while popens:
|
||||||
fds = poller.poll( timeoutms )
|
fds = poller.poll( timeoutms )
|
||||||
if fds:
|
if fds:
|
||||||
@@ -419,15 +424,15 @@ def pmonitor(popens, timeoutms=500, readline=True,
|
|||||||
host = fdToHost[ fd ]
|
host = fdToHost[ fd ]
|
||||||
popen = popens[ host ]
|
popen = popens[ host ]
|
||||||
if event & POLLIN:
|
if event & POLLIN:
|
||||||
if readline:
|
line = readit( popen.stdout )
|
||||||
# Attempt to read a line of output
|
|
||||||
# This blocks until we receive a newline!
|
|
||||||
line = decode( popen.stdout.readline() )
|
|
||||||
else:
|
|
||||||
line = decode( popen.stdout.read( readmax ) )
|
|
||||||
yield host, line
|
yield host, line
|
||||||
# Check for EOF
|
if event & POLLHUP:
|
||||||
elif event & POLLHUP:
|
while True:
|
||||||
|
# Drain buffer
|
||||||
|
line = readit( popen.stdout )
|
||||||
|
yield host, line
|
||||||
|
if line == '':
|
||||||
|
break
|
||||||
poller.unregister( fd )
|
poller.unregister( fd )
|
||||||
del popens[ host ]
|
del popens[ host ]
|
||||||
else:
|
else:
|
||||||
|
|||||||
Reference in New Issue
Block a user