summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJosé Bollo <jose.bollo@iot.bzh>2019-10-17 11:12:59 +0200
committerJosé Bollo <jose.bollo@iot.bzh>2019-10-17 18:04:09 +0200
commit6cbd15fc52490e85babb60f76a0d1887cbe88696 (patch)
tree3004c1c44a3e6e61c71e304678c60b09c42f7a1c
parent99ad30bf29c683da833efeac42d8f178b6d2ca8c (diff)
sig-monitor: Fix exit in signal handler
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
-rw-r--r--src/jobs.c3
-rw-r--r--src/sig-monitor.c26
2 files changed, 26 insertions, 3 deletions
diff --git a/src/jobs.c b/src/jobs.c
index a518766b..94bdce86 100644
--- a/src/jobs.c
+++ b/src/jobs.c
@@ -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 */
diff --git a/src/sig-monitor.c b/src/sig-monitor.c
index 70592812..c64306db 100644
--- a/src/sig-monitor.c
+++ b/src/sig-monitor.c
@@ -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) {}