jobserver: fix rare race condition in previous timer-exception workaround.

We have to clear the setitimer *before* leaving the try/except clause,
or the timer might fire between the try/except and the try/finally,
leaking a TimeoutError.

Reported-by: Denton Gentry
This commit is contained in:
Avery Pennarun 2021-07-27 12:59:55 -04:00 committed by apenwarr
commit 7f00abc36b

View file

@ -178,17 +178,17 @@ def _try_read(fd, n):
signal.setitimer(signal.ITIMER_REAL, 0.01, 0.01) # emergency fallback signal.setitimer(signal.ITIMER_REAL, 0.01, 0.01) # emergency fallback
try: try:
b = os.read(fd, 1) b = os.read(fd, 1)
except TimeoutError: finally:
signal.setitimer(signal.ITIMER_REAL, 0, 0)
signal.signal(signal.SIGALRM, oldh)
except TimeoutError:
return None # try again
except OSError as e:
if e.errno in (errno.EAGAIN, errno.EINTR):
# interrupted or it was nonblocking
return None # try again return None # try again
except OSError as e: else:
if e.errno in (errno.EAGAIN, errno.EINTR): raise
# interrupted or it was nonblocking
return None # try again
else:
raise
finally:
signal.setitimer(signal.ITIMER_REAL, 0, 0)
signal.signal(signal.SIGALRM, oldh)
return b return b