refactor: use std::mutex in place of ArchMutex in AtchMultiThreadPosix

port f71c68506e
This commit is contained in:
Povilas Kanapickas 2025-06-10 18:26:10 -04:00 committed by Nick Bolton
parent 5430625a7e
commit f4618ee085
2 changed files with 55 additions and 68 deletions

View file

@ -66,9 +66,6 @@ ArchMultithreadPosix::ArchMultithreadPosix()
m_signalUserData[i] = nullptr; m_signalUserData[i] = nullptr;
} }
// 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;
@ -104,25 +101,20 @@ ArchMultithreadPosix::ArchMultithreadPosix()
ArchMultithreadPosix::~ArchMultithreadPosix() ArchMultithreadPosix::~ArchMultithreadPosix()
{ {
assert(s_instance != nullptr); assert(s_instance != nullptr);
closeMutex(m_threadMutex);
s_instance = nullptr; s_instance = nullptr;
} }
void ArchMultithreadPosix::setNetworkDataForCurrentThread(void *data) void ArchMultithreadPosix::setNetworkDataForCurrentThread(void *data)
{ {
lockMutex(m_threadMutex); std::lock_guard<std::mutex> lock(m_threadMutex);
ArchThreadImpl *thread = find(pthread_self()); ArchThreadImpl *thread = find(pthread_self());
thread->m_networkData = data; thread->m_networkData = data;
unlockMutex(m_threadMutex);
} }
void *ArchMultithreadPosix::getNetworkDataForThread(ArchThread thread) void *ArchMultithreadPosix::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;
} }
ArchMultithreadPosix *ArchMultithreadPosix::getInstance() ArchMultithreadPosix *ArchMultithreadPosix::getInstance()
@ -292,7 +284,8 @@ ArchThread ArchMultithreadPosix::newThread(ThreadFunc func, void *data)
startSignalHandler(); startSignalHandler();
} }
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
auto *thread = new ArchThreadImpl; auto *thread = new ArchThreadImpl;
@ -321,17 +314,13 @@ ArchThread ArchMultithreadPosix::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 ArchMultithreadPosix::newCurrentThread() ArchThread ArchMultithreadPosix::newCurrentThread()
{ {
lockMutex(m_threadMutex); std::lock_guard<std::mutex> lock(m_threadMutex);
ArchThreadImpl *thread = find(pthread_self()); ArchThreadImpl *thread = find(pthread_self());
unlockMutex(m_threadMutex);
assert(thread != nullptr); assert(thread != nullptr);
return thread; return thread;
} }
@ -348,10 +337,11 @@ void ArchMultithreadPosix::closeThread(ArchThread thread)
} }
// remove thread from list // remove thread from list
lockMutex(m_threadMutex); {
assert(findNoRef(thread->m_thread) == thread); std::lock_guard<std::mutex> lock(m_threadMutex);
erase(thread); assert(findNoRef(thread->m_thread) == thread);
unlockMutex(m_threadMutex); erase(thread);
}
// done with thread // done with thread
delete thread; delete thread;
@ -370,12 +360,14 @@ void ArchMultithreadPosix::cancelThread(ArchThread thread)
// set cancel and wakeup flags if thread can be cancelled // set cancel and wakeup flags if thread can be cancelled
bool wakeup = false; bool wakeup = false;
lockMutex(m_threadMutex);
if (!thread->m_exited && !thread->m_cancelling) { {
thread->m_cancel = true; std::lock_guard<std::mutex> lock(m_threadMutex);
wakeup = true; if (!thread->m_exited && !thread->m_cancelling) {
thread->m_cancel = true;
wakeup = true;
}
} }
unlockMutex(m_threadMutex);
// force thread to exit system calls if wakeup is true // force thread to exit system calls if wakeup is true
if (wakeup) { if (wakeup) {
@ -393,10 +385,11 @@ void ArchMultithreadPosix::setPriorityOfThread(ArchThread thread, int /*n*/)
void ArchMultithreadPosix::testCancelThread() void ArchMultithreadPosix::testCancelThread()
{ {
// find current thread // find current thread
lockMutex(m_threadMutex); ArchThreadImpl *thread = nullptr;
ArchThreadImpl *thread = findNoRef(pthread_self()); {
unlockMutex(m_threadMutex); std::lock_guard<std::mutex> lock(m_threadMutex);
thread = findNoRef(pthread_self());
}
// test cancel on thread // test cancel on thread
testCancelThreadImpl(thread); testCancelThreadImpl(thread);
} }
@ -405,22 +398,19 @@ bool ArchMultithreadPosix::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(pthread_self()); // find current thread
self = findNoRef(pthread_self());
// 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);
try { try {
// do first test regardless of timeout // do first test regardless of timeout
testCancelThreadImpl(self); testCancelThreadImpl(self);
@ -462,18 +452,14 @@ bool ArchMultithreadPosix::isSameThread(ArchThread thread1, ArchThread thread2)
bool ArchMultithreadPosix::isExitedThread(ArchThread thread) bool ArchMultithreadPosix::isExitedThread(ArchThread thread)
{ {
lockMutex(m_threadMutex); std::lock_guard<std::mutex> lock(m_threadMutex);
bool exited = thread->m_exited; return thread->m_exited;
unlockMutex(m_threadMutex);
return exited;
} }
void *ArchMultithreadPosix::getResultOfThread(ArchThread thread) void *ArchMultithreadPosix::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 ArchMultithreadPosix::getIDOfThread(ArchThread thread) IArchMultithread::ThreadID ArchMultithreadPosix::getIDOfThread(ArchThread thread)
@ -483,22 +469,20 @@ IArchMultithread::ThreadID ArchMultithreadPosix::getIDOfThread(ArchThread thread
void ArchMultithreadPosix::setSignalHandler(ESignal signal, SignalFunc func, void *userData) void ArchMultithreadPosix::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 ArchMultithreadPosix::raiseSignal(ESignal signal) void ArchMultithreadPosix::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]);
pthread_kill(m_mainThread->m_thread, SIGWAKEUP); pthread_kill(m_mainThread->m_thread, SIGWAKEUP);
} else if (signal == kINTERRUPT || signal == kTERMINATE) { } else if (signal == kINTERRUPT || signal == kTERMINATE) {
ARCH->cancelThread(m_mainThread); ARCH->cancelThread(m_mainThread);
} }
unlockMutex(m_threadMutex);
} }
void ArchMultithreadPosix::startSignalHandler() void ArchMultithreadPosix::startSignalHandler()
@ -586,14 +570,13 @@ void ArchMultithreadPosix::testCancelThreadImpl(ArchThreadImpl *thread)
assert(thread != nullptr); assert(thread != nullptr);
// update cancel state // update cancel state
lockMutex(m_threadMutex); std::lock_guard<std::mutex> lock(m_threadMutex);
bool cancel = false; bool cancel = false;
if (thread->m_cancel && !thread->m_cancelling) { if (thread->m_cancel && !thread->m_cancelling) {
thread->m_cancelling = true; thread->m_cancelling = true;
thread->m_cancel = false; thread->m_cancel = false;
cancel = true; cancel = true;
} }
unlockMutex(m_threadMutex);
// unwind thread's stack if cancelling // unwind thread's stack if cancelling
if (cancel) { if (cancel) {
@ -623,8 +606,9 @@ void ArchMultithreadPosix::doThreadFunc(ArchThread thread)
setPriorityOfThread(thread, 1); setPriorityOfThread(thread, 1);
// 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 {
@ -638,18 +622,20 @@ void ArchMultithreadPosix::doThreadFunc(ArchThread thread)
result = nullptr; result = nullptr;
} catch (...) { } catch (...) {
// note -- don't catch (...) to avoid masking bugs // note -- don't catch (...) to avoid masking bugs
lockMutex(m_threadMutex); {
thread->m_exited = true; std::lock_guard<std::mutex> lock(m_threadMutex);
unlockMutex(m_threadMutex); thread->m_exited = true;
}
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);
thread->m_exited = true; thread->m_result = result;
unlockMutex(m_threadMutex); thread->m_exited = true;
}
// 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>
#include <pthread.h> #include <pthread.h>
#define ARCH_MULTITHREAD ArchMultithreadPosix #define ARCH_MULTITHREAD ArchMultithreadPosix
@ -101,7 +102,7 @@ private:
bool m_newThreadCalled = false; bool m_newThreadCalled = false;
ArchMutex m_threadMutex; std::mutex m_threadMutex;
ArchThread m_mainThread; ArchThread m_mainThread;
ThreadList m_threadList; ThreadList m_threadList;
ThreadID m_nextID = 0; ThreadID m_nextID = 0;