mirror of
https://github.com/valitydev/salt.git
synced 2024-11-08 17:33:54 +00:00
Preventing deadlock on subprocess.Popen.poll()
According to http://docs.python.org/2/library/subprocess.html#subprocess.Popen.poll Warning: This will deadlock when using stdout=PIPE and/or stderr=PIPE and the child process generates enough output to a pipe such that it blocks waiting for the OS pipe buffer to accept more data. Use communicate() to avoid that. We count consecutive iterations that do not have any output, and only if it reaches a certain threshold, self.communicate() is run.
This commit is contained in:
parent
92b37c37d6
commit
e5d284ef36
@ -208,13 +208,25 @@ class NonBlockingPopen(subprocess.Popen):
|
|||||||
fcntl.fcntl(conn, fcntl.F_SETFL, flags)
|
fcntl.fcntl(conn, fcntl.F_SETFL, flags)
|
||||||
|
|
||||||
def poll_and_read_until_finish(self):
|
def poll_and_read_until_finish(self):
|
||||||
|
silent_iterations = 0
|
||||||
while self.poll() is None:
|
while self.poll() is None:
|
||||||
if self.stdout is not None:
|
if self.stdout is not None:
|
||||||
|
silent_iterations = 0
|
||||||
self.recv()
|
self.recv()
|
||||||
|
|
||||||
if self.stderr is not None:
|
if self.stderr is not None:
|
||||||
|
silent_iterations = 0
|
||||||
self.recv_err()
|
self.recv_err()
|
||||||
|
|
||||||
|
silent_iterations += 1
|
||||||
|
|
||||||
|
if silent_iterations > 100:
|
||||||
|
silent_iterations = 0
|
||||||
|
(stdoutdata, stderrdata) = self.communicate()
|
||||||
|
if stdoutdata:
|
||||||
|
log.debug(stdoutdata)
|
||||||
|
if stderrdata:
|
||||||
|
log.error(stderrdata)
|
||||||
time.sleep(0.01)
|
time.sleep(0.01)
|
||||||
|
|
||||||
def communicate(self, input=None):
|
def communicate(self, input=None):
|
||||||
|
Loading…
Reference in New Issue
Block a user