Use signal.alarm() for py2 timeout

This commit is contained in:
Kyle Altendorf 2018-10-04 23:11:26 -04:00
parent 0d095fc978
commit 900cef6397
1 changed files with 21 additions and 14 deletions

View File

@ -2,11 +2,13 @@
from __future__ import absolute_import, division, print_function from __future__ import absolute_import, division, print_function
import codecs import codecs
import contextlib
import gc import gc
import os import os
import platform import platform
import re import re
import subprocess import subprocess
import signal
import six import six
import sys import sys
import time import time
@ -1076,6 +1078,21 @@ class Testdir(object):
popen.wait() popen.wait()
raise self.TimeoutExpired(timeout_message) raise self.TimeoutExpired(timeout_message)
@contextlib.contextmanager
def timeout_manager(handler, timeout):
original_handler = signal.getsignal(signal.SIGALRM)
if original_handler != signal.SIG_DFL:
# TODO: use an informative exception
raise Exception()
signal.signal(signal.SIGALRM, handler)
signal.alarm(timeout)
yield
signal.alarm(0)
signal.signal(signal.SIGALRM, original_handler)
if timeout is None: if timeout is None:
ret = popen.wait() ret = popen.wait()
elif six.PY3: elif six.PY3:
@ -1084,20 +1101,10 @@ class Testdir(object):
except subprocess.TimeoutExpired: except subprocess.TimeoutExpired:
handle_timeout() handle_timeout()
else: else:
end = time.time() + timeout with timeout_manager(
handler=lambda _1, _2: handle_timeout(), timeout=timeout
resolution = min(0.1, timeout / 10) ):
ret = popen.wait()
while True:
ret = popen.poll()
if ret is not None:
break
remaining = end - time.time()
if remaining <= 0:
handle_timeout()
time.sleep(resolution)
finally: finally:
f1.close() f1.close()
f2.close() f2.close()