src/os/win32/ngx_service.c - nginx source code

Global variables defined

Functions defined

Macros defined

Source code


  1. /*
  2. * Copyright (C) Igor Sysoev
  3. * Copyright (C) Nginx, Inc.
  4. */



  5. #define NGX_SERVICE_CONTROL_SHUTDOWN   128
  6. #define NGX_SERVICE_CONTROL_REOPEN     129


  7. SERVICE_TABLE_ENTRY st[] = {
  8.     { "nginx", service_main },
  9.     { NULL, NULL }
  10. };


  11. ngx_int_t
  12. ngx_service(ngx_log_t *log)
  13. {
  14.     /* primary thread */

  15.     /* StartServiceCtrlDispatcher() should be called within 30 seconds */

  16.     if (StartServiceCtrlDispatcher(st) == 0) {
  17.         ngx_log_error(NGX_LOG_EMERG, log, ngx_errno,
  18.                       "StartServiceCtrlDispatcher() failed");
  19.         return NGX_ERROR;
  20.     }

  21.     return NGX_OK;
  22. }


  23. void
  24. service_main(u_int argc, char **argv)
  25. {
  26.     SERVICE_STATUS         status;
  27.     SERVICE_STATUS_HANDLE  service;

  28.     /* thread spawned by SCM */

  29.     service = RegisterServiceCtrlHandlerEx("nginx", service_handler, ctx);
  30.     if (service == INVALID_HANDLE_VALUE) {
  31.         ngx_log_error(NGX_LOG_EMERG, log, ngx_errno,
  32.                       "RegisterServiceCtrlHandlerEx() failed");
  33.         return;
  34.     }

  35.     status.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
  36.     status.dwCurrentState = SERVICE_START_PENDING;
  37.     status.dwControlsAccepted = SERVICE_ACCEPT_STOP
  38.                                 |SERVICE_ACCEPT_PARAMCHANGE;
  39.     status.dwWin32ExitCode = NO_ERROR;
  40.     status.dwServiceSpecificExitCode = 0;
  41.     status.dwCheckPoint = 1;
  42.     status.dwWaitHint = 2000;

  43.     /* SetServiceStatus() should be called within 80 seconds */

  44.     if (SetServiceStatus(service, &status) == 0) {
  45.         ngx_log_error(NGX_LOG_EMERG, log, ngx_errno,
  46.                       "SetServiceStatus() failed");
  47.         return;
  48.     }

  49.     /* init */

  50.     status.dwCurrentState = SERVICE_RUNNING;
  51.     status.dwCheckPoint = 0;
  52.     status.dwWaitHint = 0;

  53.     if (SetServiceStatus(service, &status) == 0) {
  54.         ngx_log_error(NGX_LOG_EMERG, log, ngx_errno,
  55.                       "SetServiceStatus() failed");
  56.         return;
  57.     }

  58.     /* call master or worker loop */

  59.     /*
  60.      * master should use event notification and look status
  61.      * single should use iocp to get notifications from service handler
  62.      */

  63. }


  64. u_int
  65. service_handler(u_int control, u_int type, void *data, void *ctx)
  66. {
  67.     /* primary thread */

  68.     switch (control) {

  69.     case SERVICE_CONTROL_INTERROGATE:
  70.         status = NGX_IOCP_INTERROGATE;
  71.         break;

  72.     case SERVICE_CONTROL_STOP:
  73.         status = NGX_IOCP_STOP;
  74.         break;

  75.     case SERVICE_CONTROL_PARAMCHANGE:
  76.         status = NGX_IOCP_RECONFIGURE;
  77.         break;

  78.     case NGX_SERVICE_CONTROL_SHUTDOWN:
  79.         status = NGX_IOCP_REOPEN;
  80.         break;

  81.     case NGX_SERVICE_CONTROL_REOPEN:
  82.         status = NGX_IOCP_REOPEN;
  83.         break;

  84.     default:
  85.         return ERROR_CALL_NOT_IMPLEMENTED;
  86.     }

  87.     if (ngx_single) {
  88.         if (PostQueuedCompletionStatus(iocp, ... status, ...) == 0) {
  89.             err = ngx_errno;
  90.             ngx_log_error(NGX_LOG_ALERT, log, err,
  91.                           "PostQueuedCompletionStatus() failed");
  92.             return err;
  93.         }

  94.     } else {
  95.         Event
  96.     }

  97.     return NO_ERROR;
  98. }