Browse Source

Fix pre-Vista compatibility.

SleepConditionVariableCS() isn't available on Windows versions
prior to Vista.  Use a waitable timer instead.
Iain Patterson 11 years ago
parent
commit
3405b53f65
1 changed files with 9 additions and 8 deletions
  1. 9 8
      service.cpp

+ 9 - 8
service.cpp

@@ -11,8 +11,8 @@ char flags[CMD_LENGTH];
 char dir[MAX_PATH];
 bool stopping;
 unsigned long throttle_delay;
-CRITICAL_SECTION throttle_section;
-CONDITION_VARIABLE throttle_condition;
+HANDLE throttle_timer;
+LARGE_INTEGER throttle_duetime;
 
 static enum { NSSM_EXIT_RESTART, NSSM_EXIT_IGNORE, NSSM_EXIT_REALLY, NSSM_EXIT_UNCLEAN } exit_actions;
 static const char *exit_action_strings[] = { "Restart", "Ignore", "Exit", "Suicide", 0 };
@@ -209,7 +209,7 @@ void WINAPI service_main(unsigned long argc, char **argv) {
   set_service_recovery(service_name);
 
   /* Used for signalling a resume if the service pauses when throttled. */
-  InitializeCriticalSection(&throttle_section);
+  throttle_timer = CreateWaitableTimer(0, 1, 0);
 
   monitor_service();
 }
@@ -260,7 +260,8 @@ unsigned long WINAPI service_control_handler(unsigned long control, unsigned lon
 
     case SERVICE_CONTROL_CONTINUE:
       throttle = 0;
-      WakeConditionVariable(&throttle_condition);
+      ZeroMemory(&throttle_duetime, sizeof(throttle_duetime));
+      SetWaitableTimer(throttle_timer, &throttle_duetime, 0, 0, 0, 0);
       service_status.dwCurrentState = SERVICE_CONTINUE_PENDING;
       service_status.dwWaitHint = throttle_milliseconds() + NSSM_WAITHINT_MARGIN;
       log_event(EVENTLOG_INFORMATION_TYPE, NSSM_EVENT_RESET_THROTTLE, service_name, 0);
@@ -454,12 +455,12 @@ void throttle_restart() {
   _snprintf(milliseconds, sizeof(milliseconds), "%d", ms);
   log_event(EVENTLOG_WARNING_TYPE, NSSM_EVENT_THROTTLED, service_name, threshold, milliseconds, 0);
 
-  EnterCriticalSection(&throttle_section);
+  ZeroMemory(&throttle_duetime, sizeof(throttle_duetime));
+  throttle_duetime.QuadPart = 0 - (ms * 10000);
+  SetWaitableTimer(throttle_timer, &throttle_duetime, 0, 0, 0, 0);
 
   service_status.dwCurrentState = SERVICE_PAUSED;
   SetServiceStatus(service_handle, &service_status);
 
-  SleepConditionVariableCS(&throttle_condition, &throttle_section, ms);
-
-  LeaveCriticalSection(&throttle_section);
+  WaitForSingleObject(throttle_timer, INFINITE);
 }