queue_processors: Use try…finally to prevent leaking an alarm.

Otherwise, if consume_func raised an exception for any reason *other*
than the alarm being fired, the still-pending alarm would have fired
later at some arbitrary point in the calling code.

We need two try…finally blocks in case the signal arrives just before
signal.alarm(0).

Signed-off-by: Anders Kaseorg <anders@zulip.com>
This commit is contained in:
Anders Kaseorg 2020-10-06 18:05:17 -07:00 committed by Tim Abbott
parent 52c411df8a
commit 9bfbb29763
1 changed files with 12 additions and 4 deletions

View File

@ -263,10 +263,18 @@ class QueueProcessingWorker(ABC):
time_start = time.time() time_start = time.time()
if self.MAX_CONSUME_SECONDS and self.ENABLE_TIMEOUTS: if self.MAX_CONSUME_SECONDS and self.ENABLE_TIMEOUTS:
signal.signal(signal.SIGALRM, functools.partial(timer_expired, self.MAX_CONSUME_SECONDS, len(events))) try:
signal.alarm(self.MAX_CONSUME_SECONDS * len(events)) signal.signal(
consume_func(events) signal.SIGALRM,
signal.alarm(0) functools.partial(timer_expired, self.MAX_CONSUME_SECONDS, len(events)),
)
try:
signal.alarm(self.MAX_CONSUME_SECONDS * len(events))
consume_func(events)
finally:
signal.alarm(0)
finally:
signal.signal(signal.SIGALRM, signal.SIG_DFL)
else: else:
consume_func(events) consume_func(events)
consume_time_seconds = time.time() - time_start consume_time_seconds = time.time() - time_start