fix: Improve Windows daemon stop speed by using non-blocking pipes and shorter sleep times

This commit is contained in:
Nick Bolton
2025-02-24 16:36:13 +00:00
parent 890fd61e6e
commit 19c41e2ac5
2 changed files with 16 additions and 10 deletions

View File

@ -9,9 +9,7 @@
#include "arch/Arch.h"
#include "arch/win32/ArchMiscWindows.h"
#include "arch/win32/XArchWindows.h"
#include "common/stdvector.h"
#include <sstream>
#include "base/Log.h"
//
// ArchDaemonWindows
@ -165,9 +163,10 @@ void ArchDaemonWindows::uninstallDaemon(const char *name)
CloseServiceHandle(service);
CloseServiceHandle(mgr);
// give windows a chance to remove the service before
// we check if it still exists.
ARCH->sleep(1);
// give windows a chance to remove the service before we check if it still exists.
// 100ms should be plenty of time.
LOG_DEBUG("waiting for service to be removed");
ARCH->sleep(0.1);
// handle failure. ignore error if service isn't installed anymore.
if (!okay && isDaemonInstalled(name)) {

View File

@ -188,6 +188,13 @@ void MSWindowsWatchdog::mainLoop(void *)
throw XArch(new XArchEvalWindows());
}
// Set the pipe to non-blocking mode, which allows us to stop the output reader thread immediately
// in order to speed up the shutdown process when the Windows service needs to stop.
DWORD mode = PIPE_NOWAIT;
if (!SetNamedPipeHandleState(m_outputReadPipe, &mode, nullptr, nullptr)) {
throw XArch(new XArchEvalWindows());
}
while (m_monitoring) {
try {
@ -247,7 +254,8 @@ void MSWindowsWatchdog::mainLoop(void *)
LOG((CLOG_ERR "could not create SendSAS event"));
}
ARCH->sleep(1);
// Sleep for only 100ms rather than 1 second so that the service can shut down faster.
ARCH->sleep(0.1);
} catch (std::exception &e) {
LOG((CLOG_CRIT "failed to launch, error: %s", e.what()));
@ -401,10 +409,9 @@ void MSWindowsWatchdog::outputLoop(void *)
DWORD bytesRead;
BOOL success = ReadFile(m_outputReadPipe, buffer, kOutputBufferSize, &bytesRead, NULL);
// assume the process has gone away? slow down
// the reads until another one turns up.
if (!success || bytesRead == 0) {
ARCH->sleep(1);
// Sleep for only 100ms rather than 1 second so that the service can shut down faster.
ARCH->sleep(0.1);
} else {
buffer[bytesRead] = '\0';