From 5c1a2b328f0f75669de0f7660e8425199ba89d6b Mon Sep 17 00:00:00 2001 From: George Hazan Date: Fri, 29 Jun 2012 09:38:03 +0000 Subject: - eliminated crash in Punto Switcher's dll during exit; - removed references to the callee's local thread data in QueueUserAPC; git-svn-id: http://svn.miranda-ng.org/main/trunk@683 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- bin10/lib/mir_core.lib | Bin 27940 -> 28382 bytes bin10/lib/mir_core64.lib | Bin 25550 -> 25756 bytes include/m_core.h | 2 ++ include/m_system_cpp.h | 2 ++ plugins/Mir_core/mir_core.def | 1 + plugins/Mir_core/miranda.cpp | 14 ++++----- plugins/Mir_core/miranda.h | 1 + plugins/Mir_core/modules.cpp | 70 ++++++++++++++++++++---------------------- src/core/miranda.cpp | 1 + 9 files changed, 46 insertions(+), 45 deletions(-) diff --git a/bin10/lib/mir_core.lib b/bin10/lib/mir_core.lib index 350c3949a2..1c4d767aea 100644 Binary files a/bin10/lib/mir_core.lib and b/bin10/lib/mir_core.lib differ diff --git a/bin10/lib/mir_core64.lib b/bin10/lib/mir_core64.lib index 8a02283be1..bd6041429f 100644 Binary files a/bin10/lib/mir_core64.lib and b/bin10/lib/mir_core64.lib differ diff --git a/include/m_core.h b/include/m_core.h index fc0134a621..14c72c0a37 100644 --- a/include/m_core.h +++ b/include/m_core.h @@ -503,6 +503,8 @@ __forceinline char* mir_utf8decodeA(const char* src) /////////////////////////////////////////////////////////////////////////////// +MIR_CORE_DLL(void) UnloadCoreModule(void); + #if defined(__cplusplus) } #endif diff --git a/include/m_system_cpp.h b/include/m_system_cpp.h index 5815e410a4..76556160a6 100644 --- a/include/m_system_cpp.h +++ b/include/m_system_cpp.h @@ -42,9 +42,11 @@ template class mir_ptr T* data; public: + __inline mir_ptr() : data((T*)mir_calloc(sizeof(T))) {} __inline mir_ptr(T* _p) : data(_p) {} __inline ~mir_ptr() { mir_free(data); } __inline T* operator= (T* _p) { if (data) mir_free(data); data = _p; return data; } + __inline T* operator->() const { return data; } __inline operator T*() const { return data; } __inline operator INT_PTR() const { return (INT_PTR)data; } }; diff --git a/plugins/Mir_core/mir_core.def b/plugins/Mir_core/mir_core.def index 323ef00961..7d998c0d14 100644 --- a/plugins/Mir_core/mir_core.def +++ b/plugins/Mir_core/mir_core.def @@ -123,3 +123,4 @@ db_set_s @119 db_set_utf @120 db_set_w @121 db_set_ws @122 +UnloadCoreModule @123 diff --git a/plugins/Mir_core/miranda.cpp b/plugins/Mir_core/miranda.cpp index 83abfb3acd..910b204292 100644 --- a/plugins/Mir_core/miranda.cpp +++ b/plugins/Mir_core/miranda.cpp @@ -350,6 +350,9 @@ MIR_CORE_DLL(INT_PTR) Thread_Pop() return 1; } +///////////////////////////////////////////////////////////////////////////////////////// +// module init + static LRESULT CALLBACK APCWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { if (msg == WM_NULL) SleepEx(0, TRUE); @@ -358,10 +361,7 @@ static LRESULT CALLBACK APCWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lP return DefWindowProc(hwnd, msg, wParam, lParam); } -///////////////////////////////////////////////////////////////////////////////////////// -// module init - -static void LoadSystemModule(void) +static void LoadCoreModule(void) { INITCOMMONCONTROLSEX icce = {0}; icce.dwSize = sizeof(icce); @@ -390,7 +390,7 @@ static void LoadSystemModule(void) InitialiseModularEngine(); } -static void UnloadSystemModule(void) +MIR_CORE_DLL(void) UnloadCoreModule(void) { DestroyWindow(hAPCWindow); CloseHandle(hStackMutex); @@ -406,9 +406,7 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { if (fdwReason == DLL_PROCESS_ATTACH) { hInst = hinstDLL; - LoadSystemModule(); + LoadCoreModule(); } - else if(fdwReason == DLL_PROCESS_DETACH) - UnloadSystemModule(); return TRUE; } diff --git a/plugins/Mir_core/miranda.h b/plugins/Mir_core/miranda.h index 5e0a0d2fb1..65140260c1 100644 --- a/plugins/Mir_core/miranda.h +++ b/plugins/Mir_core/miranda.h @@ -42,6 +42,7 @@ void DestroyModularEngine(void); int InitPathUtils(void); extern HINSTANCE hInst; +extern HWND hAPCWindow; /**** modules.cpp **********************************************************************/ diff --git a/plugins/Mir_core/modules.cpp b/plugins/Mir_core/modules.cpp index 6a9aa54bcb..0818e8916e 100644 --- a/plugins/Mir_core/modules.cpp +++ b/plugins/Mir_core/modules.cpp @@ -81,24 +81,35 @@ static HANDLE hMainThread; static HANDLE hMissingService; static THook *pLastHook = NULL; +///////////////////////////////////////////////////////////////////////////////////////// + +static int QueueMainThread(PAPCFUNC pFunc, void* pParam, HANDLE hDoneEvent) +{ + int result = QueueUserAPC(pFunc, hMainThread, (ULONG_PTR)pParam); + PostMessage(hAPCWindow, WM_NULL, 0, 0); // let this get processed in its own time + if (hDoneEvent) { + WaitForSingleObject(hDoneEvent, INFINITE); + CloseHandle(hDoneEvent); + } + return result; +} + /////////////////////////////////////////////////////////////////////////////// // HOOKS MIR_CORE_DLL(HANDLE) CreateHookableEvent(const char *name) { - THook* ret; - int idx; - if (name == NULL) return NULL; EnterCriticalSection(&csHooks); + int idx; if ((idx = hooks.getIndex((THook*)name)) != -1) { LeaveCriticalSection(&csHooks); return NULL; } - ret = (THook*)mir_alloc(sizeof(THook)); + THook* ret = (THook*)mir_alloc(sizeof(THook)); strncpy(ret->name, name, sizeof(ret->name)); ret->name[ MAXMODULELABELLENGTH-1 ] = 0; ret->id = hookId++; ret->subscriberCount = 0; @@ -242,24 +253,16 @@ static void CALLBACK HookToMainAPCFunc(ULONG_PTR dwParam) MIR_CORE_DLL(int) NotifyEventHooks(HANDLE hEvent, WPARAM wParam, LPARAM lParam) { - extern HWND hAPCWindow; + if ( GetCurrentThreadId() == mainThreadId) + return (checkHook(hEvent) == -1) ? -1 : CallHookSubscribers(hEvent, wParam, lParam); - if ( GetCurrentThreadId() != mainThreadId) { - THookToMainThreadItem item; - - item.hDoneEvent = CreateEvent(NULL, FALSE, FALSE, NULL); - item.hook = (THook*)hEvent; - item.wParam = wParam; - item.lParam = lParam; - - QueueUserAPC(HookToMainAPCFunc, hMainThread, (ULONG_PTR)&item); - PostMessage(hAPCWindow, WM_NULL, 0, 0); // let it process APC even if we're in a common dialog - WaitForSingleObject(item.hDoneEvent, INFINITE); - CloseHandle(item.hDoneEvent); - return item.result; - } - - return (checkHook(hEvent) == -1) ? -1 : CallHookSubscribers(hEvent, wParam, lParam); + mir_ptr item; + item->hDoneEvent = CreateEvent(NULL, FALSE, FALSE, NULL); + item->hook = (THook*)hEvent; + item->wParam = wParam; + item->lParam = lParam; + QueueMainThread(HookToMainAPCFunc, item, item->hDoneEvent); + return item->result; } static HANDLE HookEventInt(int type, const char* name, MIRANDAHOOK hookProc, void* object, LPARAM lParam) @@ -548,23 +551,18 @@ static void CALLBACK CallServiceToMainAPCFunc(ULONG_PTR dwParam) MIR_CORE_DLL(INT_PTR) CallServiceSync(const char *name, WPARAM wParam, LPARAM lParam) { - extern HWND hAPCWindow; - if (name == NULL) return CALLSERVICE_NOTFOUND; // the service is looked up within the main thread, since the time it takes // for the APC queue to clear the service being called maybe removed. // even thou it may exists before the call, the critsec can't be locked between calls. if (GetCurrentThreadId() != mainThreadId) { - TServiceToMainThreadItem item; - item.wParam = wParam; - item.lParam = lParam; - item.name = name; - item.hDoneEvent = CreateEvent(NULL, FALSE, FALSE, NULL); - QueueUserAPC(CallServiceToMainAPCFunc, hMainThread, (ULONG_PTR) &item); - PostMessage(hAPCWindow, WM_NULL, 0, 0); // let this get processed in its own time - WaitForSingleObject(item.hDoneEvent, INFINITE); - CloseHandle(item.hDoneEvent); - return item.result; + mir_ptr item; + item->wParam = wParam; + item->lParam = lParam; + item->name = name; + item->hDoneEvent = CreateEvent(NULL, FALSE, FALSE, NULL); + QueueMainThread(CallServiceToMainAPCFunc, &item, item->hDoneEvent); + return item->result; } return CallService(name, wParam, lParam); @@ -572,10 +570,8 @@ MIR_CORE_DLL(INT_PTR) CallServiceSync(const char *name, WPARAM wParam, LPARAM lP MIR_CORE_DLL(int) CallFunctionAsync(void (__stdcall *func)(void *), void *arg) { - extern HWND hAPCWindow; - int r = QueueUserAPC((void (__stdcall *)(ULONG_PTR))func, hMainThread, (ULONG_PTR)arg); - PostMessage(hAPCWindow, WM_NULL, 0, 0); - return r; + QueueMainThread((PAPCFUNC)func, arg, 0); + return 0; } MIR_CORE_DLL(void) KillModuleServices(HINSTANCE hInst) diff --git a/src/core/miranda.cpp b/src/core/miranda.cpp index 7cd2e02962..64ec124378 100644 --- a/src/core/miranda.cpp +++ b/src/core/miranda.cpp @@ -348,6 +348,7 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, int) exit: UnloadNewPluginsModule(); + UnloadCoreModule(); CloseHandle(hMirandaShutdown); CloseHandle(hThreadQueueEmpty); -- cgit v1.2.3