comparison tests/run-tests.py @ 19413:a4de0d3dc35a

run-tests: lock popen wait/poll In python2.4, any call to Popen() may attempt to wait on any active process, and wait is not thread-safe. Make it thread-safe. See http://bugs.python.org/issue1731717 for details.
author Brendan Cully <brendan@kublai.com>
date Wed, 17 Jul 2013 12:45:12 -0700
parents ce3d1cf957f8
children b927ccf0f27d
comparison
equal deleted inserted replaced
19409:ea4342d0e6fe 19413:a4de0d3dc35a
57 import threading 57 import threading
58 import killdaemons as killmod 58 import killdaemons as killmod
59 import Queue as queue 59 import Queue as queue
60 60
61 processlock = threading.Lock() 61 processlock = threading.Lock()
62 waitlock = threading.Lock()
63
64 def waitlocked(fn):
65 def run():
66 waitlock.acquire()
67 ret = fn()
68 waitlock.release()
69 return ret
70 return run
62 71
63 closefds = os.name == 'posix' 72 closefds = os.name == 'posix'
64 def Popen4(cmd, wd, timeout, env=None): 73 def Popen4(cmd, wd, timeout, env=None):
65 processlock.acquire() 74 processlock.acquire()
66 p = subprocess.Popen(cmd, shell=True, bufsize=-1, cwd=wd, env=env, 75 p = subprocess.Popen(cmd, shell=True, bufsize=-1, cwd=wd, env=env,
67 close_fds=closefds, 76 close_fds=closefds,
68 stdin=subprocess.PIPE, stdout=subprocess.PIPE, 77 stdin=subprocess.PIPE, stdout=subprocess.PIPE,
69 stderr=subprocess.STDOUT) 78 stderr=subprocess.STDOUT)
79 p.wait = waitlocked(p.wait)
80 p.poll = waitlocked(p.poll)
70 processlock.release() 81 processlock.release()
71 82
72 p.fromchild = p.stdout 83 p.fromchild = p.stdout
73 p.tochild = p.stdin 84 p.tochild = p.stdin
74 p.childerr = p.stderr 85 p.childerr = p.stderr
836 except KeyboardInterrupt: 847 except KeyboardInterrupt:
837 vlog('# Handling keyboard interrupt') 848 vlog('# Handling keyboard interrupt')
838 cleanup() 849 cleanup()
839 raise 850 raise
840 851
841 try: 852 ret = proc.wait()
842 ret = proc.wait()
843 except OSError:
844 # Py2.4 seems to have a race here
845 pass
846 if wifexited(ret): 853 if wifexited(ret):
847 ret = os.WEXITSTATUS(ret) 854 ret = os.WEXITSTATUS(ret)
848 855
849 if proc.timeout: 856 if proc.timeout:
850 ret = 'timeout' 857 ret = 'timeout'