summaryrefslogtreecommitdiff
path: root/src/mir_core
diff options
context:
space:
mode:
authorGeorge Hazan <ghazan@miranda.im>2018-04-23 17:25:10 +0300
committerGeorge Hazan <ghazan@miranda.im>2018-04-23 17:25:10 +0300
commit389fa94f1b09f0b1e97d2ecc11c994a12801b898 (patch)
tree5743c2ecf7ee3376407a5d1991d2f039bab00d62 /src/mir_core
parentc475a38756f0f7a0404b62e6c4f924ca9900b25a (diff)
pack of fixes for complete dynamic reload of protocols
fixes #1295
Diffstat (limited to 'src/mir_core')
-rw-r--r--src/mir_core/src/threads.cpp61
1 files changed, 40 insertions, 21 deletions
diff --git a/src/mir_core/src/threads.cpp b/src/mir_core/src/threads.cpp
index a71d366585..de9474a101 100644
--- a/src/mir_core/src/threads.cpp
+++ b/src/mir_core/src/threads.cpp
@@ -208,12 +208,9 @@ MIR_CORE_DLL(HANDLE) mir_forkthreadowner(pThreadFuncOwner aFunc, void *owner, vo
/////////////////////////////////////////////////////////////////////////////////////////
-MIR_CORE_DLL(void) KillObjectThreads(void* owner)
+static void __cdecl KillObjectThreadsWorker(void* owner)
{
- if (owner == nullptr)
- return;
-
- HANDLE *threadPool = (HANDLE*)alloca(threads.getCount()*sizeof(HANDLE));
+ HANDLE *threadPool = (HANDLE*)alloca(threads.getCount() * sizeof(HANDLE));
int threadCount = 0;
{
mir_cslock lck(csThreads);
@@ -224,22 +221,44 @@ MIR_CORE_DLL(void) KillObjectThreads(void* owner)
}
// is there anything to kill?
- if (threadCount > 0) {
- if (WaitForMultipleObjects(threadCount, threadPool, TRUE, 5000) == WAIT_TIMEOUT) {
- // forcibly kill all remaining threads after 5 secs
- mir_cslock lck(csThreads);
- auto T = threads.rev_iter();
- for (auto &it : T) {
- if (it->pObject == owner) {
- char szModuleName[MAX_PATH];
- GetModuleFileNameA(it->hOwner, szModuleName, sizeof(szModuleName));
- Netlib_Logf(nullptr, "Killing object thread %s:%p", szModuleName, it->dwThreadId);
- TerminateThread(it->hThread, 9999);
- CloseHandle(it->hThread);
- mir_free(it);
- threads.remove(T.indexOf(&it));
- }
- }
+ if (threadCount == 0)
+ return;
+
+ // wait'em all
+ if (WaitForMultipleObjects(threadCount, threadPool, TRUE, 5000) != WAIT_TIMEOUT)
+ return;
+
+ // forcibly kill all remaining threads after 5 secs
+ mir_cslock lck(csThreads);
+ auto T = threads.rev_iter();
+ for (auto &it : T) {
+ if (it->pObject == owner) {
+ char szModuleName[MAX_PATH];
+ GetModuleFileNameA(it->hOwner, szModuleName, sizeof(szModuleName));
+ Netlib_Logf(nullptr, "Killing object thread %s:%p", szModuleName, it->dwThreadId);
+ TerminateThread(it->hThread, 9999);
+ CloseHandle(it->hThread);
+ mir_free(it);
+ threads.remove(T.indexOf(&it));
+ }
+ }
+}
+
+MIR_CORE_DLL(void) KillObjectThreads(void* owner)
+{
+ if (owner == nullptr)
+ return;
+
+ DWORD dwTicks = GetTickCount() + 6000;
+ HANDLE hThread = mir_forkthread(KillObjectThreadsWorker, owner);
+ while (GetTickCount() < dwTicks) {
+ if (WAIT_OBJECT_0 == MsgWaitForMultipleObjectsEx(1, &hThread, 50, QS_ALLPOSTMESSAGE | QS_ALLINPUT, MWMO_ALERTABLE))
+ break;
+
+ MSG msg;
+ while (PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE)) {
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
}
}
}