- if (throttle_timer) {\r
- ZeroMemory(&throttle_duetime, sizeof(throttle_duetime));\r
- throttle_duetime.QuadPart = 0 - (ms * 10000LL);\r
- SetWaitableTimer(throttle_timer, &throttle_duetime, 0, 0, 0, 0);\r
+/*\r
+ When responding to a stop (or any other) request we need to set dwWaitHint to\r
+ the number of milliseconds we expect the operation to take, and optionally\r
+ increase dwCheckPoint. If dwWaitHint milliseconds elapses without the\r
+ operation completing or dwCheckPoint increasing, the system will consider the\r
+ service to be hung.\r
+\r
+ However the system will consider the service to be hung after 30000\r
+ milliseconds regardless of the value of dwWaitHint if dwCheckPoint has not\r
+ changed. Therefore if we want to wait longer than that we must periodically\r
+ increase dwCheckPoint.\r
+\r
+ Furthermore, it will consider the service to be hung after 60000 milliseconds\r
+ regardless of the value of dwCheckPoint unless dwWaitHint is increased every\r
+ time dwCheckPoint is also increased.\r
+\r
+ Our strategy then is to retrieve the initial dwWaitHint and wait for\r
+ NSSM_SERVICE_STATUS_DEADLINE milliseconds. If the process is still running\r
+ and we haven't finished waiting we increment dwCheckPoint and add whichever is\r
+ smaller of NSSM_SERVICE_STATUS_DEADLINE or the remaining timeout to\r
+ dwWaitHint.\r
+\r
+ Only doing both these things will prevent the system from killing the service.\r
+\r
+ Returns: 1 if the wait timed out.\r
+ 0 if the wait completed.\r
+ -1 on error.\r
+*/\r
+int await_shutdown(nssm_service_t *service, char *function_name, unsigned long timeout) {\r
+ unsigned long interval;\r
+ unsigned long waithint;\r
+ unsigned long ret;\r
+ unsigned long waited;\r
+ char interval_milliseconds[16];\r
+ char timeout_milliseconds[16];\r
+ char waited_milliseconds[16];\r
+ char *function = function_name;\r
+\r
+ /* Add brackets to function name. */\r
+ size_t funclen = strlen(function_name) + 3;\r
+ char *func = (char *) HeapAlloc(GetProcessHeap(), 0, funclen);\r
+ if (func) {\r
+ if (_snprintf_s(func, funclen, _TRUNCATE, "%s()", function_name) > -1) function = func;\r