X-Git-Url: http://git.iain.cx/?a=blobdiff_plain;f=service.cpp;h=7e13da783298ccec5d9a6436ea370782268feed2;hb=85fe241fc72957ceb77ed2c5587189a23246d87f;hp=52937cffb399d19f82dd436b5ec117bf91c85130;hpb=8bb8d0f780b0837639e95241a58677169fd15b4e;p=nssm.git diff --git a/service.cpp b/service.cpp index 52937cf..7e13da7 100644 --- a/service.cpp +++ b/service.cpp @@ -1394,6 +1394,7 @@ void WINAPI service_main(unsigned long argc, TCHAR **argv) { if (services) { service->handle = open_service(services, service->name, SERVICE_CHANGE_CONFIG, 0, 0); set_service_recovery(service); + CloseServiceHandle(services); } } @@ -1687,16 +1688,7 @@ int start_service(nssm_service_t *service) { but be mindful of the fact that we are blocking the service control manager so abandon the wait before too much time has elapsed. */ - unsigned long delay = service->throttle_delay; - if (delay > NSSM_SERVICE_STATUS_DEADLINE) { - TCHAR delay_milliseconds[16]; - _sntprintf_s(delay_milliseconds, _countof(delay_milliseconds), _TRUNCATE, _T("%lu"), delay); - TCHAR deadline_milliseconds[16]; - _sntprintf_s(deadline_milliseconds, _countof(deadline_milliseconds), _TRUNCATE, _T("%lu"), NSSM_SERVICE_STATUS_DEADLINE); - log_event(EVENTLOG_WARNING_TYPE, NSSM_EVENT_STARTUP_DELAY_TOO_LONG, service->name, delay_milliseconds, NSSM, deadline_milliseconds, 0); - delay = NSSM_SERVICE_STATUS_DEADLINE; - } - unsigned long deadline = WaitForSingleObject(service->process_handle, delay); + await_startup(service); /* Signal successful start */ service->status.dwCurrentState = SERVICE_RUNNING; @@ -1985,3 +1977,38 @@ awaited: return ret; } + +int await_startup(nssm_service_t *service) { + unsigned long interval; + unsigned long waithint; + unsigned long waited; + + waithint = service->status.dwWaitHint; + waited = 0; + while (waited < service->throttle_delay) { + interval = service->throttle_delay - waited; + if (interval > NSSM_SERVICE_STATUS_DEADLINE) interval = NSSM_SERVICE_STATUS_DEADLINE; + + service->status.dwCurrentState = SERVICE_START_PENDING; + service->status.dwWaitHint += interval; + service->status.dwCheckPoint++; + SetServiceStatus(service->status_handle, &service->status); + + switch (WaitForSingleObject(service->process_handle, interval)) { + case WAIT_OBJECT_0: + return 1; + + case WAIT_TIMEOUT: + break; + + default: + return -1; + } + + waited += interval; + } + + service->throttle = 0; + + return 0; +}