From 04df02a71284a1edaad4116060f36c160cf1ead6 Mon Sep 17 00:00:00 2001 From: jongmyeongko Date: Tue, 2 May 2017 18:59:35 +0900 Subject: [PATCH] Fix signal handler for handling all dead childs The signal handler can be called once (not for each child) when childs are terminated at very close timing each other. reproduce : #pkgcmd --clear-all this causes all slots (rpm, tpk and wgt) active, and some processes are terminated at very close timing. Change-Id: Ie007e17431e78e2920356e6178dff3af86826790 Signed-off-by: jongmyeongko --- src/pkgmgr-server.c | 51 +++++++++++++++++++++++++++------------------------ 1 file changed, 27 insertions(+), 24 deletions(-) diff --git a/src/pkgmgr-server.c b/src/pkgmgr-server.c index 82cb5d5..7f6a2ae 100644 --- a/src/pkgmgr-server.c +++ b/src/pkgmgr-server.c @@ -193,34 +193,37 @@ static gboolean __signal_handler(GIOChannel *io, GIOCondition cond, return TRUE; } - pid = waitpid(-1, &status, WNOHANG); - job = (struct backend_job *)g_hash_table_lookup(backend_info_table, - (gconstpointer)pid); - if (job == NULL) { - ERR("Unknown child exit"); - return -1; - } + while ((pid = waitpid(-1, &status, WNOHANG)) > 0) { + job = (struct backend_job *)g_hash_table_lookup( + backend_info_table, (gconstpointer)pid); + if (job == NULL) { + ERR("Unknown child exit"); + continue; + } - __set_backend_free(job->backend_slot); - if (WIFSIGNALED(status)) { - _send_fail_signal(job); - INFO("backend[%s][%d] exit with signal[%d]", job->backend_type, - pid, WTERMSIG(status)); - } else if (WEXITSTATUS(status)) { - INFO("backend[%s][%d] exit with error", job->backend_type, pid); - } else { - INFO("backend[%s][%d] exit", job->backend_type, pid); - } + __set_backend_free(job->backend_slot); + if (WIFSIGNALED(status)) { + _send_fail_signal(job); + INFO("backend[%s][%d] exit with signal[%d]", + job->backend_type, pid, WTERMSIG(status)); + } else if (WEXITSTATUS(status)) { + INFO("backend[%s][%d] exit with error", + job->backend_type, pid); + } else { + INFO("backend[%s][%d] exit", job->backend_type, pid); + } - if (job->extra) { - if (job->extra->getsize_fifo) { - ERR("invalid backend close"); - _return_value_to_caller(job->req_id, - g_variant_new("(ix)", PKGMGR_R_ERROR, -1)); + if (job->extra) { + if (job->extra->getsize_fifo) { + ERR("invalid backend close"); + _return_value_to_caller(job->req_id, + g_variant_new("(ix)", PKGMGR_R_ERROR, + -1)); + } } - } - g_hash_table_remove(backend_info_table, (gconstpointer)pid); + g_hash_table_remove(backend_info_table, (gconstpointer)pid); + } g_idle_add(queue_job, NULL); return TRUE; -- 2.7.4