diff --git a/src/common/dllinst.cpp b/src/common/dllinst.cpp index 83e91cd027..db002aac5d 100644 --- a/src/common/dllinst.cpp +++ b/src/common/dllinst.cpp @@ -34,7 +34,6 @@ namespace Firebird { HINSTANCE hDllInst = 0; -bool bEmbedded = false; } // namespace diff --git a/src/common/dllinst.h b/src/common/dllinst.h index 9574325676..23628b638e 100644 --- a/src/common/dllinst.h +++ b/src/common/dllinst.h @@ -36,7 +36,6 @@ namespace Firebird { extern HINSTANCE hDllInst; -extern bool bEmbedded; } // namespace diff --git a/src/jrd/os/win32/ibinitdll.cpp b/src/jrd/os/win32/ibinitdll.cpp index 3f77a9edfc..16a8d2f8f3 100644 --- a/src/jrd/os/win32/ibinitdll.cpp +++ b/src/jrd/os/win32/ibinitdll.cpp @@ -23,9 +23,10 @@ */ #include "firebird.h" -#include "../../../common/dllinst.h" - #include +#include "../../../common/dllinst.h" +#include "../../../yvalve/MasterImplementation.h" + using namespace Firebird; @@ -36,10 +37,13 @@ BOOL WINAPI DllMain(HINSTANCE h, DWORD reason, LPVOID /*reserved*/) { case DLL_PROCESS_ATTACH: hDllInst = h; -//#if defined(EMBEDDED) - bEmbedded = true; -//#endif break; + + case DLL_THREAD_DETACH: + { + Why::threadCleanup(); + break; + } } return TRUE; diff --git a/src/yvalve/MasterImplementation.cpp b/src/yvalve/MasterImplementation.cpp index 680dbd6b24..9d4194bc41 100644 --- a/src/yvalve/MasterImplementation.cpp +++ b/src/yvalve/MasterImplementation.cpp @@ -147,7 +147,6 @@ int MasterImplementation::serverMode(int mode) #include #endif -#ifdef USE_POSIX_THREADS namespace { class ThreadCleanup @@ -162,12 +161,23 @@ private: void* argument; ThreadCleanup* next; + static ThreadCleanup* chain; + static GlobalPtr cleanupMutex; + ThreadCleanup(FPTR_VOID_PTR cleanup, void* arg, ThreadCleanup* chain) : function(cleanup), argument(arg), next(chain) { } + static void initThreadCleanup(); + static void finiThreadCleanup(); + static ThreadCleanup** findCleanup(FPTR_VOID_PTR cleanup, void* arg); }; +ThreadCleanup* ThreadCleanup::chain = NULL; +GlobalPtr ThreadCleanup::cleanupMutex; + +#ifdef USE_POSIX_THREADS + pthread_key_t key; pthread_once_t keyOnce = PTHREAD_ONCE_INIT; bool keySet = false; @@ -182,7 +192,7 @@ void makeKey() keySet = true; } -void initThreadCleanup() +void ThreadCleanup::initThreadCleanup() { int err = pthread_once(&keyOnce, makeKey); if (err) @@ -197,7 +207,11 @@ void initThreadCleanup() } } -ThreadCleanup* chain = NULL; +void ThreadCleanup::finiThreadCleanup() +{ + pthread_setspecific(key, NULL); +} + class FiniThreadCleanup { @@ -217,9 +231,19 @@ public: } }; -Firebird::GlobalPtr cleanupMutex; Firebird::GlobalPtr thrCleanup; // needed to call dtor +#endif // USE_POSIX_THREADS + +#ifdef WIN_NT +void ThreadCleanup::initThreadCleanup() +{ +} + +void ThreadCleanup::finiThreadCleanup() +{ +} +#endif // #ifdef WIN_NT ThreadCleanup** ThreadCleanup::findCleanup(FPTR_VOID_PTR cleanup, void* arg) { @@ -243,7 +267,7 @@ void ThreadCleanup::destructor(void*) ptr->function(ptr->argument); } - pthread_setspecific(key, NULL); + finiThreadCleanup(); } void ThreadCleanup::add(FPTR_VOID_PTR cleanup, void* arg) @@ -276,7 +300,7 @@ void ThreadCleanup::remove(FPTR_VOID_PTR cleanup, void* arg) } } // anonymous namespace -#endif // USE_POSIX_THREADS + namespace { @@ -294,6 +318,11 @@ private: public: explicit ThreadBuffer(ThreadId thr) : buffer_ptr(buffer), thread(thr) { } + static ThreadId generate(const ThreadBuffer* item) + { + return item->thread; + } + const char* alloc(const char* string, size_t length) { // if string is already in our buffer - return it @@ -345,7 +374,7 @@ private: } }; - typedef Firebird::Array ProcessBuffer; + typedef Firebird::SortedArray, ThreadId, ThreadBuffer> ProcessBuffer; ProcessBuffer processBuffer; Firebird::Mutex mutex; @@ -358,9 +387,7 @@ public: ~StringsBuffer() { -#ifdef USE_POSIX_THREADS ThreadCleanup::remove(cleanupAllStrings, this); -#endif } private: @@ -368,11 +395,12 @@ private: { fb_assert(mutex.locked()); - for (FB_SIZE_T i = 0; i < processBuffer.getCount(); ++i) + size_t pos; + if (processBuffer.find(thr, pos)) { - if (processBuffer[i]->thisThread(thr)) + if (processBuffer[pos]->thisThread(thr)) { - return i; + return pos; } } @@ -389,9 +417,8 @@ private: return processBuffer[p]; } -#ifdef USE_POSIX_THREADS ThreadCleanup::add(cleanupAllStrings, this); -#endif + ThreadBuffer* b = new ThreadBuffer(thr); processBuffer.add(b); return b; @@ -436,6 +463,11 @@ const char* MasterImplementation::circularAlloc(const char* s, unsigned len, int return allStrings->alloc(s, len, (ThreadId) thr); } +void threadCleanup() +{ + ThreadCleanup::destructor(NULL); +} + } // namespace Why diff --git a/src/yvalve/MasterImplementation.h b/src/yvalve/MasterImplementation.h index dc40437103..f8486b13e4 100644 --- a/src/yvalve/MasterImplementation.h +++ b/src/yvalve/MasterImplementation.h @@ -68,6 +68,7 @@ namespace Why }; void shutdownTimers(); + void threadCleanup(); Firebird::Mutex& pauseTimer(); } // namespace Why