sig-monitor: Fix exit in signal handler 03/22703/1
authorJosé Bollo <jose.bollo@iot.bzh>
Thu, 17 Oct 2019 09:12:59 +0000 (11:12 +0200)
committerJosé Bollo <jose.bollo@iot.bzh>
Thu, 17 Oct 2019 16:04:09 +0000 (18:04 +0200)
Calling exit in signal interrupts wasn't correctly handling
the case where the signal interrupts a thread waiting in the
main loop. This can lead to the binder error report:

    CRITICAL: Can't enter dispatch while in dispatch!

This patch defers the call to exit in a job.

Bug-AGL: SPEC-2907

Signed-off-by: José Bollo <jose.bollo@iot.bzh>
Change-Id: I49c7cca1d229ae957d9ea9bfb8838161ce73a53e

src/jobs.c
src/sig-monitor.c

index a518766..94bdce8 100644 (file)
@@ -838,7 +838,8 @@ void jobs_exit(void (*handler)())
                t = t->next;
        }
 
-       /* wait the threads */
+       /* wake up the threads */
+       evloop_wakeup();
        pthread_cond_broadcast(&cond);
 
        /* leave */
index 7059281..c64306d 100644 (file)
@@ -284,9 +284,9 @@ static void on_rescue_exit(int signum)
 }
 
 /*
- * Do a safe exit
+ * Do a direct safe exit
  */
-static void safe_exit(int code)
+static void direct_safe_exit(int code)
 {
        set_signals_handler(on_rescue_exit, sigerr);
        set_signals_handler(on_rescue_exit, sigterm);
@@ -294,6 +294,28 @@ static void safe_exit(int code)
        exit(code);
 }
 
+/*
+ * Do a safe exit
+ */
+#if WITH_SIG_MONITOR_NO_DEFERRED_EXIT
+#  define safe_exit(x) direct_safe_exit(x)
+#else
+#include "jobs.h"
+static void exit_job(int signum, void* arg)
+{
+       exiting = (int)(intptr_t)arg;
+       if (signum)
+               on_rescue_exit(signum);
+       exit(exiting);
+}
+
+static void safe_exit(int code)
+{
+       if (jobs_queue(safe_exit, 0, exit_job, (void*)(intptr_t)code))
+               direct_safe_exit(code);
+}
+#endif
+
 #if !WITH_SIG_MONITOR_DUMPSTACK
 
 static inline void safe_dumpstack(int crop, int signum) {}