From 4aab694deedcfa52a55eb90adc2c57ead993a2fd Mon Sep 17 00:00:00 2001 From: Nikita Kalyazin Date: Fri, 6 Sep 2013 14:17:47 +0400 Subject: [PATCH] [FIX] merge from tizen_2.2 Original commit: cfea84c2fd3e4f5559fc8ab92a785dbcdcab6f6f fix deadlock when pthread_cancel is called by user Change-Id: Ifa0ed7b5e01be03d122896a2052e1c8165921d7f Signed-off-by: Nikita Kalyazin --- helper/libdaprobe.c | 13 +++++++------ probe_thread/libdathread.c | 24 ++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 6 deletions(-) diff --git a/helper/libdaprobe.c b/helper/libdaprobe.c index 899fd62..9d21345 100755 --- a/helper/libdaprobe.c +++ b/helper/libdaprobe.c @@ -53,6 +53,7 @@ #include "dautil.h" #include "dahelper.h" #include "dacollection.h" +#include "da_sync.h" #include "binproto.h" @@ -431,9 +432,9 @@ bool printLog(log_t* log, int msgType) probeBlockStart(); log->type = msgType; - pthread_mutex_lock(&(gTraceInfo.socket.sockMutex)); + real_pthread_mutex_lock(&(gTraceInfo.socket.sockMutex)); res = send(gTraceInfo.socket.daemonSock, log, sizeof(log->type) + sizeof(log->length) + log->length, 0); - pthread_mutex_unlock(&(gTraceInfo.socket.sockMutex)); + real_pthread_mutex_unlock(&(gTraceInfo.socket.sockMutex)); probeBlockEnd(); return true; @@ -460,9 +461,9 @@ bool printLogStr(const char* str, int msgType) log.length = 0; } - pthread_mutex_lock(&(gTraceInfo.socket.sockMutex)); + real_pthread_mutex_lock(&(gTraceInfo.socket.sockMutex)); res = send(gTraceInfo.socket.daemonSock, &log, sizeof(log.type) + sizeof(log.length) + log.length, MSG_DONTWAIT); - pthread_mutex_unlock(&(gTraceInfo.socket.sockMutex)); + real_pthread_mutex_unlock(&(gTraceInfo.socket.sockMutex)); probeBlockEnd(); @@ -755,9 +756,9 @@ bool setProbePoint(probeInfo_t* iProbe) probeBlockStart(); // atomic operaion(gcc builtin) is more expensive then pthread_mutex - pthread_mutex_lock(&(gTraceInfo.index.eventMutex)); + real_pthread_mutex_lock(&(gTraceInfo.index.eventMutex)); iProbe->eventIndex = gTraceInfo.index.eventIndex++; - pthread_mutex_unlock(&(gTraceInfo.index.eventMutex)); + real_pthread_mutex_unlock(&(gTraceInfo.index.eventMutex)); iProbe->currentTime = getCurrentTime(); iProbe->pID = getpid(); diff --git a/probe_thread/libdathread.c b/probe_thread/libdathread.c index f9dc68d..f966066 100644 --- a/probe_thread/libdathread.c +++ b/probe_thread/libdathread.c @@ -53,6 +53,10 @@ void _da_cleanup_handler(void *data) probeInfo_t probeInfo; + // unlock socket mutex to prevent deadlock + // in case of cancellation happened while log sending + real_pthread_mutex_unlock(&(gTraceInfo.socket.sockMutex)); + PRE_UNCONDITIONAL_BLOCK_BEGIN(); pSelf = pthread_self(); @@ -76,9 +80,14 @@ void *_da_ThreadProc(void *params) thread_routine_call *ptrc; ptrc = (thread_routine_call *) params; pthread_t pSelf; + int old_state; + int new_state = PTHREAD_CANCEL_DISABLE; probeInfo_t probeInfo; + // disable cancellation to prevent deadlock + real_pthread_setcancelstate(new_state, &old_state); + PRE_UNCONDITIONAL_BLOCK_BEGIN(); pSelf = pthread_self(); @@ -93,11 +102,17 @@ void *_da_ThreadProc(void *params) PRE_UNCONDITIONAL_BLOCK_END(); + // restore cancellation state + real_pthread_setcancelstate(old_state, NULL); + pthread_cleanup_push(_da_cleanup_handler, NULL); // call user-defined thread routine ret = ptrc->thread_routine(ptrc->argument); pthread_cleanup_pop(0); + // disable cancellation to prevent deadlock + real_pthread_setcancelstate(new_state, &old_state); + PRE_UNCONDITIONAL_BLOCK_BEGIN(); pSelf = pthread_self(); @@ -275,6 +290,15 @@ int pthread_equal(pthread_t t1, pthread_t t2) return ret; } +int real_pthread_setcancelstate(int state, int *oldstate) +{ + static int (*pthread_setcancelstatep)(int state, int *oldstate); + + GET_REAL_FUNC(pthread_setcancelstate, LIBPTHREAD); + + return pthread_setcancelstatep(state, oldstate); +} + int pthread_setcancelstate(int state, int *oldstate) { pthread_t pSelf; -- 2.7.4