From 353f7a7bbbf612cdae0fe00a4add739d5316c8a2 Mon Sep 17 00:00:00 2001 From: David Oberhollenzer Date: Wed, 13 May 2020 17:44:21 +0200 Subject: Cleanup: Elimiate "waiting" state from supervisor Instead, use a wait() loop in the queue processing function. Signed-off-by: David Oberhollenzer --- initd/supervisor.c | 40 +++++++++++++++++++++++++++++----------- 1 file changed, 29 insertions(+), 11 deletions(-) (limited to 'initd') diff --git a/initd/supervisor.c b/initd/supervisor.c index 5849b9c..c1b44e7 100644 --- a/initd/supervisor.c +++ b/initd/supervisor.c @@ -16,7 +16,6 @@ static size_t queue_count[TGT_MAX]; static size_t queue_idx = 0; static int target = TGT_BOOT; static size_t singleshot = 0; -static bool waiting = false; /*****************************************************************************/ @@ -57,7 +56,7 @@ fail: static void check_target_completion(void) { - if (singleshot > 0 || queue_idx < queue_count[target] || waiting) + if (singleshot > 0 || queue_idx < queue_count[target]) return; switch (target) { @@ -105,11 +104,8 @@ void supervisor_handle_exited(pid_t pid, int status) print_status(svc->desc, rt->state); - if (svc->type == SVC_ONCE) { + if (svc->type == SVC_ONCE) singleshot -= 1; - } else if (svc->type == SVC_WAIT) { - waiting = false; - } check_target_completion(); } @@ -177,14 +173,25 @@ out: print_status("reading configuration from " SVCDIR, status); } +static pid_t wait_for_process(int *status) +{ + pid_t pid = wait(status); + + if (pid == -1 || !WIFEXITED(*status)) { + *status = EXIT_FAILURE; + } else { + *status = WEXITSTATUS(*status); + } + return pid; +} + bool supervisor_process_queues(void) { svc_run_data_t *rt; service_t *svc; size_t count; - - if (waiting) - return false; + int status; + pid_t pid; count = queue_count[target]; if (queue_idx >= count) @@ -198,12 +205,23 @@ bool supervisor_process_queues(void) if (rt->pid == -1) { rt->state = STATE_FAILED; + print_status(svc->desc, rt->state); } else { rt->state = STATE_RUNNING; + print_status(svc->desc, rt->state); switch (svc->type) { case SVC_WAIT: - waiting = true; + for (;;) { + pid = wait_for_process(&status); + if (pid == rt->pid) + break; + supervisor_handle_exited(pid, status); + } + + rt->state = status == EXIT_SUCCESS ? + STATE_COMPLETED : STATE_FAILED; + print_status(svc->desc, rt->state); break; case SVC_ONCE: singleshot += 1; @@ -213,9 +231,9 @@ bool supervisor_process_queues(void) } else { rt->status = EXIT_SUCCESS; rt->state = STATE_COMPLETED; + print_status(svc->desc, rt->state); } - print_status(svc->desc, rt->state); check_target_completion(); return true; } -- cgit v1.2.3