summaryrefslogtreecommitdiff
path: root/src/mir_core/threads.cpp
diff options
context:
space:
mode:
authorKirill Volinsky <mataes2007@gmail.com>2014-12-25 19:42:00 +0000
committerKirill Volinsky <mataes2007@gmail.com>2014-12-25 19:42:00 +0000
commit12e3e7f057bdb3d965a944d6c97fe7f222158eee (patch)
tree03cc4e03671c7faa80c5df9c4bd99e6e0825f21f /src/mir_core/threads.cpp
parent14bf9d366e6c23ad44c8266f87405a401dfa3f90 (diff)
files structure changed
git-svn-id: http://svn.miranda-ng.org/main/trunk@11638 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
Diffstat (limited to 'src/mir_core/threads.cpp')
-rw-r--r--src/mir_core/threads.cpp364
1 files changed, 0 insertions, 364 deletions
diff --git a/src/mir_core/threads.cpp b/src/mir_core/threads.cpp
deleted file mode 100644
index b1d6a23ebd..0000000000
--- a/src/mir_core/threads.cpp
+++ /dev/null
@@ -1,364 +0,0 @@
-/*
-
-Miranda NG: the free IM client for Microsoft* Windows*
-
-Copyright (c) 2012-14 Miranda NG project (http://miranda-ng.org),
-Copyright (c) 2000-12 Miranda IM project,
-all portions of this codebase are copyrighted to the people
-listed in contributors.txt.
-
-This program is free software; you can redistribute it and/or
-modify it under the terms of the GNU General Public License
-as published by the Free Software Foundation; either version 2
-of the License, or (at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-*/
-
-#include "commonheaders.h"
-
-#include <m_netlib.h>
-
-/////////////////////////////////////////////////////////////////////////////////////////
-// APC and mutex functions
-
-static void __stdcall DummyAPCFunc(ULONG_PTR)
-{
- /* called in the context of thread that cleared it's APC queue */
- return;
-}
-
-static int MirandaWaitForMutex(HANDLE hEvent)
-{
- for (;;) {
- // will get WAIT_IO_COMPLETE for QueueUserAPC() which isnt a result
- DWORD rc = MsgWaitForMultipleObjectsEx(1, &hEvent, INFINITE, QS_ALLINPUT, MWMO_ALERTABLE);
- if (rc == WAIT_OBJECT_0 + 1) {
- MSG msg;
- while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
- if (IsDialogMessage(msg.hwnd, &msg)) continue;
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
- }
- else if (rc == WAIT_OBJECT_0) { // got object
- return 1;
- }
- else if (rc == WAIT_ABANDONED_0 || rc == WAIT_FAILED)
- return 0;
- }
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-// exception handling
-
-static DWORD __cdecl sttDefaultFilter(DWORD, EXCEPTION_POINTERS*)
-{
- return EXCEPTION_EXECUTE_HANDLER;
-}
-
-pfnExceptionFilter pMirandaExceptFilter = sttDefaultFilter;
-
-MIR_CORE_DLL(pfnExceptionFilter) GetExceptionFilter()
-{
- return pMirandaExceptFilter;
-}
-
-MIR_CORE_DLL(pfnExceptionFilter) SetExceptionFilter(pfnExceptionFilter pMirandaExceptFilter)
-{
- pfnExceptionFilter oldOne = pMirandaExceptFilter;
- if (pMirandaExceptFilter != 0)
- pMirandaExceptFilter = pMirandaExceptFilter;
- return oldOne;
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-// thread support functions
-
-struct THREAD_WAIT_ENTRY
-{
- DWORD dwThreadId; // valid if hThread isn't signalled
- HANDLE hThread;
- HINSTANCE hOwner;
- void *pObject, *pEntryPoint;
-};
-
-static LIST<THREAD_WAIT_ENTRY> threads(10, NumericKeySortT);
-
-struct FORK_ARG
-{
- HANDLE hEvent;
- union
- {
- pThreadFunc threadcode;
- pThreadFuncEx threadcodeex;
- };
- void *arg, *owner;
-};
-
-/////////////////////////////////////////////////////////////////////////////////////////
-// forkthread - starts a new thread
-
-void __cdecl forkthread_r(void *arg)
-{
- FORK_ARG *fa = (FORK_ARG*)arg;
- pThreadFunc callercode = fa->threadcode;
- void *cookie = fa->arg;
- Thread_Push((HINSTANCE)callercode);
- SetEvent(fa->hEvent);
-
- callercode(cookie);
-
- SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL);
- Thread_Pop();
-}
-
-MIR_CORE_DLL(UINT_PTR) forkthread(void(__cdecl *threadcode)(void*), unsigned long stacksize, void *arg)
-{
- FORK_ARG fa;
- fa.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
- fa.threadcode = threadcode;
- fa.arg = arg;
- UINT_PTR rc = _beginthread(forkthread_r, stacksize, &fa);
- if ((UINT_PTR)-1L != rc)
- WaitForSingleObject(fa.hEvent, INFINITE);
-
- CloseHandle(fa.hEvent);
- return rc;
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-// forkthreadex - starts a new thread with the extended info and returns the thread id
-
-unsigned __stdcall forkthreadex_r(void * arg)
-{
- struct FORK_ARG *fa = (struct FORK_ARG *)arg;
- pThreadFuncEx threadcode = fa->threadcodeex;
- pThreadFuncOwner threadcodeex = (pThreadFuncOwner)fa->threadcodeex;
- void *cookie = fa->arg;
- void *owner = fa->owner;
- unsigned long rc = 0;
-
- Thread_Push((HINSTANCE)threadcode, fa->owner);
- SetEvent(fa->hEvent);
- if (owner)
- rc = threadcodeex(owner, cookie);
- else
- rc = threadcode(cookie);
-
- SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL);
- Thread_Pop();
- return rc;
-}
-
-MIR_CORE_DLL(UINT_PTR) forkthreadex(
- void *sec,
- unsigned stacksize,
- unsigned(__stdcall *threadcode)(void*),
- void *owner,
- void *arg,
- unsigned *thraddr)
-{
- struct FORK_ARG fa = { 0 };
- fa.threadcodeex = threadcode;
- fa.arg = arg;
- fa.owner = owner;
- fa.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
- UINT_PTR rc = _beginthreadex(sec, stacksize, forkthreadex_r, (void *)&fa, 0, thraddr);
- if (rc)
- WaitForSingleObject(fa.hEvent, INFINITE);
-
- CloseHandle(fa.hEvent);
- return rc;
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-MIR_CORE_DLL(void) KillObjectThreads(void* owner)
-{
- if (owner == NULL)
- return;
-
- WaitForSingleObject(hStackMutex, INFINITE);
-
- HANDLE *threadPool = (HANDLE*)alloca(threads.getCount()*sizeof(HANDLE));
- int threadCount = 0;
-
- for (int j = threads.getCount(); j--;) {
- THREAD_WAIT_ENTRY *p = threads[j];
- if (p->pObject == owner)
- threadPool[threadCount++] = p->hThread;
- }
- ReleaseMutex(hStackMutex);
-
- // is there anything to kill?
- if (threadCount > 0) {
- if (WaitForMultipleObjects(threadCount, threadPool, TRUE, 5000) == WAIT_TIMEOUT) {
- // forcibly kill all remaining threads after 5 secs
- WaitForSingleObject(hStackMutex, INFINITE);
- for (int j = threads.getCount() - 1; j >= 0; j--) {
- THREAD_WAIT_ENTRY* p = threads[j];
- if (p->pObject == owner) {
- char szModuleName[MAX_PATH];
- GetModuleFileNameA(p->hOwner, szModuleName, sizeof(szModuleName));
- Netlib_Logf(0, "Killing objec thread %s:%p", szModuleName, p->dwThreadId);
- TerminateThread(p->hThread, 9999);
- CloseHandle(p->hThread);
- threads.remove(j);
- mir_free(p);
- }
- }
- ReleaseMutex(hStackMutex);
- }
- }
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-static void CALLBACK KillAllThreads(HWND, UINT, UINT_PTR, DWORD)
-{
- if (MirandaWaitForMutex(hStackMutex)) {
- for (int j = 0; j < threads.getCount(); j++) {
- THREAD_WAIT_ENTRY *p = threads[j];
- char szModuleName[MAX_PATH];
- GetModuleFileNameA(p->hOwner, szModuleName, sizeof(szModuleName));
- Netlib_Logf(0, "Killing thread %s:%p (%p)", szModuleName, p->dwThreadId, p->pEntryPoint);
- TerminateThread(p->hThread, 9999);
- CloseHandle(p->hThread);
- mir_free(p);
- }
-
- threads.destroy();
-
- ReleaseMutex(hStackMutex);
- SetEvent(hThreadQueueEmpty);
- }
-}
-
-MIR_CORE_DLL(void) Thread_Wait(void)
-{
- // acquire the list and wake up any alertable threads
- if (MirandaWaitForMutex(hStackMutex)) {
- for (int j = 0; j < threads.getCount(); j++)
- QueueUserAPC(DummyAPCFunc, threads[j]->hThread, 0);
- ReleaseMutex(hStackMutex);
- }
-
- // give all unclosed threads 5 seconds to close
- SetTimer(NULL, 0, 5000, KillAllThreads);
-
- // wait til the thread list is empty
- MirandaWaitForMutex(hThreadQueueEmpty);
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-typedef LONG (WINAPI *pNtQIT)(HANDLE, LONG, PVOID, ULONG, PULONG);
-#define ThreadQuerySetWin32StartAddress 9
-
-static void* GetCurrentThreadEntryPoint()
-{
- pNtQIT NtQueryInformationThread = (pNtQIT)GetProcAddress(GetModuleHandle(_T("ntdll.dll")), "NtQueryInformationThread");
- if (NtQueryInformationThread == NULL) return 0;
-
- HANDLE hDupHandle, hCurrentProcess = GetCurrentProcess();
- if (!DuplicateHandle(hCurrentProcess, GetCurrentThread(), hCurrentProcess, &hDupHandle, THREAD_QUERY_INFORMATION, FALSE, 0)) {
- SetLastError(ERROR_ACCESS_DENIED);
- return NULL;
- }
-
- DWORD_PTR dwStartAddress;
- LONG ntStatus = NtQueryInformationThread(hDupHandle, ThreadQuerySetWin32StartAddress, &dwStartAddress, sizeof(DWORD_PTR), NULL);
- CloseHandle(hDupHandle);
-
- return (ntStatus != ERROR_SUCCESS) ? NULL : (void*)dwStartAddress;
-}
-
-MIR_CORE_DLL(INT_PTR) Thread_Push(HINSTANCE hInst, void* pOwner)
-{
- ResetEvent(hThreadQueueEmpty); // thread list is not empty
- if (WaitForSingleObject(hStackMutex, INFINITE) == WAIT_OBJECT_0) {
- THREAD_WAIT_ENTRY* p = (THREAD_WAIT_ENTRY*)mir_calloc(sizeof(THREAD_WAIT_ENTRY));
-
- DuplicateHandle(GetCurrentProcess(), GetCurrentThread(), GetCurrentProcess(), &p->hThread, 0, FALSE, DUPLICATE_SAME_ACCESS);
- p->dwThreadId = GetCurrentThreadId();
- p->pObject = pOwner;
- if (pluginListAddr.getIndex(hInst) != -1)
- p->hOwner = hInst;
- else
- p->hOwner = GetInstByAddress((hInst != NULL) ? (PVOID)hInst : GetCurrentThreadEntryPoint());
- p->pEntryPoint = hInst;
-
- threads.insert(p);
-
- ReleaseMutex(hStackMutex);
- }
- return 0;
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-MIR_CORE_DLL(INT_PTR) Thread_Pop()
-{
- if (WaitForSingleObject(hStackMutex, INFINITE) == WAIT_OBJECT_0) {
- DWORD dwThreadId = GetCurrentThreadId();
- for (int j = 0; j < threads.getCount(); j++) {
- THREAD_WAIT_ENTRY *p = threads[j];
- if (p->dwThreadId == dwThreadId) {
- SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL);
- CloseHandle(p->hThread);
- threads.remove(j);
- mir_free(p);
-
- if (!threads.getCount()) {
- threads.destroy();
- ReleaseMutex(hStackMutex);
- SetEvent(hThreadQueueEmpty); // thread list is empty now
- return 0;
- }
-
- ReleaseMutex(hStackMutex);
- return 0;
- }
- }
- ReleaseMutex(hStackMutex);
- }
- return 1;
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-const DWORD MS_VC_EXCEPTION=0x406D1388;
-
-#pragma pack(push,8)
-typedef struct tagTHREADNAME_INFO
-{
- DWORD dwType; // Must be 0x1000.
- LPCSTR szName; // Pointer to name (in user addr space).
- DWORD dwThreadID; // Thread ID (-1=caller thread).
- DWORD dwFlags; // Reserved for future use, must be zero.
-} THREADNAME_INFO;
-#pragma pack(pop)
-
-MIR_CORE_DLL(void) Thread_SetName(const char *szThreadName)
-{
- THREADNAME_INFO info;
- info.dwType = 0x1000;
- info.szName = szThreadName;
- info.dwThreadID = GetCurrentThreadId();
- info.dwFlags = 0;
-
- __try {
- RaiseException(MS_VC_EXCEPTION, 0, sizeof(info) / sizeof(ULONG_PTR), (ULONG_PTR*)&info);
- }
- __except (EXCEPTION_EXECUTE_HANDLER)
- {}
-}