def Popen(*args, **kwargs):
"""
Wrapper for subprocess.Popen() that provides thread-safety and works around
other known bugs.
"""
_popen_lock.acquire()
try:
# Python's subprocess module has a bug where it propagates the
# exception to the caller when it gets interrupted trying to read the
# status back from the child process, leaving the child process
# effectively orphaned and registering a false failure. To work around
# it, we temporarily replace os.read with a retrying version that
# allows Popen to succeed in this case.
class RetryFunc(object):
def __init__ (self, func):
import os
self.func = func
def __call__ (self, *args, **kwargs):
while True:
try:
return self.func(*args, **kwargs)
except OSError, e:
if e.errno != errno.EINTR:
raise
reader = RetryFunc(os.read)
os.read = reader
return subprocess.Popen(*args, **kwargs)
finally:
os.read = reader.func
_popen_lock.release()
评论列表
文章目录