From 90b896a26a68724149b544d8063cd6fde77f5ab5 Mon Sep 17 00:00:00 2001 From: Iain Patterson Date: Mon, 28 Feb 2011 17:35:20 +0000 Subject: [PATCH] Timer safety. Check we actually have a waitable timer before trying to use it. Use the correct compiler food to ensure that 256000 milliseconds is converted to a LARGE_INTEGER correctly. --- messages.mc | 9 +++++++++ service.cpp | 15 +++++++++++---- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/messages.mc b/messages.mc index 41586ba..07ed432 100644 --- a/messages.mc +++ b/messages.mc @@ -281,3 +281,12 @@ Language = English The registry value %2, used to specify the minimum number of milliseconds which must elapse before service %1 is considered to have started successfully, was not of type REG_DWORD. The default time of %3 milliseconds will be used. . +MessageId = +1 +SymbolicName = NSSM_EVENT_CREATEWAITABLETIMER_FAILED +Severity = Warning +Language = English +Failed to create waitable timer for service %1: +%2 +Throttled restarts will not be interruptible. +. + diff --git a/service.cpp b/service.cpp index 4f7ff03..60a8db0 100644 --- a/service.cpp +++ b/service.cpp @@ -210,6 +210,9 @@ void WINAPI service_main(unsigned long argc, char **argv) { /* Used for signalling a resume if the service pauses when throttled. */ throttle_timer = CreateWaitableTimer(0, 1, 0); + if (! throttle_timer) { + log_event(EVENTLOG_WARNING_TYPE, NSSM_EVENT_CREATEWAITABLETIMER_FAILED, service_name, error_string(GetLastError()), 0); + } monitor_service(); } @@ -259,6 +262,7 @@ unsigned long WINAPI service_control_handler(unsigned long control, unsigned lon return NO_ERROR; case SERVICE_CONTROL_CONTINUE: + if (! throttle_timer) return ERROR_CALL_NOT_IMPLEMENTED; throttle = 0; ZeroMemory(&throttle_duetime, sizeof(throttle_duetime)); SetWaitableTimer(throttle_timer, &throttle_duetime, 0, 0, 0, 0); @@ -455,12 +459,15 @@ void throttle_restart() { _snprintf(milliseconds, sizeof(milliseconds), "%d", ms); log_event(EVENTLOG_WARNING_TYPE, NSSM_EVENT_THROTTLED, service_name, threshold, milliseconds, 0); - ZeroMemory(&throttle_duetime, sizeof(throttle_duetime)); - throttle_duetime.QuadPart = 0 - (ms * 10000); - SetWaitableTimer(throttle_timer, &throttle_duetime, 0, 0, 0, 0); + if (throttle_timer) { + ZeroMemory(&throttle_duetime, sizeof(throttle_duetime)); + throttle_duetime.QuadPart = 0 - (ms * 10000LL); + SetWaitableTimer(throttle_timer, &throttle_duetime, 0, 0, 0, 0); + } service_status.dwCurrentState = SERVICE_PAUSED; SetServiceStatus(service_handle, &service_status); - WaitForSingleObject(throttle_timer, INFINITE); + if (throttle_timer) WaitForSingleObject(throttle_timer, INFINITE); + else Sleep(ms); } -- 2.20.1