lib/arch/win32: Use standard mutex primitives in threading utilities

This commit is contained in:
Povilas Kanapickas 2021-11-03 02:58:42 +02:00
parent 959306fb1b
commit 734588827f
2 changed files with 35 additions and 49 deletions

View File

@ -91,9 +91,6 @@ ArchMultithreadWindows::ArchMultithreadWindows()
m_signalUserData[i] = NULL; m_signalUserData[i] = NULL;
} }
// create mutex for thread list
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.
m_mainThread = new ArchThreadImpl; m_mainThread = new ArchThreadImpl;
@ -111,35 +108,28 @@ ArchMultithreadWindows::~ArchMultithreadWindows()
index != m_threadList.end(); ++index) { index != m_threadList.end(); ++index) {
delete *index; delete *index;
} }
// done with mutex
delete m_threadMutex;
} }
void void
ArchMultithreadWindows::setNetworkDataForCurrentThread(void* data) ArchMultithreadWindows::setNetworkDataForCurrentThread(void* data)
{ {
lockMutex(m_threadMutex); std::lock_guard<std::mutex> lock(thread_mutex_);
ArchThreadImpl* thread = findNoRef(GetCurrentThreadId()); ArchThreadImpl* thread = findNoRef(GetCurrentThreadId());
thread->m_networkData = data; thread->m_networkData = data;
unlockMutex(m_threadMutex);
} }
void* void*
ArchMultithreadWindows::getNetworkDataForThread(ArchThread thread) ArchMultithreadWindows::getNetworkDataForThread(ArchThread thread)
{ {
lockMutex(m_threadMutex); std::lock_guard<std::mutex> lock(thread_mutex_);
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(thread_mutex_);
ArchThreadImpl* thread = findNoRef(GetCurrentThreadId()); ArchThreadImpl* thread = findNoRef(GetCurrentThreadId());
unlockMutex(m_threadMutex);
return thread->m_cancel; return thread->m_cancel;
} }
@ -151,7 +141,8 @@ ArchMultithreadWindows::getInstance()
ArchThread ArchMultithreadWindows::newThread(const std::function<void()>& func) ArchThread ArchMultithreadWindows::newThread(const std::function<void()>& func)
{ {
lockMutex(m_threadMutex); // note that the child thread will wait until we release this mutex
std::lock_guard<std::mutex> lock(thread_mutex_);
// create thread impl for new thread // create thread impl for new thread
ArchThreadImpl* thread = new ArchThreadImpl; ArchThreadImpl* thread = new ArchThreadImpl;
@ -177,18 +168,15 @@ ArchThread ArchMultithreadWindows::newThread(const std::function<void()>& func)
refThread(thread); refThread(thread);
} }
// note that the child thread will wait until we release this mutex
unlockMutex(m_threadMutex);
return thread; return thread;
} }
ArchThread ArchThread
ArchMultithreadWindows::newCurrentThread() ArchMultithreadWindows::newCurrentThread()
{ {
lockMutex(m_threadMutex); std::lock_guard<std::mutex> lock(thread_mutex_);
ArchThreadImpl* thread = find(GetCurrentThreadId()); ArchThreadImpl* thread = find(GetCurrentThreadId());
unlockMutex(m_threadMutex);
assert(thread != NULL); assert(thread != NULL);
return thread; return thread;
} }
@ -206,12 +194,9 @@ ArchMultithreadWindows::closeThread(ArchThread thread)
} }
// remove thread from list // remove thread from list
lockMutex(m_threadMutex); std::lock_guard<std::mutex> lock(thread_mutex_);
assert(findNoRefOrCreate(thread->m_id) == thread); assert(findNoRefOrCreate(thread->m_id) == thread);
erase(thread); erase(thread);
unlockMutex(m_threadMutex);
// done with thread
delete thread; delete thread;
} }
} }
@ -294,10 +279,11 @@ ArchMultithreadWindows::setPriorityOfThread(ArchThread thread, int n)
void void
ArchMultithreadWindows::testCancelThread() ArchMultithreadWindows::testCancelThread()
{ {
// find current thread ArchThreadImpl* thread = nullptr;
lockMutex(m_threadMutex); {
ArchThreadImpl* thread = findNoRef(GetCurrentThreadId()); std::lock_guard<std::mutex> lock(thread_mutex_);
unlockMutex(m_threadMutex); thread = findNoRef(GetCurrentThreadId());
}
// test cancel on thread // test cancel on thread
testCancelThreadImpl(thread); testCancelThreadImpl(thread);
@ -308,22 +294,22 @@ ArchMultithreadWindows::wait(ArchThread target, double timeout)
{ {
assert(target != NULL); assert(target != NULL);
lockMutex(m_threadMutex); ArchThreadImpl* self = nullptr;
{
std::lock_guard<std::mutex> lock(thread_mutex_);
// find current thread // find current thread
ArchThreadImpl* self = findNoRef(GetCurrentThreadId()); 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) {
@ -388,16 +374,15 @@ void
ArchMultithreadWindows::setSignalHandler( ArchMultithreadWindows::setSignalHandler(
ESignal signal, SignalFunc func, void* userData) ESignal signal, SignalFunc func, void* userData)
{ {
lockMutex(m_threadMutex); std::lock_guard<std::mutex> lock(thread_mutex_);
m_signalFunc[signal] = func; m_signalFunc[signal] = func;
m_signalUserData[signal] = userData; m_signalUserData[signal] = userData;
unlockMutex(m_threadMutex);
} }
void void
ArchMultithreadWindows::raiseSignal(ESignal signal) ArchMultithreadWindows::raiseSignal(ESignal signal)
{ {
lockMutex(m_threadMutex); std::lock_guard<std::mutex> lock(thread_mutex_);
if (m_signalFunc[signal] != NULL) { if (m_signalFunc[signal] != NULL) {
m_signalFunc[signal](signal, m_signalUserData[signal]); m_signalFunc[signal](signal, m_signalUserData[signal]);
ARCH->unblockPollSocket(m_mainThread); ARCH->unblockPollSocket(m_mainThread);
@ -405,7 +390,6 @@ ArchMultithreadWindows::raiseSignal(ESignal signal)
else if (signal == kINTERRUPT || signal == kTERMINATE) { else if (signal == kINTERRUPT || signal == kTERMINATE) {
ARCH->cancelThread(m_mainThread); ARCH->cancelThread(m_mainThread);
} }
unlockMutex(m_threadMutex);
} }
ArchThreadImpl* ArchThreadImpl*
@ -492,11 +476,11 @@ ArchMultithreadWindows::testCancelThreadImpl(ArchThreadImpl* thread)
} }
// update cancel state // update cancel state
lockMutex(m_threadMutex); std::lock_guard<std::mutex> lock(thread_mutex_);
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) {
@ -521,8 +505,9 @@ void
ArchMultithreadWindows::doThreadFunc(ArchThread thread) 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(thread_mutex_);
}
try { try {
thread->func_(); thread->func_();

View File

@ -23,6 +23,7 @@
#define WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN
#include <Windows.h> #include <Windows.h>
#include <mutex>
#define ARCH_MULTITHREAD ArchMultithreadWindows #define ARCH_MULTITHREAD ArchMultithreadWindows
@ -82,7 +83,7 @@ private:
static ArchMultithreadWindows* s_instance; static ArchMultithreadWindows* s_instance;
ArchMutex m_threadMutex; std::mutex thread_mutex_;
ThreadList m_threadList; ThreadList m_threadList;
ArchThread m_mainThread; ArchThread m_mainThread;