diff options
author | Jose Bollo <jose.bollo@iot.bzh> | 2019-08-02 16:23:50 +0200 |
---|---|---|
committer | José Bollo <jose.bollo@iot.bzh> | 2019-08-09 14:34:43 +0000 |
commit | 6f13ad1989875b5a0ce50b24211fd1fba093735f (patch) | |
tree | e88b8447f6b282384ebaa009057c2871db7fb0ff | |
parent | 3343b4d0514d25fd1f2365eb25049f748cab688e (diff) |
Avoid lock when child dies
Interaction between pthread_cond_wait, pthread_broadcast
and signal may lead to lock when the child of afb-daemon dies.
To avoid that sad behavior, this commit defers the call to
"job_exit" using lazy job queueing.
Bug-AGL: SPEC-2720
Change-Id: Ifd1a56f4a439e1704f79a1291fa01f39b1640f29
Signed-off-by: Jose Bollo <jose.bollo@iot.bzh>
-rw-r--r-- | src/afb-session.c | 2 | ||||
-rw-r--r-- | src/main-afb-daemon.c | 24 |
2 files changed, 18 insertions, 8 deletions
diff --git a/src/afb-session.c b/src/afb-session.c index 1bdb59db..61aa3f61 100644 --- a/src/afb-session.c +++ b/src/afb-session.c @@ -579,7 +579,7 @@ static int cookeyidx(const void *key) * @param makecb the creation function or NULL * @param freecb the release function or NULL * @param closure an argument for makecb or the value if makecb==NULL - * @param replace a boolean enforcing replecement of the previous value + * @param replace a boolean enforcing replacement of the previous value * * @return the value of the cookie * diff --git a/src/main-afb-daemon.c b/src/main-afb-daemon.c index 7b92905f..3421be81 100644 --- a/src/main-afb-daemon.c +++ b/src/main-afb-daemon.c @@ -403,15 +403,25 @@ static struct afb_hsrv *start_http_server() | execute_command +--------------------------------------------------------- */ -static void wait_child_and_exit() +static void exit_at_end() { + exit(0); +} + +static void wait_child(int signum, void* arg) +{ + pid_t pid = (pid_t)(intptr_t)arg; pid_t pidchld = childpid; - childpid = 0; - if (!SELF_PGROUP) - killpg(pidchld, SIGKILL); - waitpid(pidchld, NULL, 0); - exit(0); + if (pidchld == pid) { + childpid = 0; + if (!SELF_PGROUP) + killpg(pidchld, SIGKILL); + waitpid(pidchld, NULL, 0); + jobs_exit(exit_at_end); + } else { + waitpid(pid, NULL, 0); + } } static void on_sigchld(int signum, siginfo_t *info, void *uctx) @@ -421,7 +431,7 @@ static void on_sigchld(int signum, siginfo_t *info, void *uctx) case CLD_EXITED: case CLD_KILLED: case CLD_DUMPED: - jobs_exit(wait_child_and_exit); + jobs_queue_lazy(0, 0, wait_child, (void*)(intptr_t)info->si_pid); default: break; } |