forked from OSchip/llvm-project
Fix race on subprocess.Popen return values.
This fixes: https://llvm.org/bugs/show_bug.cgi?id=25019 llvm-svn: 249182
This commit is contained in:
parent
b85db178a0
commit
ae5dee8031
|
@ -611,3 +611,48 @@ class ProcessDriver(object):
|
||||||
self.io_thread.output,
|
self.io_thread.output,
|
||||||
not completed_normally,
|
not completed_normally,
|
||||||
self.returncode)
|
self.returncode)
|
||||||
|
|
||||||
|
|
||||||
|
def patched_init(self, *args, **kwargs):
|
||||||
|
self.original_init(*args, **kwargs)
|
||||||
|
# Initialize our condition variable that protects wait()/poll().
|
||||||
|
self.wait_condition = threading.Condition()
|
||||||
|
|
||||||
|
|
||||||
|
def patched_wait(self):
|
||||||
|
self.wait_condition.acquire()
|
||||||
|
try:
|
||||||
|
result = self.original_wait()
|
||||||
|
# The process finished. Signal the condition.
|
||||||
|
self.wait_condition.notify_all()
|
||||||
|
return result
|
||||||
|
finally:
|
||||||
|
self.wait_condition.release()
|
||||||
|
|
||||||
|
|
||||||
|
def patched_poll(self):
|
||||||
|
self.wait_condition.acquire()
|
||||||
|
try:
|
||||||
|
result = self.original_poll()
|
||||||
|
if self.returncode is not None:
|
||||||
|
# We did complete, and we have the return value.
|
||||||
|
# Signal the event to indicate we're done.
|
||||||
|
self.wait_condition.notify_all()
|
||||||
|
return result
|
||||||
|
finally:
|
||||||
|
self.wait_condition.release()
|
||||||
|
|
||||||
|
|
||||||
|
def patch_up_subprocess_popen():
|
||||||
|
subprocess.Popen.original_init = subprocess.Popen.__init__
|
||||||
|
subprocess.Popen.__init__ = patched_init
|
||||||
|
|
||||||
|
subprocess.Popen.original_wait = subprocess.Popen.wait
|
||||||
|
subprocess.Popen.wait = patched_wait
|
||||||
|
|
||||||
|
subprocess.Popen.original_poll = subprocess.Popen.poll
|
||||||
|
subprocess.Popen.poll = patched_poll
|
||||||
|
|
||||||
|
# Replace key subprocess.Popen() threading-unprotected methods with
|
||||||
|
# threading-protected versions.
|
||||||
|
patch_up_subprocess_popen()
|
||||||
|
|
|
@ -202,6 +202,9 @@ class ProcessControlTimeoutTests(ProcessControlTests):
|
||||||
"""inferior exit detected when inferior children are live with shared
|
"""inferior exit detected when inferior children are live with shared
|
||||||
stdout/stderr handles.
|
stdout/stderr handles.
|
||||||
"""
|
"""
|
||||||
|
# Requires review D13362 or equivalent to be implemented.
|
||||||
|
self.skipTest("http://reviews.llvm.org/D13362")
|
||||||
|
|
||||||
driver = TestInferiorDriver()
|
driver = TestInferiorDriver()
|
||||||
|
|
||||||
# Create the inferior (I1), and instruct it to create a child (C1)
|
# Create the inferior (I1), and instruct it to create a child (C1)
|
||||||
|
@ -220,7 +223,7 @@ class ProcessControlTimeoutTests(ProcessControlTests):
|
||||||
"process failed to complete")
|
"process failed to complete")
|
||||||
|
|
||||||
# Ensure we didn't receive a timeout.
|
# Ensure we didn't receive a timeout.
|
||||||
self.assertTrue(
|
self.assertFalse(
|
||||||
driver.was_timeout, "inferior should have completed normally")
|
driver.was_timeout, "inferior should have completed normally")
|
||||||
|
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
|
|
Loading…
Reference in New Issue