case SERVICE_CONTROL_STOP:\r
case SERVICE_CONTROL_SHUTDOWN:\r
switch (status) {\r
+ case SERVICE_RUNNING:\r
case SERVICE_STOP_PENDING:\r
return 1;\r
\r
}\r
\r
case SERVICE_CONTROL_INTERROGATE:\r
+ case NSSM_SERVICE_CONTROL_ROTATE:\r
return 0;\r
}\r
\r
\r
static inline int await_service_control_response(unsigned long control, SC_HANDLE service_handle, SERVICE_STATUS *service_status, unsigned long initial_status) {\r
int tries = 0;\r
+ unsigned long checkpoint = 0;\r
+ unsigned long waithint = 0;\r
while (QueryServiceStatus(service_handle, service_status)) {\r
int response = service_control_response(control, service_status->dwCurrentState);\r
/* Alas we can't WaitForSingleObject() on an SC_HANDLE. */\r
if (! response) return response;\r
if (response > 0 || service_status->dwCurrentState == initial_status) {\r
- if (++tries > 10) return response;\r
+ if (service_status->dwCheckPoint != checkpoint || service_status->dwWaitHint != waithint) tries = 0;\r
+ checkpoint = service_status->dwCheckPoint;\r
+ waithint = service_status->dwWaitHint;\r
+ if (++tries > 10) tries = 10;\r
Sleep(50 * tries);\r
}\r
else return response;\r
/* Initialise status */\r
ZeroMemory(&service->status, sizeof(service->status));\r
service->status.dwServiceType = SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS;\r
- service->status.dwControlsAccepted = SERVICE_ACCEPT_POWEREVENT | SERVICE_ACCEPT_SHUTDOWN | SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_PAUSE_CONTINUE;\r
+ service->status.dwControlsAccepted = 0;\r
service->status.dwWin32ExitCode = NO_ERROR;\r
service->status.dwServiceSpecificExitCode = 0;\r
service->status.dwCheckPoint = 0;\r
so abandon the wait before too much time has elapsed.\r
*/\r
service->status.dwCurrentState = SERVICE_START_PENDING;\r
+ service->status.dwControlsAccepted = SERVICE_ACCEPT_POWEREVENT | SERVICE_ACCEPT_SHUTDOWN | SERVICE_ACCEPT_STOP;\r
if (await_single_handle(service->status_handle, &service->status, service->process_handle, service->name, _T("start_service"), service->throttle_delay) == 1) service->throttle = 0;\r
\r
/* Signal successful start */\r
service->status.dwCurrentState = SERVICE_RUNNING;\r
+ service->status.dwControlsAccepted &= ~SERVICE_ACCEPT_PAUSE_CONTINUE;\r
SetServiceStatus(service->status_handle, &service->status);\r
\r
/* Continue waiting for a clean startup. */\r
if (graceful) {\r
service->status.dwCurrentState = SERVICE_STOP_PENDING;\r
service->status.dwWaitHint = NSSM_WAITHINT_MARGIN;\r
- SetServiceStatus(service->status_handle, &service->status);\r
}\r
+ service->status.dwControlsAccepted = 0;\r
+ SetServiceStatus(service->status_handle, &service->status);\r
\r
/* Nothing to do if service isn't running */\r
if (service->pid) {\r
}\r
\r
service->status.dwCurrentState = SERVICE_PAUSED;\r
+ service->status.dwControlsAccepted |= SERVICE_ACCEPT_PAUSE_CONTINUE;\r
SetServiceStatus(service->status_handle, &service->status);\r
\r
if (use_critical_section) {\r