From b91e3f8d37797d53b115dd5dd862953a2c595e5f Mon Sep 17 00:00:00 2001 From: George Hazan Date: Thu, 28 Jun 2012 13:35:13 +0000 Subject: some atavisms removed git-svn-id: http://svn.miranda-ng.org/main/trunk@667 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- include/m_system.h | 143 ------------------------------------------ plugins/IEView/Utils.cpp | 4 +- plugins/Mir_core/miranda.cpp | 35 +++++++++-- plugins/Mir_core/miranda.h | 2 + plugins/Mir_core/utils.cpp | 2 +- protocols/GTalkExt/avatar.cpp | 4 +- src/core/miranda.cpp | 52 ++------------- 7 files changed, 43 insertions(+), 199 deletions(-) diff --git a/include/m_system.h b/include/m_system.h index e8c22a9124..4cc9105773 100644 --- a/include/m_system.h +++ b/include/m_system.h @@ -132,149 +132,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. //returns 0 on success or nonzero on failure. #define MS_SYSTEM_REMOVEWAIT "Miranda/System/RemoveWait" -/* - - -- Thread Safety -- - - Proper thread safe shutdown was implemented in 0.3.0.0 (2003/04/18) - and not before, therefore it is improper that any MT plugins be used - with earlier versions of Miranda (as hav0c will result) - - Note: This does not apply to MT plugins which included their own - thread-safe shutdown routines. - - Shutdown thread safety works thusly: - - All new threads must call MS_SYSTEM_THREAD_PUSH and MS_SYSTEM_THREAD_POP - when they return. - - Due to the nature of thread creation, it is illegal to assume - just a call pair of MS_SYSTEM_THREAD_PUSH inside the thread will - be enough -- the source thread may only return when the new child - thread has actually executed MS_SYSTEM_THREAD_PUSH - - This is because a thread maybe in an undefined state at the point - when the thread creation routine returns, thus Miranda may exit - thinking it is safe to do so, because MS_SYSTEM_THREAD_PUSH was not - called in time. - - See miranda.c for how this can be done using an event object - which is signalled just after the MS_SYSTEM_THREAD_PUSH call is executed - and so the source thread knows that the created thread is known to Miranda. - - -- What happens when Miranda exits -- - - Miranda will firstly set an event object to signalled, this will - make MS_SYSTEM_TERMINATED return TRUE, it will then fire ME_SYSTEM_PRESHUTDOWN - at this point, no plugins or modules are unloaded. - - Miranda will then enumerate all active threads and queue an APC call - to each thread, so any thread in an alertable state will become active, - this functionailty may not be required by your threads: but if you use - the Winsock2 event object system or Sleep() please use the alertable - wait functions, so that the thread will 'wake up' when Miranda queues - a message to it, SleepEx() will return WAIT_IO_COMPLETION if this happens. - - After all threads have been signalled, Miranda will spin on the unwind thread stack waiting - for it to become empty, in this time, it will carry on processing thread - switches, clearing it's own APC calls (used by NotifyEventHooks(), CallServiceSync()) - - So a thread should be written in this kind of form: - - void mythread(void *arg) - { - // assume all thread pushing/popping is done by forkthread() - int run=1; - for (;run;) - { - Beep(4391, 500); - SleepEx(1500, TRUE); - if (Miranda_Terminated()) { - Beep(5000, 150); run=0; - } //if - } //for - } - - The above will make a nice Beep every 1.5 seconds and when the UI - quits, it will make a lower beep and then return. - - As many copies of this thread maybe running, the creator does not need - to worry about what to do with previous threads, as long as they're on the - unwind stack.If there are any global resources (and they're mutex) you can free() them - at Unload(), which will only be called, after all threads have returned. - - -- Summary -- - - MS_SYSTEM_TERMINATED (will start returning TRUE) - ME_SYSTEM_PRESHUTDOWN will be fired (The CList won't be visible at this point) - - All PROTOTYPE_PROTOCOL registered plugins will be sent ID_STATUS_OFFLINE - automatically. - - All the threads will be notified via QueueUserAPC() and then Miranda - will poll on the unwind thread queue until it is empty. - - ME_SYSTEM_SHUTDOWN will be fired, the database will be unloaded, the core - will be unloaded -- Miranda will return. - -*/ - -/* 0.5.2+ -wParam=function address -lParam=function parameter - -registers a thread in the core and forks it - -*/ - -#define MS_SYSTEM_FORK_THREAD "Miranda/Thread/Fork" - -/* 0.5.2+ -wParam=void* - thread owner object -lParam=FORK_THREADEX_PARAMS* - -registers a thread in the core and forks it -passes the extended parameters info and returns the thread id - -*/ - -typedef struct -{ - pThreadFuncEx pFunc; - int iStackSize; - void* arg; - unsigned* threadID; -} - FORK_THREADEX_PARAMS; - -#define MS_SYSTEM_FORK_THREAD_EX "Miranda/Thread/ForkEx" - -/* -wParam=0 -lParam=0 - -Add a thread to the unwind wait stack that Miranda will poll on -when it is tearing down modules. - -This must be called in the context of the thread that is to be pushed -i.e. there are no args, it works out what thread is being called -and gets itself a handle to the calling thread. - -*/ -#define MS_SYSTEM_THREAD_PUSH "Miranda/Thread/Push" - -/* -wParam=0 -lParam=0 - -Remove a thread from the unwind wait stack -- it is expected -that the call be made in the context of the thread to be removed. - -Miranda will begin to tear down modules and plugins if/when the -last thread from the unwind stack is removed. -*/ -#define MS_SYSTEM_THREAD_POP "Miranda/Thread/Pop" - /* wParam=0 lParam=0 diff --git a/plugins/IEView/Utils.cpp b/plugins/IEView/Utils.cpp index de2d02694b..fef1056cac 100644 --- a/plugins/IEView/Utils.cpp +++ b/plugins/IEView/Utils.cpp @@ -339,10 +339,10 @@ static void __cdecl forkthread_r(struct FORK_ARG *fa) { void (*callercode)(void*) = fa->threadcode; void *arg = fa->arg; - CallService(MS_SYSTEM_THREAD_PUSH, 0, 0); + Thread_Push((HINSTANCE)callercode); SetEvent(fa->hEvent); callercode(arg); - CallService(MS_SYSTEM_THREAD_POP, 0, 0); + Thread_Pop(); return; } diff --git a/plugins/Mir_core/miranda.cpp b/plugins/Mir_core/miranda.cpp index 0ca0f4bd6c..067cff5d4c 100644 --- a/plugins/Mir_core/miranda.cpp +++ b/plugins/Mir_core/miranda.cpp @@ -85,7 +85,7 @@ void __cdecl forkthread_r(void * arg) struct FORK_ARG * fa = (struct FORK_ARG *) arg; void (*callercode)(void*)=fa->threadcode; void * cookie=fa->arg; - CallService(MS_SYSTEM_THREAD_PUSH, 0, (LPARAM)callercode); + Thread_Push(( HINSTANCE)callercode); SetEvent(fa->hEvent); __try { @@ -96,7 +96,7 @@ void __cdecl forkthread_r(void * arg) } SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL); - CallService(MS_SYSTEM_THREAD_POP, 0, 0); + Thread_Pop(); return; } @@ -127,7 +127,7 @@ unsigned __stdcall forkthreadex_r(void * arg) void *owner = fa->owner; unsigned long rc = 0; - CallService(MS_SYSTEM_THREAD_PUSH, (WPARAM)fa->owner, (LPARAM)threadcode); + Thread_Push((HINSTANCE)threadcode, fa->owner); SetEvent(fa->hEvent); __try { @@ -141,7 +141,7 @@ unsigned __stdcall forkthreadex_r(void * arg) } SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL); - CallService(MS_SYSTEM_THREAD_POP, 0, 0); + Thread_Pop(); return rc; } @@ -278,6 +278,27 @@ MIR_CORE_DLL(void) Thread_Wait(void) typedef LONG (WINAPI *pNtQIT)(HANDLE, LONG, PVOID, ULONG, PULONG); #define ThreadQuerySetWin32StartAddress 9 +static void* GetCurrentThreadEntryPoint() +{ + LONG ntStatus; + HANDLE hDupHandle, hCurrentProcess; + DWORD_PTR dwStartAddress; + + pNtQIT NtQueryInformationThread = (pNtQIT)GetProcAddress(GetModuleHandle(_T("ntdll.dll")), "NtQueryInformationThread" ); + if(NtQueryInformationThread == NULL) return 0; + + hCurrentProcess = GetCurrentProcess(); + if(!DuplicateHandle(hCurrentProcess, GetCurrentThread(), hCurrentProcess, &hDupHandle, THREAD_QUERY_INFORMATION, FALSE, 0)){ + SetLastError(ERROR_ACCESS_DENIED); + return NULL; + } + ntStatus = NtQueryInformationThread(hDupHandle, ThreadQuerySetWin32StartAddress, &dwStartAddress, sizeof(DWORD_PTR), NULL); + CloseHandle(hDupHandle); + + if(ntStatus != ERROR_SUCCESS) return 0; + return ( void* )dwStartAddress; +} + MIR_CORE_DLL(INT_PTR) Thread_Push(HINSTANCE hInst, void* pOwner) { ResetEvent(hThreadQueueEmpty); // thread list is not empty @@ -287,7 +308,11 @@ MIR_CORE_DLL(INT_PTR) Thread_Push(HINSTANCE hInst, void* pOwner) DuplicateHandle(GetCurrentProcess(), GetCurrentThread(), GetCurrentProcess(), &p->hThread, 0, FALSE, DUPLICATE_SAME_ACCESS); p->dwThreadId = GetCurrentThreadId(); p->pObject = pOwner; - p->hOwner = hInst; + if (pluginListAddr.getIndex(hInst) != -1) + p->hOwner = hInst; + else + p->hOwner = GetInstByAddress(( hInst != NULL ) ? (PVOID)hInst : GetCurrentThreadEntryPoint()); + threads.insert(p); ReleaseMutex(hStackMutex); diff --git a/plugins/Mir_core/miranda.h b/plugins/Mir_core/miranda.h index 9faa569eff..5e0a0d2fb1 100644 --- a/plugins/Mir_core/miranda.h +++ b/plugins/Mir_core/miranda.h @@ -77,6 +77,8 @@ struct THook CRITICAL_SECTION csHook; }; +extern LIST pluginListAddr; + /**** langpack.cpp *********************************************************************/ char* LangPackTranslateString(struct LangPackMuuid* pUuid, const char *szEnglish, const int W); diff --git a/plugins/Mir_core/utils.cpp b/plugins/Mir_core/utils.cpp index f0fcdcfa07..5adb7e1cc1 100644 --- a/plugins/Mir_core/utils.cpp +++ b/plugins/Mir_core/utils.cpp @@ -118,7 +118,7 @@ static int sttComparePlugins(const HINSTANCE__* p1, const HINSTANCE__* p2) return (p1 < p2) ? -1 : 1; } -static LIST pluginListAddr(10, sttComparePlugins); +LIST pluginListAddr(10, sttComparePlugins); MIR_CORE_DLL(void) RegisterModule(HINSTANCE hInst) { diff --git a/protocols/GTalkExt/avatar.cpp b/protocols/GTalkExt/avatar.cpp index 086a4641d1..1e55937a44 100644 --- a/protocols/GTalkExt/avatar.cpp +++ b/protocols/GTalkExt/avatar.cpp @@ -124,7 +124,7 @@ struct AVACHANGED { VOID CALLBACK CallSetAvatar(PVOID lpParameter, BOOLEAN TimerOrWaitFired) { - CallService(MS_SYSTEM_THREAD_PUSH, 0, 0); + Thread_Push(0); __try { AVACHANGED *ach = (AVACHANGED*)lpParameter; __try { @@ -136,7 +136,7 @@ VOID CALLBACK CallSetAvatar(PVOID lpParameter, BOOLEAN TimerOrWaitFired) } } __finally { - CallService(MS_SYSTEM_THREAD_POP, 0, 0); + Thread_Pop(); } } diff --git a/src/core/miranda.cpp b/src/core/miranda.cpp index 7a463c05c6..7cd2e02962 100644 --- a/src/core/miranda.cpp +++ b/src/core/miranda.cpp @@ -100,27 +100,6 @@ static INT_PTR srvSetExceptionFilter(WPARAM, LPARAM lParam) return (INT_PTR)SetExceptionFilter((pfnExceptionFilter)lParam); } -///////////////////////////////////////////////////////////////////////////////////////// -// forkthread - starts a new thread - -static INT_PTR ForkThreadService(WPARAM wParam, LPARAM lParam) -{ - return (INT_PTR)forkthread((pThreadFunc)wParam, 0, (void*)lParam); -} - -///////////////////////////////////////////////////////////////////////////////////////// -// forkthreadex - starts a new thread with the extended info and returns the thread id - -static INT_PTR ForkThreadServiceEx(WPARAM wParam, LPARAM lParam) -{ - FORK_THREADEX_PARAMS* params = (FORK_THREADEX_PARAMS*)lParam; - if (params == NULL) - return 0; - - UINT threadID; - return forkthreadex(NULL, params->iStackSize, params->pFunc, (void*)wParam, params->arg, params->threadID ? params->threadID : &threadID); -} - ///////////////////////////////////////////////////////////////////////////////////////// typedef LONG (WINAPI *pNtQIT)(HANDLE, LONG, PVOID, ULONG, PULONG); @@ -133,15 +112,15 @@ INT_PTR MirandaIsTerminated(WPARAM, LPARAM) static void __cdecl compactHeapsThread(void*) { - while ( !Miranda_Terminated()) - { + while ( !Miranda_Terminated()) { HANDLE hHeaps[256]; DWORD hc; SleepEx((1000*60)*5, TRUE); // every 5 minutes hc=GetProcessHeaps(255, (PHANDLE)&hHeaps); if (hc != 0 && hc < 256) { DWORD j; - for (j=0;j