X-Git-Url: http://git.iain.cx/?a=blobdiff_plain;f=service.cpp;h=d66b91606f5b5be28627b8cb9da954118e39d33f;hb=b3b29f0b27046a282e688c494def532252ad21c3;hp=c9f47000515e4a4a65ce63b2e2ce47a9bca81600;hpb=71764fe41e37f36bcbc89ac62f664aeda4240790;p=nssm.git diff --git a/service.cpp b/service.cpp index c9f4700..d66b916 100644 --- a/service.cpp +++ b/service.cpp @@ -83,10 +83,11 @@ static inline int service_control_response(unsigned long control, unsigned long return 0; } -static inline int await_service_control_response(unsigned long control, SC_HANDLE service_handle, SERVICE_STATUS *service_status, unsigned long initial_status) { +static inline int await_service_control_response(unsigned long control, SC_HANDLE service_handle, SERVICE_STATUS *service_status, unsigned long initial_status, unsigned long cutoff) { int tries = 0; unsigned long checkpoint = 0; unsigned long waithint = 0; + unsigned long waited = 0; while (QueryServiceStatus(service_handle, service_status)) { int response = service_control_response(control, service_status->dwCurrentState); /* Alas we can't WaitForSingleObject() on an SC_HANDLE. */ @@ -96,13 +97,22 @@ static inline int await_service_control_response(unsigned long control, SC_HANDL checkpoint = service_status->dwCheckPoint; waithint = service_status->dwWaitHint; if (++tries > 10) tries = 10; - Sleep(50 * tries); + unsigned long wait = 50 * tries; + if (cutoff) { + if (waited > cutoff) return response; + waited += wait; + } + Sleep(wait); } else return response; } return -1; } +static inline int await_service_control_response(unsigned long control, SC_HANDLE service_handle, SERVICE_STATUS *service_status, unsigned long initial_status) { + return await_service_control_response(control, service_handle, service_status, initial_status, 0); +} + static inline void wait_for_hooks(nssm_service_t *service, bool notify) { SERVICE_STATUS_HANDLE status_handle; SERVICE_STATUS *status; @@ -1407,7 +1417,16 @@ int control_service(unsigned long control, int argc, TCHAR **argv) { } if (ret) { - int response = await_service_control_response(control, service_handle, &service_status, initial_status); + unsigned long cutoff = 0; + + /* If we manage the service, respect the throttle time. */ + HKEY key = open_registry(service_name, 0, KEY_READ, false); + if (key) { + if (get_number(key, NSSM_REG_THROTTLE, &cutoff, false) != 1) cutoff = NSSM_RESET_THROTTLE_RESTART; + RegCloseKey(key); + } + + int response = await_service_control_response(control, service_handle, &service_status, initial_status, cutoff); CloseServiceHandle(service_handle); if (response) { @@ -2091,7 +2110,6 @@ void CALLBACK end_service(void *arg, unsigned char why) { log_event(EVENTLOG_INFORMATION_TYPE, NSSM_EVENT_EXIT_UNCLEAN, service->name, code, exit_action_strings[action], 0); stop_service(service, exitcode, false, default_action); wait_for_hooks(service, false); - free_imports(); nssm_exit(exitcode); } }