]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
eloop: Try to terminate more quickly on SIGINT and SIGTERM
authorJouni Malinen <jouni@qca.qualcomm.com>
Wed, 22 Jul 2015 14:05:46 +0000 (17:05 +0300)
committerJouni Malinen <j@w1.fi>
Wed, 22 Jul 2015 14:05:46 +0000 (17:05 +0300)
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 <jouni@qca.qualcomm.com>
src/utils/eloop.c

index 4a565ebdbd0a989d0ccd3de3989054e3e3f9a399..2627c0fab07e286da13a87c997db84eaf327205f 100644 (file)
@@ -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;
 }