From acbd59d0a8e47afb745c900432e5da2873dfd851 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Wed, 22 Jul 2015 17:05:46 +0300 Subject: [PATCH] eloop: Try to terminate more quickly on SIGINT and SIGTERM It was possible for the SIGINT/SIGTERM signal to be received while processing a pending timeout/socket/signal event and then get stuck in the following select() call before processing the signal event. If no other events show up within the two second SIGALRM trigger, process will be terminated forcefully even though there would have been possibility to do clean termination assuming no operationg blocked for that two second time. Handle this more cleanly by checking for eloop.pending_terminate before starting the select()/poll()/epoll_wait() wait for the following event. Terminate the loop if pending signal handling requests termination. In addition, make eloop_terminated() return 1 on eloop.pending_terminate in addition to eloop.terminate since the process will be terminated shortly and there is no point in starting additional processing. Signed-off-by: Jouni Malinen --- src/utils/eloop.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/utils/eloop.c b/src/utils/eloop.c index 4a565ebdb..2627c0fab 100644 --- a/src/utils/eloop.c +++ b/src/utils/eloop.c @@ -923,6 +923,20 @@ void eloop_run(void) (!dl_list_empty(&eloop.timeout) || eloop.readers.count > 0 || eloop.writers.count > 0 || eloop.exceptions.count > 0)) { struct eloop_timeout *timeout; + + if (eloop.pending_terminate) { + /* + * This may happen in some corner cases where a signal + * is received during a blocking operation. We need to + * process the pending signals and exit if requested to + * avoid hitting the SIGALRM limit if the blocking + * operation took more than two seconds. + */ + eloop_process_pending_signals(); + if (eloop.terminate) + break; + } + timeout = dl_list_first(&eloop.timeout, struct eloop_timeout, list); if (timeout) { @@ -1073,7 +1087,7 @@ void eloop_destroy(void) int eloop_terminated(void) { - return eloop.terminate; + return eloop.terminate || eloop.pending_terminate; }