lib/arch/win32: Use standard mutex primitives in daemon code
This commit is contained in:
parent
c59074835f
commit
959306fb1b
|
@ -320,7 +320,6 @@ int
|
||||||
ArchDaemonWindows::doRunDaemon(RunFunc run)
|
ArchDaemonWindows::doRunDaemon(RunFunc run)
|
||||||
{
|
{
|
||||||
// should only be called from DaemonFunc
|
// should only be called from DaemonFunc
|
||||||
assert(m_serviceMutex != NULL);
|
|
||||||
assert(run != NULL);
|
assert(run != NULL);
|
||||||
|
|
||||||
// create message queue for this thread
|
// create message queue for this thread
|
||||||
|
@ -328,32 +327,30 @@ ArchDaemonWindows::doRunDaemon(RunFunc run)
|
||||||
PeekMessage(&dummy, NULL, 0, 0, PM_NOREMOVE);
|
PeekMessage(&dummy, NULL, 0, 0, PM_NOREMOVE);
|
||||||
|
|
||||||
int result = 0;
|
int result = 0;
|
||||||
ARCH->lockMutex(m_serviceMutex);
|
std::unique_lock<std::mutex> lock(service_mutex_);
|
||||||
m_daemonThreadID = GetCurrentThreadId();
|
m_daemonThreadID = GetCurrentThreadId();
|
||||||
while (m_serviceState != SERVICE_STOPPED) {
|
while (m_serviceState != SERVICE_STOPPED) {
|
||||||
// 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) {
|
||||||
ArchMutexLock lock{m_serviceMutex, std::adopt_lock};
|
ARCH->wait_cond_var(service_cv_, lock, -1.0);
|
||||||
ARCH->waitCondVar(m_serviceCondVar, lock, -1.0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// run unless told to stop
|
// run unless told to stop
|
||||||
if (m_serviceState != SERVICE_STOP_PENDING) {
|
if (m_serviceState != SERVICE_STOP_PENDING) {
|
||||||
ARCH->unlockMutex(m_serviceMutex);
|
lock.unlock();
|
||||||
try {
|
try {
|
||||||
result = run();
|
result = run();
|
||||||
}
|
}
|
||||||
catch (...) {
|
catch (...) {
|
||||||
ARCH->lockMutex(m_serviceMutex);
|
lock.lock();
|
||||||
setStatusError(0);
|
setStatusError(0);
|
||||||
m_serviceState = SERVICE_STOPPED;
|
m_serviceState = SERVICE_STOPPED;
|
||||||
setStatus(m_serviceState);
|
setStatus(m_serviceState);
|
||||||
ARCH->broadcastCondVar(m_serviceCondVar);
|
service_cv_.notify_all();
|
||||||
ARCH->unlockMutex(m_serviceMutex);
|
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
ARCH->lockMutex(m_serviceMutex);
|
lock.lock();
|
||||||
}
|
}
|
||||||
|
|
||||||
// notify of new state
|
// notify of new state
|
||||||
|
@ -364,22 +361,20 @@ ArchDaemonWindows::doRunDaemon(RunFunc run)
|
||||||
m_serviceState = SERVICE_STOPPED;
|
m_serviceState = SERVICE_STOPPED;
|
||||||
}
|
}
|
||||||
setStatus(m_serviceState);
|
setStatus(m_serviceState);
|
||||||
ARCH->broadcastCondVar(m_serviceCondVar);
|
service_cv_.notify_all();
|
||||||
}
|
}
|
||||||
ARCH->unlockMutex(m_serviceMutex);
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ArchDaemonWindows::doDaemonRunning(bool running)
|
ArchDaemonWindows::doDaemonRunning(bool running)
|
||||||
{
|
{
|
||||||
ARCH->lockMutex(m_serviceMutex);
|
std::lock_guard<std::mutex> lock(service_mutex_);
|
||||||
if (running) {
|
if (running) {
|
||||||
m_serviceState = SERVICE_RUNNING;
|
m_serviceState = SERVICE_RUNNING;
|
||||||
setStatus(m_serviceState);
|
setStatus(m_serviceState);
|
||||||
ARCH->broadcastCondVar(m_serviceCondVar);
|
service_cv_.notify_all();
|
||||||
}
|
}
|
||||||
ARCH->unlockMutex(m_serviceMutex);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
UINT
|
UINT
|
||||||
|
@ -439,18 +434,12 @@ ArchDaemonWindows::serviceMain(DWORD argc, LPTSTR* argvIn)
|
||||||
typedef std::vector<std::string> Arguments;
|
typedef std::vector<std::string> Arguments;
|
||||||
const char** argv = const_cast<const char**>(argvIn);
|
const char** argv = const_cast<const char**>(argvIn);
|
||||||
|
|
||||||
// create synchronization objects
|
|
||||||
m_serviceMutex = ARCH->newMutex();
|
|
||||||
m_serviceCondVar = ARCH->newCondVar();
|
|
||||||
|
|
||||||
// register our service handler function
|
// register our service handler function
|
||||||
m_statusHandle = RegisterServiceCtrlHandler(argv[0],
|
m_statusHandle = RegisterServiceCtrlHandler(argv[0],
|
||||||
&ArchDaemonWindows::serviceHandlerEntry);
|
&ArchDaemonWindows::serviceHandlerEntry);
|
||||||
if (m_statusHandle == 0) {
|
if (m_statusHandle == 0) {
|
||||||
// cannot start as service
|
// cannot start as service
|
||||||
m_daemonResult = -1;
|
m_daemonResult = -1;
|
||||||
ARCH->closeCondVar(m_serviceCondVar);
|
|
||||||
ARCH->closeMutex(m_serviceMutex);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -544,10 +533,6 @@ ArchDaemonWindows::serviceMain(DWORD argc, LPTSTR* argvIn)
|
||||||
m_daemonResult = -1;
|
m_daemonResult = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// clean up
|
|
||||||
ARCH->closeCondVar(m_serviceCondVar);
|
|
||||||
ARCH->closeMutex(m_serviceMutex);
|
|
||||||
|
|
||||||
// we're going to exit now, so set status to stopped
|
// we're going to exit now, so set status to stopped
|
||||||
m_serviceState = SERVICE_STOPPED;
|
m_serviceState = SERVICE_STOPPED;
|
||||||
setStatus(m_serviceState, 0, 10000);
|
setStatus(m_serviceState, 0, 10000);
|
||||||
|
@ -562,17 +547,13 @@ ArchDaemonWindows::serviceMainEntry(DWORD argc, LPTSTR* argv)
|
||||||
void
|
void
|
||||||
ArchDaemonWindows::serviceHandler(DWORD ctrl)
|
ArchDaemonWindows::serviceHandler(DWORD ctrl)
|
||||||
{
|
{
|
||||||
assert(m_serviceMutex != NULL);
|
std::unique_lock<std::mutex> lock(service_mutex_);
|
||||||
assert(m_serviceCondVar != NULL);
|
|
||||||
|
|
||||||
ARCH->lockMutex(m_serviceMutex);
|
|
||||||
|
|
||||||
// ignore request if service is already stopped
|
// ignore request if service is already stopped
|
||||||
if (s_daemon == NULL || m_serviceState == SERVICE_STOPPED) {
|
if (s_daemon == NULL || m_serviceState == SERVICE_STOPPED) {
|
||||||
if (s_daemon != NULL) {
|
if (s_daemon != NULL) {
|
||||||
setStatus(m_serviceState);
|
setStatus(m_serviceState);
|
||||||
}
|
}
|
||||||
ARCH->unlockMutex(m_serviceMutex);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -582,8 +563,7 @@ 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)) {
|
||||||
ArchMutexLock lock{m_serviceMutex, std::adopt_lock};
|
ARCH->wait_cond_var(service_cv_, lock, -1.0);
|
||||||
ARCH->waitCondVar(m_serviceCondVar, lock, -1.0);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -591,7 +571,7 @@ ArchDaemonWindows::serviceHandler(DWORD ctrl)
|
||||||
// FIXME -- maybe should flush quit messages from queue
|
// FIXME -- maybe should flush quit messages from queue
|
||||||
m_serviceState = SERVICE_CONTINUE_PENDING;
|
m_serviceState = SERVICE_CONTINUE_PENDING;
|
||||||
setStatus(m_serviceState, 0, 5000);
|
setStatus(m_serviceState, 0, 5000);
|
||||||
ARCH->broadcastCondVar(m_serviceCondVar);
|
service_cv_.notify_all();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SERVICE_CONTROL_STOP:
|
case SERVICE_CONTROL_STOP:
|
||||||
|
@ -599,10 +579,9 @@ ArchDaemonWindows::serviceHandler(DWORD ctrl)
|
||||||
m_serviceState = SERVICE_STOP_PENDING;
|
m_serviceState = SERVICE_STOP_PENDING;
|
||||||
setStatus(m_serviceState, 0, 5000);
|
setStatus(m_serviceState, 0, 5000);
|
||||||
PostThreadMessage(m_daemonThreadID, m_quitMessage, 0, 0);
|
PostThreadMessage(m_daemonThreadID, m_quitMessage, 0, 0);
|
||||||
ARCH->broadcastCondVar(m_serviceCondVar);
|
service_cv_.notify_all();
|
||||||
while (isRunState(m_serviceState)) {
|
while (isRunState(m_serviceState)) {
|
||||||
ArchMutexLock lock{m_serviceMutex, std::adopt_lock};
|
ARCH->wait_cond_var(service_cv_, lock, -1.0);
|
||||||
ARCH->waitCondVar(m_serviceCondVar, lock, -1.0);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -614,8 +593,6 @@ ArchDaemonWindows::serviceHandler(DWORD ctrl)
|
||||||
setStatus(m_serviceState);
|
setStatus(m_serviceState);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
ARCH->unlockMutex(m_serviceMutex);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void WINAPI
|
void WINAPI
|
||||||
|
|
|
@ -26,6 +26,8 @@
|
||||||
#include <Windows.h>
|
#include <Windows.h>
|
||||||
#include <tchar.h>
|
#include <tchar.h>
|
||||||
|
|
||||||
|
#include <condition_variable>
|
||||||
|
|
||||||
#define ARCH_DAEMON ArchDaemonWindows
|
#define ARCH_DAEMON ArchDaemonWindows
|
||||||
|
|
||||||
//! Win32 implementation of IArchDaemon
|
//! Win32 implementation of IArchDaemon
|
||||||
|
@ -122,8 +124,8 @@ private:
|
||||||
private:
|
private:
|
||||||
static ArchDaemonWindows* s_daemon;
|
static ArchDaemonWindows* s_daemon;
|
||||||
|
|
||||||
ArchMutex m_serviceMutex;
|
std::mutex service_mutex_;
|
||||||
ArchCond m_serviceCondVar;
|
std::condition_variable service_cv_;
|
||||||
DWORD m_serviceState;
|
DWORD m_serviceState;
|
||||||
bool m_serviceHandlerWaiting;
|
bool m_serviceHandlerWaiting;
|
||||||
bool m_serviceRunning;
|
bool m_serviceRunning;
|
||||||
|
|
Loading…
Reference in New Issue