lib: Switch ArchMutexLock to use std::unique_lock behind the scenes

This commit is contained in:
Povilas Kanapickas 2021-11-03 02:58:23 +02:00
parent cd356d7c3d
commit 9e7982f8ec
9 changed files with 31 additions and 23 deletions

View File

@ -64,6 +64,8 @@
# include "arch/unix/ArchInternetUnix.h" # include "arch/unix/ArchInternetUnix.h"
#endif #endif
#include <mutex>
/*! /*!
\def ARCH \def ARCH
This macro evaluates to the singleton Arch object. This macro evaluates to the singleton Arch object.
@ -125,15 +127,19 @@ private:
//! Convenience object to lock/unlock an arch mutex //! Convenience object to lock/unlock an arch mutex
class ArchMutexLock { class ArchMutexLock {
public: public:
ArchMutexLock(ArchMutex mutex) : m_mutex(mutex) ArchMutexLock(ArchMutex mutex) : lock{*mutex} {}
{ ArchMutexLock(ArchMutex mutex, std::adopt_lock_t) :
ARCH->lockMutex(m_mutex); lock{*mutex, std::adopt_lock}, adopted_{true}
} {}
~ArchMutexLock() ~ArchMutexLock()
{ {
ARCH->unlockMutex(m_mutex); if (adopted_) {
lock.release();
}
} }
std::unique_lock<std::mutex> lock;
private: private:
ArchMutex m_mutex; bool adopted_ = false;
}; };

View File

@ -17,12 +17,11 @@
*/ */
#include "IArchMultithread.h" #include "IArchMultithread.h"
#include "arch/Arch.h"
bool IArchMultithread::waitCondVar(ArchCond cond, ArchMutex mutex, bool IArchMultithread::waitCondVar(ArchCond cond, ArchMutexLock& lock,
double timeout) double timeout)
{ {
std::unique_lock<std::mutex> lock{*mutex, std::adopt_lock};
// we can't wait on a condition variable and also wake it up for // we can't wait on a condition variable and also wake it up for
// cancellation since we don't use posix cancellation. so we // cancellation since we don't use posix cancellation. so we
// must wake up periodically to check for cancellation. we // must wake up periodically to check for cancellation. we
@ -39,8 +38,7 @@ bool IArchMultithread::waitCondVar(ArchCond cond, ArchMutex mutex,
// see if we should cancel this thread // see if we should cancel this thread
testCancelThread(); testCancelThread();
auto ret = cond->wait_for(lock, seconds_to_chrono(timeout)); auto ret = cond->wait_for(lock.lock, seconds_to_chrono(timeout));
lock.release();
// check for cancel again // check for cancel again
testCancelThread(); testCancelThread();

View File

@ -32,6 +32,7 @@ using ArchMutex = std::mutex*;
An architecture dependent type holding the necessary data for a thread. An architecture dependent type holding the necessary data for a thread.
*/ */
class ArchThreadImpl; class ArchThreadImpl;
class ArchMutexLock;
/*! /*!
\var ArchThread \var ArchThread
@ -107,7 +108,7 @@ public:
(Cancellation point) (Cancellation point)
*/ */
bool waitCondVar(ArchCond cv, ArchMutex mutex, double timeout); bool waitCondVar(ArchCond cv, ArchMutexLock& lock, double timeout);
// //
// mutex methods // mutex methods

View File

@ -334,7 +334,8 @@ ArchDaemonWindows::doRunDaemon(RunFunc run)
// wait until we're told to start // wait until we're told to start
while (!isRunState(m_serviceState) && while (!isRunState(m_serviceState) &&
m_serviceState != SERVICE_STOP_PENDING) { m_serviceState != SERVICE_STOP_PENDING) {
ARCH->waitCondVar(m_serviceCondVar, m_serviceMutex, -1.0); ArchMutexLock lock{m_serviceMutex, std::adopt_lock};
ARCH->waitCondVar(m_serviceCondVar, lock, -1.0);
} }
// run unless told to stop // run unless told to stop
@ -581,7 +582,8 @@ ArchDaemonWindows::serviceHandler(DWORD ctrl)
setStatus(m_serviceState, 0, 5000); setStatus(m_serviceState, 0, 5000);
PostThreadMessage(m_daemonThreadID, m_quitMessage, 0, 0); PostThreadMessage(m_daemonThreadID, m_quitMessage, 0, 0);
while (isRunState(m_serviceState)) { while (isRunState(m_serviceState)) {
ARCH->waitCondVar(m_serviceCondVar, m_serviceMutex, -1.0); ArchMutexLock lock{m_serviceMutex, std::adopt_lock};
ARCH->waitCondVar(m_serviceCondVar, lock, -1.0);
} }
break; break;
@ -599,7 +601,8 @@ ArchDaemonWindows::serviceHandler(DWORD ctrl)
PostThreadMessage(m_daemonThreadID, m_quitMessage, 0, 0); PostThreadMessage(m_daemonThreadID, m_quitMessage, 0, 0);
ARCH->broadcastCondVar(m_serviceCondVar); ARCH->broadcastCondVar(m_serviceCondVar);
while (isRunState(m_serviceState)) { while (isRunState(m_serviceState)) {
ARCH->waitCondVar(m_serviceCondVar, m_serviceMutex, -1.0); ArchMutexLock lock{m_serviceMutex, std::adopt_lock};
ARCH->waitCondVar(m_serviceCondVar, lock, -1.0);
} }
break; break;

View File

@ -81,7 +81,7 @@ ArchTaskBarWindows::init()
// we're going to want to get a result from the thread we're // we're going to want to get a result from the thread we're
// about to create to know if it initialized successfully. // about to create to know if it initialized successfully.
// so we lock the condition variable. // so we lock the condition variable.
ARCH->lockMutex(m_mutex); ArchMutexLock lock(m_mutex);
// open a window and run an event loop in a separate thread. // open a window and run an event loop in a separate thread.
// this has to happen in a separate thread because if we // this has to happen in a separate thread because if we
@ -92,11 +92,9 @@ ArchTaskBarWindows::init()
// wait for child thread // wait for child thread
while (!m_ready) { while (!m_ready) {
ARCH->waitCondVar(m_condVar, m_mutex, -1.0); ARCH->waitCondVar(m_condVar, lock, -1.0);
} }
// ready
ARCH->unlockMutex(m_mutex);
} }
void void

View File

@ -52,7 +52,7 @@ SimpleEventQueueBuffer::waitForEvent(double timeout)
return; return;
} }
} }
ARCH->waitCondVar(m_queueReadyCond, m_queueMutex, timeLeft); ARCH->waitCondVar(m_queueReadyCond, lock, timeLeft);
} }
} }

View File

@ -149,7 +149,7 @@ void IpcLogOutputter::buffer_thread()
while (isRunning()) { while (isRunning()) {
if (m_buffer.empty() || !m_ipcServer.hasClients(m_clientType)) { if (m_buffer.empty() || !m_ipcServer.hasClients(m_clientType)) {
ArchMutexLock lock(m_notifyMutex); ArchMutexLock lock(m_notifyMutex);
ARCH->waitCondVar(m_notifyCond, m_notifyMutex, -1); ARCH->waitCondVar(m_notifyCond, lock, -1);
} }
sendBuffer(); sendBuffer();

View File

@ -81,7 +81,8 @@ CondVarBase::wait(Stopwatch& timer, double timeout) const
bool bool
CondVarBase::wait(double timeout) const CondVarBase::wait(double timeout) const
{ {
return ARCH->waitCondVar(m_cond, m_mutex->m_mutex, timeout); ArchMutexLock lock{m_mutex->m_mutex, std::adopt_lock};
return ARCH->waitCondVar(m_cond, lock, timeout);
} }
Mutex* Mutex*

View File

@ -54,7 +54,8 @@ public:
} }
void waitForSend() { void waitForSend() {
ARCH->waitCondVar(m_sendCond, m_sendMutex, 5); ArchMutexLock lock{m_sendMutex, std::adopt_lock};
ARCH->waitCondVar(m_sendCond, lock, 5);
} }
private: private: