lib/arch/win32: Use standard mutex primitives in threading utilities
This commit is contained in:
parent
959306fb1b
commit
734588827f
|
@ -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,21 +294,21 @@ 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
|
// ref the target so it can't go away while we're watching it
|
||||||
refThread(target);
|
refThread(target);
|
||||||
|
}
|
||||||
unlockMutex(m_threadMutex);
|
|
||||||
|
|
||||||
// convert timeout
|
// convert timeout
|
||||||
DWORD t;
|
DWORD t;
|
||||||
|
@ -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_();
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue