From: <ale...@us...> - 2011-10-31 18:36:05
|
Revision: 53602 http://firebird.svn.sourceforge.net/firebird/?rev=53602&view=rev Author: alexpeshkoff Date: 2011-10-31 18:35:59 +0000 (Mon, 31 Oct 2011) Log Message: ----------- Fixed CORE-3646: Segmentation fault in multi-threaded program when using 2.5.x client library on Linux Modified Paths: -------------- firebird/branches/B2_5_Release/src/common/fb_exception.cpp firebird/branches/B2_5_Release/src/common/thd.cpp firebird/branches/B2_5_Release/src/common/thd.h Modified: firebird/branches/B2_5_Release/src/common/fb_exception.cpp =================================================================== --- firebird/branches/B2_5_Release/src/common/fb_exception.cpp 2011-10-28 03:18:44 UTC (rev 53601) +++ firebird/branches/B2_5_Release/src/common/fb_exception.cpp 2011-10-31 18:35:59 UTC (rev 53602) @@ -13,6 +13,9 @@ #ifdef WIN_NT #include <windows.h> +#else +#include <pthread.h> +#include <signal.h> #endif namespace { @@ -76,6 +79,15 @@ thread = currTID; } } +#else + if (thread != currTID) + { + if (pthread_kill(thread, 0) == ESRCH) + { + // Thread does not exist any more + thread = currTID; + } + } #endif return thread == currTID; @@ -91,9 +103,7 @@ explicit StringsBuffer(Firebird::MemoryPool& p) : processBuffer(p) { } ~StringsBuffer() - { - ThreadCleanup::remove(cleanupAllStrings, this); - } + { } private: size_t position(FB_THREAD_ID thr) @@ -126,29 +136,9 @@ return b; } - void cleanup() - { - Firebird::MutexLockGuard guard(mutex); - - size_t p = position(getThreadId()); - if (p >= processBuffer.getCount()) - { - return; - } - - delete processBuffer[p]; - processBuffer.remove(p); - } - - static void cleanupAllStrings(void* toClean) - { - static_cast<StringsBuffer*>(toClean)->cleanup(); - } - public: const char* alloc(const char* s, size_t& len, FB_THREAD_ID thr = getThreadId()) { - ThreadCleanup::add(cleanupAllStrings, this); return getThreadBuffer(thr)->alloc(s, len); } }; Modified: firebird/branches/B2_5_Release/src/common/thd.cpp =================================================================== --- firebird/branches/B2_5_Release/src/common/thd.cpp 2011-10-28 03:18:44 UTC (rev 53601) +++ firebird/branches/B2_5_Release/src/common/thd.cpp 2011-10-31 18:35:59 UTC (rev 53602) @@ -154,111 +154,3 @@ SleepEx(0, FALSE); #endif } - -// Cleanup on thread completion - -#ifdef USE_POSIX_THREADS -namespace { - -pthread_key_t key; -pthread_once_t keyOnce = PTHREAD_ONCE_INIT; - -void makeKey() -{ - int err = pthread_key_create(&key, ThreadCleanup::destructor); - if (err) - { - Firebird::system_call_failed("pthread_key_create", err); - } -} - -void initThreadCleanup() -{ - int err = pthread_once(&keyOnce, makeKey); - if (err) - { - Firebird::system_call_failed("pthread_once", err); - } - - err = pthread_setspecific(key, &key); - if (err) - { - Firebird::system_call_failed("pthread_setspecific", err); - } -} - -ThreadCleanup* chain = NULL; -Firebird::GlobalPtr<Firebird::Mutex> cleanupMutex; - -} // anonymous namespace - -ThreadCleanup** ThreadCleanup::findCleanup(FPTR_VOID_PTR cleanup, void* arg) -{ - for (ThreadCleanup** ptr = &chain; *ptr; ptr = &((*ptr)->next)) - { - if ((*ptr)->function == cleanup && (*ptr)->argument == arg) - { - return ptr; - } - } - - return NULL; -} - -void ThreadCleanup::destructor(void*) -{ - Firebird::MutexLockGuard guard(cleanupMutex); - - for (ThreadCleanup* ptr = chain; ptr; ptr = ptr->next) - { - ptr->function(ptr->argument); - } -} - -void ThreadCleanup::add(FPTR_VOID_PTR cleanup, void* arg) -{ - Firebird::MutexLockGuard guard(cleanupMutex); - - initThreadCleanup(); - - if (findCleanup(cleanup, arg)) - { - return; - } - - chain = FB_NEW(*getDefaultMemoryPool()) ThreadCleanup(cleanup, arg, chain); -} - -void ThreadCleanup::remove(FPTR_VOID_PTR cleanup, void* arg) -{ - ThreadCleanup** ptr = findCleanup(cleanup, arg); - if (!ptr) - { - return; - } - - ThreadCleanup* toDelete = *ptr; - *ptr = toDelete->next; - delete toDelete; -} - -#else // USE_POSIX_THREADS - -ThreadCleanup** ThreadCleanup::findCleanup(FPTR_VOID_PTR, void*) -{ - return NULL; -} - -void ThreadCleanup::destructor(void*) -{ -} - -void ThreadCleanup::add(FPTR_VOID_PTR, void*) -{ -} - -void ThreadCleanup::remove(FPTR_VOID_PTR, void*) -{ -} - -#endif // USE_POSIX_THREADS Modified: firebird/branches/B2_5_Release/src/common/thd.h =================================================================== --- firebird/branches/B2_5_Release/src/common/thd.h 2011-10-28 03:18:44 UTC (rev 53601) +++ firebird/branches/B2_5_Release/src/common/thd.h 2011-10-31 18:35:59 UTC (rev 53602) @@ -37,23 +37,4 @@ // thread ID FB_THREAD_ID getThreadId() throw(); -class ThreadCleanup -{ -public: - static void add(FPTR_VOID_PTR cleanup, void* arg); - static void remove(FPTR_VOID_PTR cleanup, void* arg); - static void destructor(void*); - -private: - FPTR_VOID_PTR function; - void* argument; - ThreadCleanup* next; - - ThreadCleanup(FPTR_VOID_PTR cleanup, void* arg, ThreadCleanup* chain) - : function(cleanup), argument(arg), next(chain) { } - ~ThreadCleanup() { } - - static ThreadCleanup** findCleanup(FPTR_VOID_PTR cleanup, void* arg); -}; - #endif // JRD_THD_H This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |