Mercurial > hg > nginx
view src/os/win32/ngx_service.c @ 3537:d2848db4d98e
fix IPv6 and Unix domain sockets inheritance while online upgrade
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Mon, 31 May 2010 14:49:11 +0000 |
parents | 42d11f017717 |
children | d620f497c50f |
line wrap: on
line source
/* * Copyright (C) Igor Sysoev */ #define NGX_SERVICE_CONTROL_SHUTDOWN 128 #define NGX_SERVICE_CONTROL_REOPEN 129 SERVICE_TABLE_ENTRY st[] = { { "nginx", service_main }, { NULL, NULL } }; ngx_int_t ngx_service(ngx_log_t *log) { /* primary thread */ /* StartServiceCtrlDispatcher() shouxpdl be called within 30 seconds */ if (StartServiceCtrlDispatcher(st) == 0) { ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "StartServiceCtrlDispatcher() failed"); return NGX_ERROR; } return NGX_OK; } void service_main(u_int argc, char **argv) { SERVICE_STATUS status; SERVICE_STATUS_HANDLE service; /* thread spawned by SCM */ service = RegisterServiceCtrlHandlerEx("nginx", service_handler, ctx); if (service == INVALID_HANDLE_VALUE) { ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "RegisterServiceCtrlHandlerEx() failed"); return; } status.dwServiceType = SERVICE_WIN32_OWN_PROCESS; status.dwCurrentState = SERVICE_START_PENDING; status.dwControlsAccepted = SERVICE_ACCEPT_STOP |SERVICE_ACCEPT_PARAMCHANGE; status.dwWin32ExitCode = NO_ERROR; status.dwServiceSpecificExitCode = 0; status.dwCheckPoint = 1; status.dwWaitHint = 2000; /* SetServiceStatus() should be called within 80 seconds */ if (SetServiceStatus(service, &status) == 0) { ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "SetServiceStatus() failed"); return; } /* init */ status.dwCurrentState = SERVICE_RUNNING; status.dwCheckPoint = 0; status.dwWaitHint = 0; if (SetServiceStatus(service, &status) == 0) { ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "SetServiceStatus() failed"); return; } /* call master or worker loop */ /* * master should use event notification and look status * single should use iocp to get notifications from service handler */ } u_int service_handler(u_int control, u_int type, void *data, void *ctx) { /* primary thread */ switch(control) { case SERVICE_CONTROL_INTERROGATE: status = NGX_IOCP_INTERROGATE; break; case SERVICE_CONTROL_STOP: status = NGX_IOCP_STOP; break; case SERVICE_CONTROL_PARAMCHANGE: status = NGX_IOCP_RECONFIGURE; break; case NGX_SERVICE_CONTROL_SHUTDOWN: status = NGX_IOCP_REOPEN; break; case NGX_SERVICE_CONTROL_REOPEN: status = NGX_IOCP_REOPEN; break; default: return ERROR_CALL_NOT_IMPLEMENTED; } if (ngx_single) { if (PostQueuedCompletionStatus(iocp, ... status, ...) == 0) { err = ngx_errno; ngx_log_error(NGX_LOG_ALERT, log, err, "PostQueuedCompletionStatus() failed"); return err; } } else { Event } return NO_ERROR; }