From: Vitaliy Cherepanov Date: Fri, 25 Sep 2015 07:02:14 +0000 (+0300) Subject: [FIX] deadlock X-Git-Tag: submit/tizen/20151105.065919~11 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=b035458ed8f0df3399cca03bcadd72b117b195e8;p=platform%2Fcore%2Fsystem%2Fswap-manager.git [FIX] deadlock deadlock on stop instrumentation (target threads) Change-Id: I97b6a9ebe4fcb54fd67d4d0a34ab2b16426a7611 Signed-off-by: Vitaliy Cherepanov --- diff --git a/daemon/daemon.c b/daemon/daemon.c index be242d8..959d63b 100644 --- a/daemon/daemon.c +++ b/daemon/daemon.c @@ -675,13 +675,14 @@ static int target_event_stop_handler(struct target *target) int cnt; enum app_type_t app_type = target->app_type; - LOGI("target[%p] close, pid(%d) : (remaining %d target)\n", - target, target_get_pid(target), target_cnt_get() - 1); + LOGI("target[%p] close, pid(%d) : (remaining %d target) close ecore handler %p\n", + target, target_get_pid(target), target_cnt_get() - 1, target->handler); ecore_main_fd_handler_del(target->handler); - target_wait(target); - target_dtor(target); + /* mark target uninitialised */ + target->event_fd_released = 1; + // all target client are closed cnt = target_cnt_sub_and_fetch(); if (0 == cnt) { diff --git a/daemon/target.c b/daemon/target.c index 024a326..729a6ce 100644 --- a/daemon/target.c +++ b/daemon/target.c @@ -50,6 +50,7 @@ struct target *target_ctor(void) t->socket = UNKNOWN_FD; t->event_fd = UNKNOWN_FD; t->initial_log = 0; + t->event_fd_released = 0; t->allocmem = 0; t->thread = thread_ctor(); @@ -65,6 +66,7 @@ struct target *target_ctor(void) void target_dtor(struct target *t) { t->allocmem = 0; + t->event_fd_released = 0; t->initial_log = 0; if (t->event_fd != -1) @@ -160,6 +162,18 @@ static struct target *target_malloc(void) target_array_lock(); for (i = 0; i < MAX_TARGET_COUNT; i++) { + /* FIXME refactor this code: convert targer_use[] and + * event_fd_released to one counter variable */ + + /* if target_use is 1 and event_fd_released 1 targed not used + * and can be released. target_use and event_fd_released are set + * in different threads asynchronously + */ + if (target_use[i] == 1 && target_array[i].event_fd_released == 1) { + target_dtor(&target_array[i]); + target_use[i] = 0; + } + if (target_use[i] == 0) { target_use[i] = 1; t = &target_array[i]; @@ -237,16 +251,34 @@ void target_wait_all(void) target_array_lock(); for (i = 0; i < MAX_TARGET_COUNT; ++i) { + LOGI("target_use [%d] = %d\n", i, target_use[i]); if (target_use[i] == 0) continue; t = target_get(i); + if (close(t->socket) != 0) { + LOGW("target socket already closed %u:%u\n", (unsigned int)t->pid, (unsigned int)t->ppid); + } - LOGI("join recv thread [%d] is started\n", i); + LOGI("join recv thread [%d] %u:%u is started\n", i, (unsigned int)t->pid, (unsigned int)t->ppid); target_wait(t); - LOGI("join recv thread %d. done\n", i); + LOGI("join recv thread [%d] %u:%u done\n", i, (unsigned int)t->pid, (unsigned int)t->ppid); } + target_array_unlock(); + + for (i = 0; i < MAX_TARGET_COUNT; ++i) { + if (target_use[i] == 0) + continue; + t = target_get(i); + while (t->event_fd_released != 1) { + LOGI("wait uninit [%d] %u:%u\n", i, t->pid, t->ppid); + sleep(1); + } + LOGI("target destroy [%d] start\n", i); + target_dtor(t); + LOGI("target destroy [%d] done\n", i); + } } uint64_t target_get_total_alloc(pid_t pid) diff --git a/daemon/target.h b/daemon/target.h index c21af67..2abba94 100644 --- a/daemon/target.h +++ b/daemon/target.h @@ -55,6 +55,7 @@ struct target { * (from recv thread to main thread) */ int initial_log; /* written only by main thread */ Ecore_Fd_Handler *handler; /* calculated when connecting */ + int event_fd_released; struct thread *thread; }; diff --git a/daemon/threads.c b/daemon/threads.c index bc0cfa3..8c97db1 100644 --- a/daemon/threads.c +++ b/daemon/threads.c @@ -233,6 +233,7 @@ static void* recvThread(void* data) pass = 1; } + LOGI("thread finished %u:%u\n", target->pid, target->ppid); return NULL; }