refactor: use std::mutex in ArchMutithreadWindows

This commit is contained in:
sithlord48 2025-06-10 20:34:29 -04:00 committed by Nick Bolton
parent f89168d00a
commit d535593d1d
2 changed files with 45 additions and 59 deletions

View file

@ -85,8 +85,7 @@ ArchMultithreadWindows::ArchMultithreadWindows()
m_signalUserData[i] = nullptr; m_signalUserData[i] = nullptr;
} }
// create mutex for thread list std::lock_guard<std::mutex> lock(m_threadMutex);
m_threadMutex = newMutex();
// create thread for calling (main) thread and add it to our // create thread for calling (main) thread and add it to our
// list. no need to lock the mutex since we're the only thread. // list. no need to lock the mutex since we're the only thread.
@ -104,33 +103,25 @@ ArchMultithreadWindows::~ArchMultithreadWindows()
for (ThreadList::iterator index = m_threadList.begin(); index != m_threadList.end(); ++index) { for (ThreadList::iterator index = m_threadList.begin(); index != m_threadList.end(); ++index) {
delete *index; delete *index;
} }
// done with mutex
delete m_threadMutex;
} }
void ArchMultithreadWindows::setNetworkDataForCurrentThread(void *data) void ArchMultithreadWindows::setNetworkDataForCurrentThread(void *data)
{ {
lockMutex(m_threadMutex); std::lock_guard<std::mutex> lock(m_threadMutex);
ArchThreadImpl *thread = findNoRef(GetCurrentThreadId()); ArchThreadImpl *thread = findNoRef(GetCurrentThreadId());
thread->m_networkData = data; thread->m_networkData = data;
unlockMutex(m_threadMutex);
} }
void *ArchMultithreadWindows::getNetworkDataForThread(ArchThread thread) void *ArchMultithreadWindows::getNetworkDataForThread(ArchThread thread)
{ {
lockMutex(m_threadMutex); std::lock_guard<std::mutex> lock(m_threadMutex);
void *data = thread->m_networkData; return thread->m_networkData;
unlockMutex(m_threadMutex);
return data;
} }
HANDLE HANDLE ArchMultithreadWindows::getCancelEventForCurrentThread()
ArchMultithreadWindows::getCancelEventForCurrentThread()
{ {
lockMutex(m_threadMutex); std::lock_guard<std::mutex> lock(m_threadMutex);
ArchThreadImpl *thread = findNoRef(GetCurrentThreadId()); ArchThreadImpl *thread = findNoRef(GetCurrentThreadId());
unlockMutex(m_threadMutex);
return thread->m_cancel; return thread->m_cancel;
} }
@ -263,7 +254,8 @@ void ArchMultithreadWindows::unlockMutex(ArchMutex mutex)
ArchThread ArchMultithreadWindows::newThread(ThreadFunc func, void *data) ArchThread ArchMultithreadWindows::newThread(ThreadFunc func, void *data)
{ {
lockMutex(m_threadMutex); // note that the child thread will wait until we release this mutex
std::lock_guard<std::mutex> lock(m_threadMutex);
// create thread impl for new thread // create thread impl for new thread
ArchThreadImpl *thread = new ArchThreadImpl; ArchThreadImpl *thread = new ArchThreadImpl;
@ -288,17 +280,13 @@ ArchThread ArchMultithreadWindows::newThread(ThreadFunc func, void *data)
refThread(thread); refThread(thread);
} }
// note that the child thread will wait until we release this mutex
unlockMutex(m_threadMutex);
return thread; return thread;
} }
ArchThread ArchMultithreadWindows::newCurrentThread() ArchThread ArchMultithreadWindows::newCurrentThread()
{ {
lockMutex(m_threadMutex); std::lock_guard<std::mutex> lock(m_threadMutex);
ArchThreadImpl *thread = find(GetCurrentThreadId()); ArchThreadImpl *thread = find(GetCurrentThreadId());
unlockMutex(m_threadMutex);
assert(thread != nullptr); assert(thread != nullptr);
return thread; return thread;
} }
@ -315,10 +303,11 @@ void ArchMultithreadWindows::closeThread(ArchThread thread)
} }
// remove thread from list // remove thread from list
lockMutex(m_threadMutex); {
assert(findNoRefOrCreate(thread->m_id) == thread); std::lock_guard<std::mutex> lock(m_threadMutex);
erase(thread); assert(findNoRefOrCreate(thread->m_id) == thread);
unlockMutex(m_threadMutex); erase(thread);
}
// done with thread // done with thread
delete thread; delete thread;
@ -400,9 +389,8 @@ void ArchMultithreadWindows::setPriorityOfThread(ArchThread thread, int n)
void ArchMultithreadWindows::testCancelThread() void ArchMultithreadWindows::testCancelThread()
{ {
// find current thread // find current thread
lockMutex(m_threadMutex); std::lock_guard<std::mutex> lock(m_threadMutex);
ArchThreadImpl *thread = findNoRef(GetCurrentThreadId()); ArchThreadImpl *thread = findNoRef(GetCurrentThreadId());
unlockMutex(m_threadMutex);
// test cancel on thread // test cancel on thread
testCancelThreadImpl(thread); testCancelThreadImpl(thread);
@ -412,22 +400,19 @@ bool ArchMultithreadWindows::wait(ArchThread target, double timeout)
{ {
assert(target != nullptr); assert(target != nullptr);
lockMutex(m_threadMutex); ArchThreadImpl *self = nullptr;
{
// find current thread std::lock_guard<std::mutex> lock(m_threadMutex);
ArchThreadImpl *self = findNoRef(GetCurrentThreadId()); // find current thread
self = findNoRef(GetCurrentThreadId());
// ignore wait if trying to wait on ourself // ignore wait if trying to wait on ourself
if (target == self) { if (target == self) {
unlockMutex(m_threadMutex); return false;
return false; }
// ref the target so it can't go away while we're watching it
refThread(target);
} }
// ref the target so it can't go away while we're watching it
refThread(target);
unlockMutex(m_threadMutex);
// convert timeout // convert timeout
DWORD t; DWORD t;
if (timeout < 0.0) { if (timeout < 0.0) {
@ -480,10 +465,8 @@ bool ArchMultithreadWindows::isExitedThread(ArchThread thread)
void *ArchMultithreadWindows::getResultOfThread(ArchThread thread) void *ArchMultithreadWindows::getResultOfThread(ArchThread thread)
{ {
lockMutex(m_threadMutex); std::lock_guard<std::mutex> lock(m_threadMutex);
void *result = thread->m_result; return thread->m_result;
unlockMutex(m_threadMutex);
return result;
} }
IArchMultithread::ThreadID ArchMultithreadWindows::getIDOfThread(ArchThread thread) IArchMultithread::ThreadID ArchMultithreadWindows::getIDOfThread(ArchThread thread)
@ -493,22 +476,20 @@ IArchMultithread::ThreadID ArchMultithreadWindows::getIDOfThread(ArchThread thre
void ArchMultithreadWindows::setSignalHandler(ESignal signal, SignalFunc func, void *userData) void ArchMultithreadWindows::setSignalHandler(ESignal signal, SignalFunc func, void *userData)
{ {
lockMutex(m_threadMutex); std::lock_guard<std::mutex> lock(m_threadMutex);
m_signalFunc[signal] = func; m_signalFunc[signal] = func;
m_signalUserData[signal] = userData; m_signalUserData[signal] = userData;
unlockMutex(m_threadMutex);
} }
void ArchMultithreadWindows::raiseSignal(ESignal signal) void ArchMultithreadWindows::raiseSignal(ESignal signal)
{ {
lockMutex(m_threadMutex); std::lock_guard<std::mutex> lock(m_threadMutex);
if (m_signalFunc[signal] != nullptr) { if (m_signalFunc[signal] != nullptr) {
m_signalFunc[signal](signal, m_signalUserData[signal]); m_signalFunc[signal](signal, m_signalUserData[signal]);
ARCH->unblockPollSocket(m_mainThread); ARCH->unblockPollSocket(m_mainThread);
} else if (signal == kINTERRUPT || signal == kTERMINATE) { } else if (signal == kINTERRUPT || signal == kTERMINATE) {
ARCH->cancelThread(m_mainThread); ARCH->cancelThread(m_mainThread);
} }
unlockMutex(m_threadMutex);
} }
ArchThreadImpl *ArchMultithreadWindows::find(DWORD id) ArchThreadImpl *ArchMultithreadWindows::find(DWORD id)
@ -586,11 +567,10 @@ void ArchMultithreadWindows::testCancelThreadImpl(ArchThreadImpl *thread)
} }
// update cancel state // update cancel state
lockMutex(m_threadMutex); std::lock_guard<std::mutex> lock(m_threadMutex);
bool cancel = !thread->m_cancelling; bool cancel = !thread->m_cancelling;
thread->m_cancelling = true; thread->m_cancelling = true;
ResetEvent(thread->m_cancel); ResetEvent(thread->m_cancel);
unlockMutex(m_threadMutex);
// unwind thread's stack if cancelling // unwind thread's stack if cancelling
if (cancel) { if (cancel) {
@ -613,8 +593,9 @@ unsigned int __stdcall ArchMultithreadWindows::threadFunc(void *vrep)
void ArchMultithreadWindows::doThreadFunc(ArchThread thread) void ArchMultithreadWindows::doThreadFunc(ArchThread thread)
{ {
// wait for parent to initialize this object // wait for parent to initialize this object
lockMutex(m_threadMutex); {
unlockMutex(m_threadMutex); std::lock_guard<std::mutex> lock(m_threadMutex);
}
void *result = nullptr; void *result = nullptr;
try { try {
@ -626,16 +607,20 @@ void ArchMultithreadWindows::doThreadFunc(ArchThread thread)
// client called cancel() // client called cancel()
} catch (...) { } catch (...) {
// note -- don't catch (...) to avoid masking bugs // note -- don't catch (...) to avoid masking bugs
SetEvent(thread->m_exit); {
std::lock_guard<std::mutex> lock(m_threadMutex);
SetEvent(thread->m_exit);
}
closeThread(thread); closeThread(thread);
throw; throw;
} }
// thread has exited // thread has exited
lockMutex(m_threadMutex); {
thread->m_result = result; std::lock_guard<std::mutex> lock(m_threadMutex);
unlockMutex(m_threadMutex); thread->m_result = result;
SetEvent(thread->m_exit); SetEvent(thread->m_exit);
}
// done with thread // done with thread
closeThread(thread); closeThread(thread);

View file

@ -10,6 +10,7 @@
#include "arch/IArchMultithread.h" #include "arch/IArchMultithread.h"
#include <list> #include <list>
#include <mutex>
#define WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN
#include <Windows.h> #include <Windows.h>
@ -103,7 +104,7 @@ private:
static ArchMultithreadWindows *s_instance; static ArchMultithreadWindows *s_instance;
ArchMutex m_threadMutex; std::mutex m_threadMutex;
ThreadList m_threadList; ThreadList m_threadList;
ArchThread m_mainThread; ArchThread m_mainThread;