src/event/ngx_event.c - nginx-1.31.9 nginx/ @ 2a3a19c6f

Global variables defined

Functions defined

Macros defined

Source code


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


  5. #include <ngx_config.h>
  6. #include <ngx_core.h>
  7. #include <ngx_event.h>


  8. ‌#define DEFAULT_CONNECTIONS  512


  9. extern ngx_module_t ngx_kqueue_module;
  10. extern ngx_module_t ngx_eventport_module;
  11. extern ngx_module_t ngx_devpoll_module;
  12. extern ngx_module_t ngx_epoll_module;
  13. extern ngx_module_t ngx_select_module;


  14. static char *ngx_event_init_conf(ngx_cycle_t *cycle, void *conf);
  15. static ngx_int_t ngx_event_module_init(ngx_cycle_t *cycle);
  16. static ngx_int_t ngx_event_process_init(ngx_cycle_t *cycle);
  17. static char *ngx_events_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);

  18. static char *ngx_event_connections(ngx_conf_t *cf, ngx_command_t *cmd,
  19.     void *conf);
  20. static char *ngx_event_use(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
  21. static char *ngx_event_debug_connection(ngx_conf_t *cf, ngx_command_t *cmd,
  22.     void *conf);

  23. static void *ngx_event_core_create_conf(ngx_cycle_t *cycle);
  24. static char *ngx_event_core_init_conf(ngx_cycle_t *cycle, void *conf);


  25. ‌static ngx_uint_t     ngx_timer_resolution;
  26. ‌sig_atomic_t          ngx_event_timer_alarm;

  27. ‌static ngx_uint_t     ngx_event_max_module;

  28. ‌ngx_uint_t            ngx_event_flags;
  29. ‌ngx_event_actions_t   ngx_event_actions;


  30. ‌static ngx_atomic_t   connection_counter = 1;
  31. ‌ngx_atomic_t         *ngx_connection_counter = &connection_counter;


  32. ‌ngx_atomic_t         *ngx_accept_mutex_ptr;
  33. ‌ngx_shmtx_t           ngx_accept_mutex;
  34. ‌ngx_uint_t            ngx_use_accept_mutex;
  35. ‌ngx_uint_t            ngx_accept_events;
  36. ‌ngx_uint_t            ngx_accept_mutex_held;
  37. ‌ngx_msec_t            ngx_accept_mutex_delay;
  38. ‌ngx_int_t             ngx_accept_disabled;
  39. ‌ngx_uint_t            ngx_use_exclusive_accept;


  40. #if (NGX_STAT_STUB)

  41. ‌static ngx_atomic_t   ngx_stat_accepted0;
  42. ‌ngx_atomic_t         *ngx_stat_accepted = &ngx_stat_accepted0;
  43. ‌static ngx_atomic_t   ngx_stat_handled0;
  44. ‌ngx_atomic_t         *ngx_stat_handled = &ngx_stat_handled0;
  45. ‌static ngx_atomic_t   ngx_stat_requests0;
  46. ‌ngx_atomic_t         *ngx_stat_requests = &ngx_stat_requests0;
  47. ‌static ngx_atomic_t   ngx_stat_active0;
  48. ‌ngx_atomic_t         *ngx_stat_active = &ngx_stat_active0;
  49. ‌static ngx_atomic_t   ngx_stat_reading0;
  50. ‌ngx_atomic_t         *ngx_stat_reading = &ngx_stat_reading0;
  51. ‌static ngx_atomic_t   ngx_stat_writing0;
  52. ‌ngx_atomic_t         *ngx_stat_writing = &ngx_stat_writing0;
  53. ‌static ngx_atomic_t   ngx_stat_waiting0;
  54. ‌ngx_atomic_t         *ngx_stat_waiting = &ngx_stat_waiting0;

  55. #endif



  56. ‌static ngx_command_t  ngx_events_commands[] = {

  57.     { ngx_string("events"),
  58.       NGX_MAIN_CONF|NGX_CONF_BLOCK|NGX_CONF_NOARGS,
  59.       ngx_events_block,
  60.       0,
  61.       0,
  62.       NULL },

  63.       ngx_null_command
  64. };


  65. ‌static ngx_core_module_t  ngx_events_module_ctx = {
  66.     ngx_string("events"),
  67.     NULL,
  68.     ngx_event_init_conf
  69. };


  70. ‌ngx_module_t  ngx_events_module = {
  71.     NGX_MODULE_V1,
  72.     &ngx_events_module_ctx,                /* module context */
  73.     ngx_events_commands,                   /* module directives */
  74.     NGX_CORE_MODULE,                       /* module type */
  75.     NULL,                                  /* init master */
  76.     NULL,                                  /* init module */
  77.     NULL,                                  /* init process */
  78.     NULL,                                  /* init thread */
  79.     NULL,                                  /* exit thread */
  80.     NULL,                                  /* exit process */
  81.     NULL,                                  /* exit master */
  82.     NGX_MODULE_V1_PADDING
  83. };


  84. ‌static ngx_str_t  event_core_name = ngx_string("event_core");


  85. ‌static ngx_command_t  ngx_event_core_commands[] = {

  86.     { ngx_string("worker_connections"),
  87.       NGX_EVENT_CONF|NGX_CONF_TAKE1,
  88.       ngx_event_connections,
  89.       0,
  90.       0,
  91.       NULL },

  92.     { ngx_string("use"),
  93.       NGX_EVENT_CONF|NGX_CONF_TAKE1,
  94.       ngx_event_use,
  95.       0,
  96.       0,
  97.       NULL },

  98.     { ngx_string("multi_accept"),
  99.       NGX_EVENT_CONF|NGX_CONF_FLAG,
  100.       ngx_conf_set_flag_slot,
  101.       0,
  102.       offsetof(ngx_event_conf_t, multi_accept),
  103.       NULL },

  104.     { ngx_string("accept_mutex"),
  105.       NGX_EVENT_CONF|NGX_CONF_FLAG,
  106.       ngx_conf_set_flag_slot,
  107.       0,
  108.       offsetof(ngx_event_conf_t, accept_mutex),
  109.       NULL },

  110.     { ngx_string("accept_mutex_delay"),
  111.       NGX_EVENT_CONF|NGX_CONF_TAKE1,
  112.       ngx_conf_set_msec_slot,
  113.       0,
  114.       offsetof(ngx_event_conf_t, accept_mutex_delay),
  115.       NULL },

  116.     { ngx_string("debug_connection"),
  117.       NGX_EVENT_CONF|NGX_CONF_TAKE1,
  118.       ngx_event_debug_connection,
  119.       0,
  120.       0,
  121.       NULL },

  122.       ngx_null_command
  123. };


  124. ‌static ngx_event_module_t  ngx_event_core_module_ctx = {
  125.     &event_core_name,
  126.     ngx_event_core_create_conf,            /* create configuration */
  127.     ngx_event_core_init_conf,              /* init configuration */

  128.     { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }
  129. };


  130. ‌ngx_module_t  ngx_event_core_module = {
  131.     NGX_MODULE_V1,
  132.     &ngx_event_core_module_ctx,            /* module context */
  133.     ngx_event_core_commands,               /* module directives */
  134.     NGX_EVENT_MODULE,                      /* module type */
  135.     NULL,                                  /* init master */
  136.     ngx_event_module_init,                 /* init module */
  137.     ngx_event_process_init,                /* init process */
  138.     NULL,                                  /* init thread */
  139.     NULL,                                  /* exit thread */
  140.     NULL,                                  /* exit process */
  141.     NULL,                                  /* exit master */
  142.     NGX_MODULE_V1_PADDING
  143. };


  144. void
  145. ‌ngx_process_events_and_timers(ngx_cycle_t *cycle)
  146. {
  147.     ngx_uint_t  flags;
  148.     ngx_msec_t  timer, delta;

  149.     if (ngx_timer_resolution) {
  150.         timer = NGX_TIMER_INFINITE;
  151.         flags = 0;

  152.     } else {
  153.         timer = ngx_event_find_timer();
  154.         flags = NGX_UPDATE_TIME;

  155. #if (NGX_WIN32)

  156.         /* handle signals from master in case of network inactivity */

  157.         if (timer == NGX_TIMER_INFINITE || timer > 500) {
  158.             timer = 500;
  159.         }

  160. #endif
  161.     }

  162.     if (ngx_use_accept_mutex) {
  163.         if (ngx_accept_disabled > 0) {
  164.             ngx_accept_disabled--;

  165.         } else {
  166.             if (ngx_trylock_accept_mutex(cycle) == NGX_ERROR) {
  167.                 return;
  168.             }

  169.             if (ngx_accept_mutex_held) {
  170.                 flags |= NGX_POST_EVENTS;

  171.             } else {
  172.                 if (timer == NGX_TIMER_INFINITE
  173.                     || timer > ngx_accept_mutex_delay)
  174.                 {
  175.                     timer = ngx_accept_mutex_delay;
  176.                 }
  177.             }
  178.         }
  179.     }

  180.     if (!ngx_queue_empty(&ngx_posted_next_events)) {
  181.         ngx_event_move_posted_next(cycle);
  182.         timer = 0;
  183.     }

  184.     delta = ngx_current_msec;

  185.     (void) ngx_process_events(cycle, timer, flags);

  186.     delta = ngx_current_msec - delta;

  187.     ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
  188.                    "timer delta: %M", delta);

  189.     ngx_event_process_posted(cycle, &ngx_posted_accept_events);

  190.     if (ngx_accept_mutex_held) {
  191.         ngx_shmtx_unlock(&ngx_accept_mutex);
  192.     }

  193.     ngx_event_expire_timers();

  194.     ngx_event_process_posted(cycle, &ngx_posted_events);
  195. }


  196. ngx_int_t
  197. ‌ngx_handle_read_event(ngx_event_t *rev, ngx_uint_t flags)
  198. {
  199. #if (NGX_QUIC)

  200.     ngx_connection_t  *c;

  201.     c = rev->data;

  202.     if (c->quic) {
  203.         return NGX_OK;
  204.     }

  205. #endif

  206.     if (ngx_event_flags & NGX_USE_CLEAR_EVENT) {

  207.         /* kqueue, epoll */

  208.         if (!rev->active && !rev->ready) {
  209.             if (ngx_add_event(rev, NGX_READ_EVENT, NGX_CLEAR_EVENT)
  210.                 == NGX_ERROR)
  211.             {
  212.                 return NGX_ERROR;
  213.             }
  214.         }

  215.         return NGX_OK;

  216.     } else if (ngx_event_flags & NGX_USE_LEVEL_EVENT) {

  217.         /* select, poll, /dev/poll */

  218.         if (!rev->active && !rev->ready) {
  219.             if (ngx_add_event(rev, NGX_READ_EVENT, NGX_LEVEL_EVENT)
  220.                 == NGX_ERROR)
  221.             {
  222.                 return NGX_ERROR;
  223.             }

  224.             return NGX_OK;
  225.         }

  226.         if (rev->active && (rev->ready || (flags & NGX_CLOSE_EVENT))) {
  227.             if (ngx_del_event(rev, NGX_READ_EVENT, NGX_LEVEL_EVENT | flags)
  228.                 == NGX_ERROR)
  229.             {
  230.                 return NGX_ERROR;
  231.             }

  232.             return NGX_OK;
  233.         }

  234.     } else if (ngx_event_flags & NGX_USE_EVENTPORT_EVENT) {

  235.         /* event ports */

  236.         if (!rev->active && !rev->ready) {
  237.             if (ngx_add_event(rev, NGX_READ_EVENT, 0) == NGX_ERROR) {
  238.                 return NGX_ERROR;
  239.             }

  240.             return NGX_OK;
  241.         }

  242.         if (rev->oneshot && rev->ready) {
  243.             if (ngx_del_event(rev, NGX_READ_EVENT, 0) == NGX_ERROR) {
  244.                 return NGX_ERROR;
  245.             }

  246.             return NGX_OK;
  247.         }
  248.     }

  249.     return NGX_OK;
  250. }


  251. ngx_int_t
  252. ‌ngx_handle_write_event(ngx_event_t *wev, size_t lowat)
  253. {
  254.     ngx_connection_t  *c;

  255.     c = wev->data;

  256. #if (NGX_QUIC)
  257.     if (c->quic) {
  258.         return NGX_OK;
  259.     }
  260. #endif

  261.     if (lowat) {
  262.         if (ngx_send_lowat(c, lowat) == NGX_ERROR) {
  263.             return NGX_ERROR;
  264.         }
  265.     }

  266.     if (ngx_event_flags & NGX_USE_CLEAR_EVENT) {

  267.         /* kqueue, epoll */

  268.         if (!wev->active && !wev->ready) {
  269.             if (ngx_add_event(wev, NGX_WRITE_EVENT,
  270.                               NGX_CLEAR_EVENT | (lowat ? NGX_LOWAT_EVENT : 0))
  271.                 == NGX_ERROR)
  272.             {
  273.                 return NGX_ERROR;
  274.             }
  275.         }

  276.         return NGX_OK;

  277.     } else if (ngx_event_flags & NGX_USE_LEVEL_EVENT) {

  278.         /* select, poll, /dev/poll */

  279.         if (!wev->active && !wev->ready) {
  280.             if (ngx_add_event(wev, NGX_WRITE_EVENT, NGX_LEVEL_EVENT)
  281.                 == NGX_ERROR)
  282.             {
  283.                 return NGX_ERROR;
  284.             }

  285.             return NGX_OK;
  286.         }

  287.         if (wev->active && wev->ready) {
  288.             if (ngx_del_event(wev, NGX_WRITE_EVENT, NGX_LEVEL_EVENT)
  289.                 == NGX_ERROR)
  290.             {
  291.                 return NGX_ERROR;
  292.             }

  293.             return NGX_OK;
  294.         }

  295.     } else if (ngx_event_flags & NGX_USE_EVENTPORT_EVENT) {

  296.         /* event ports */

  297.         if (!wev->active && !wev->ready) {
  298.             if (ngx_add_event(wev, NGX_WRITE_EVENT, 0) == NGX_ERROR) {
  299.                 return NGX_ERROR;
  300.             }

  301.             return NGX_OK;
  302.         }

  303.         if (wev->oneshot && wev->ready) {
  304.             if (ngx_del_event(wev, NGX_WRITE_EVENT, 0) == NGX_ERROR) {
  305.                 return NGX_ERROR;
  306.             }

  307.             return NGX_OK;
  308.         }
  309.     }

  310.     return NGX_OK;
  311. }


  312. static char *
  313. ‌ngx_event_init_conf(ngx_cycle_t *cycle, void *conf)
  314. {
  315. #if (NGX_HAVE_REUSEPORT)
  316.     ngx_uint_t        i;
  317.     ngx_core_conf_t  *ccf;
  318.     ngx_listening_t  *ls;
  319. #endif

  320.     if (ngx_get_conf(cycle->conf_ctx, ngx_events_module) == NULL) {
  321.         ngx_log_error(NGX_LOG_EMERG, cycle->log, 0,
  322.                       "no \"events\" section in configuration");
  323.         return NGX_CONF_ERROR;
  324.     }

  325.     if (cycle->connection_n < cycle->listening.nelts + 1) {

  326.         /*
  327.          * there should be at least one connection for each listening
  328.          * socket, plus an additional connection for channel
  329.          */

  330.         ngx_log_error(NGX_LOG_EMERG, cycle->log, 0,
  331.                       "%ui worker_connections are not enough "
  332.                       "for %ui listening sockets",
  333.                       cycle->connection_n, cycle->listening.nelts);

  334.         return NGX_CONF_ERROR;
  335.     }

  336. #if (NGX_HAVE_REUSEPORT)

  337.     ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);

  338.     if (!ngx_test_config && ccf->master) {

  339.         ls = cycle->listening.elts;
  340.         for (i = 0; i < cycle->listening.nelts; i++) {

  341.             if (!ls[i].reuseport || ls[i].worker != 0) {
  342.                 continue;
  343.             }

  344.             if (ngx_clone_listening(cycle, &ls[i]) != NGX_OK) {
  345.                 return NGX_CONF_ERROR;
  346.             }

  347.             /* cloning may change cycle->listening.elts */

  348.             ls = cycle->listening.elts;
  349.         }
  350.     }

  351. #endif

  352.     return NGX_CONF_OK;
  353. }


  354. static ngx_int_t
  355. ‌ngx_event_module_init(ngx_cycle_t *cycle)
  356. {
  357.     void              ***cf;
  358.     u_char              *shared;
  359.     size_t               size, cl;
  360.     ngx_shm_t            shm;
  361.     ngx_time_t          *tp;
  362.     ngx_core_conf_t     *ccf;
  363.     ngx_event_conf_t    *ecf;

  364.     cf = ngx_get_conf(cycle->conf_ctx, ngx_events_module);
  365.     ecf = (*cf)[ngx_event_core_module.ctx_index];

  366.     if (!ngx_test_config && ngx_process <= NGX_PROCESS_MASTER) {
  367.         ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0,
  368.                       "using the \"%s\" event method", ecf->name);
  369.     }

  370.     ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);

  371.     ngx_timer_resolution = ccf->timer_resolution;

  372. #if !(NGX_WIN32)
  373.     {
  374.     ngx_int_t      limit;
  375.     struct rlimit  rlmt;

  376.     if (getrlimit(RLIMIT_NOFILE, &rlmt) == -1) {
  377.         ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
  378.                       "getrlimit(RLIMIT_NOFILE) failed, ignored");

  379.     } else {
  380.         if (ecf->connections > (ngx_uint_t) rlmt.rlim_cur
  381.             && (ccf->rlimit_nofile == NGX_CONF_UNSET
  382.                 || ecf->connections > (ngx_uint_t) ccf->rlimit_nofile))
  383.         {
  384.             limit = (ccf->rlimit_nofile == NGX_CONF_UNSET) ?
  385.                          (ngx_int_t) rlmt.rlim_cur : ccf->rlimit_nofile;

  386.             ngx_log_error(NGX_LOG_WARN, cycle->log, 0,
  387.                           "%ui worker_connections exceed "
  388.                           "open file resource limit: %i",
  389.                           ecf->connections, limit);
  390.         }
  391.     }
  392.     }
  393. #endif /* !(NGX_WIN32) */


  394.     if (ccf->master == 0) {
  395.         return NGX_OK;
  396.     }

  397.     if (ngx_accept_mutex_ptr) {
  398.         return NGX_OK;
  399.     }


  400.     /* cl should be equal to or greater than cache line size */

  401.     cl = 128;

  402.     size = cl            /* ngx_accept_mutex */
  403.            + cl          /* ngx_connection_counter */
  404.            + cl;         /* ngx_temp_number */

  405. #if (NGX_STAT_STUB)

  406.     size += cl           /* ngx_stat_accepted */
  407.            + cl          /* ngx_stat_handled */
  408.            + cl          /* ngx_stat_requests */
  409.            + cl          /* ngx_stat_active */
  410.            + cl          /* ngx_stat_reading */
  411.            + cl          /* ngx_stat_writing */
  412.            + cl;         /* ngx_stat_waiting */

  413. #endif

  414.     shm.size = size;
  415.     ngx_str_set(&shm.name, "nginx_shared_zone");
  416.     shm.log = cycle->log;

  417.     if (ngx_shm_alloc(&shm) != NGX_OK) {
  418.         return NGX_ERROR;
  419.     }

  420.     shared = shm.addr;

  421.     ngx_accept_mutex_ptr = (ngx_atomic_t *) shared;
  422.     ngx_accept_mutex.spin = (ngx_uint_t) -1;

  423.     if (ngx_shmtx_create(&ngx_accept_mutex, (ngx_shmtx_sh_t *) shared,
  424.                          cycle->lock_file.data)
  425.         != NGX_OK)
  426.     {
  427.         return NGX_ERROR;
  428.     }

  429.     ngx_connection_counter = (ngx_atomic_t *) (shared + 1 * cl);

  430.     (void) ngx_atomic_cmp_set(ngx_connection_counter, 0, 1);

  431.     ngx_log_debug2(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
  432.                    "counter: %p, %uA",
  433.                    ngx_connection_counter, *ngx_connection_counter);

  434.     ngx_temp_number = (ngx_atomic_t *) (shared + 2 * cl);

  435.     tp = ngx_timeofday();

  436.     ngx_random_number = (tp->msec << 16) + ngx_pid;

  437. #if (NGX_STAT_STUB)

  438.     ngx_stat_accepted = (ngx_atomic_t *) (shared + 3 * cl);
  439.     ngx_stat_handled = (ngx_atomic_t *) (shared + 4 * cl);
  440.     ngx_stat_requests = (ngx_atomic_t *) (shared + 5 * cl);
  441.     ngx_stat_active = (ngx_atomic_t *) (shared + 6 * cl);
  442.     ngx_stat_reading = (ngx_atomic_t *) (shared + 7 * cl);
  443.     ngx_stat_writing = (ngx_atomic_t *) (shared + 8 * cl);
  444.     ngx_stat_waiting = (ngx_atomic_t *) (shared + 9 * cl);

  445. #endif

  446.     return NGX_OK;
  447. }


  448. #if !(NGX_WIN32)

  449. static void
  450. ‌ngx_timer_signal_handler(int signo)
  451. {
  452.     ngx_event_timer_alarm = 1;

  453. #if 1
  454.     ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ngx_cycle->log, 0, "timer signal");
  455. #endif
  456. }

  457. #endif


  458. static ngx_int_t
  459. ‌ngx_event_process_init(ngx_cycle_t *cycle)
  460. {
  461.     ngx_uint_t           m, i;
  462.     ngx_event_t         *rev, *wev;
  463.     ngx_listening_t     *ls;
  464.     ngx_connection_t    *c, *next, *old;
  465.     ngx_core_conf_t     *ccf;
  466.     ngx_event_conf_t    *ecf;
  467.     ngx_event_module_t  *module;

  468.     ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);
  469.     ecf = ngx_event_get_conf(cycle->conf_ctx, ngx_event_core_module);

  470.     if (ccf->master && ccf->worker_processes > 1 && ecf->accept_mutex) {
  471.         ngx_use_accept_mutex = 1;
  472.         ngx_accept_mutex_held = 0;
  473.         ngx_accept_mutex_delay = ecf->accept_mutex_delay;

  474.     } else {
  475.         ngx_use_accept_mutex = 0;
  476.     }

  477. #if (NGX_WIN32)

  478.     /*
  479.      * disable accept mutex on win32 as it may cause deadlock if
  480.      * grabbed by a process which can't accept connections
  481.      */

  482.     ngx_use_accept_mutex = 0;

  483. #endif

  484.     ngx_use_exclusive_accept = 0;

  485.     ngx_queue_init(&ngx_posted_accept_events);
  486.     ngx_queue_init(&ngx_posted_next_events);
  487.     ngx_queue_init(&ngx_posted_events);

  488.     if (ngx_event_timer_init(cycle->log) == NGX_ERROR) {
  489.         return NGX_ERROR;
  490.     }

  491.     for (m = 0; cycle->modules[m]; m++) {
  492.         if (cycle->modules[m]->type != NGX_EVENT_MODULE) {
  493.             continue;
  494.         }

  495.         if (cycle->modules[m]->ctx_index != ecf->use) {
  496.             continue;
  497.         }

  498.         module = cycle->modules[m]->ctx;

  499.         if (module->actions.init(cycle, ngx_timer_resolution) != NGX_OK) {
  500.             /* fatal */
  501.             exit(2);
  502.         }

  503.         break;
  504.     }

  505. #if !(NGX_WIN32)

  506.     if (ngx_timer_resolution && !(ngx_event_flags & NGX_USE_TIMER_EVENT)) {
  507.         struct sigaction  sa;
  508.         struct itimerval  itv;

  509.         ngx_memzero(&sa, sizeof(struct sigaction));
  510.         sa.sa_handler = ngx_timer_signal_handler;
  511.         sigemptyset(&sa.sa_mask);

  512.         if (sigaction(SIGALRM, &sa, NULL) == -1) {
  513.             ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
  514.                           "sigaction(SIGALRM) failed");
  515.             return NGX_ERROR;
  516.         }

  517.         itv.it_interval.tv_sec = ngx_timer_resolution / 1000;
  518.         itv.it_interval.tv_usec = (ngx_timer_resolution % 1000) * 1000;
  519.         itv.it_value.tv_sec = ngx_timer_resolution / 1000;
  520.         itv.it_value.tv_usec = (ngx_timer_resolution % 1000 ) * 1000;

  521.         if (setitimer(ITIMER_REAL, &itv, NULL) == -1) {
  522.             ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
  523.                           "setitimer() failed");
  524.         }
  525.     }

  526.     if (ngx_event_flags & NGX_USE_FD_EVENT) {
  527.         struct rlimit  rlmt;

  528.         if (getrlimit(RLIMIT_NOFILE, &rlmt) == -1) {
  529.             ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
  530.                           "getrlimit(RLIMIT_NOFILE) failed");
  531.             return NGX_ERROR;
  532.         }

  533.         cycle->files_n = (ngx_uint_t) rlmt.rlim_cur;

  534.         cycle->files = ngx_calloc(sizeof(ngx_connection_t *) * cycle->files_n,
  535.                                   cycle->log);
  536.         if (cycle->files == NULL) {
  537.             return NGX_ERROR;
  538.         }
  539.     }

  540. #else

  541.     if (ngx_timer_resolution && !(ngx_event_flags & NGX_USE_TIMER_EVENT)) {
  542.         ngx_log_error(NGX_LOG_WARN, cycle->log, 0,
  543.                       "the \"timer_resolution\" directive is not supported "
  544.                       "with the configured event method, ignored");
  545.         ngx_timer_resolution = 0;
  546.     }

  547. #endif

  548.     cycle->connections =
  549.         ngx_alloc(sizeof(ngx_connection_t) * cycle->connection_n, cycle->log);
  550.     if (cycle->connections == NULL) {
  551.         return NGX_ERROR;
  552.     }

  553.     c = cycle->connections;

  554.     cycle->read_events = ngx_alloc(sizeof(ngx_event_t) * cycle->connection_n,
  555.                                    cycle->log);
  556.     if (cycle->read_events == NULL) {
  557.         return NGX_ERROR;
  558.     }

  559.     rev = cycle->read_events;
  560.     for (i = 0; i < cycle->connection_n; i++) {
  561.         rev[i].closed = 1;
  562.         rev[i].instance = 1;
  563.     }

  564.     cycle->write_events = ngx_alloc(sizeof(ngx_event_t) * cycle->connection_n,
  565.                                     cycle->log);
  566.     if (cycle->write_events == NULL) {
  567.         return NGX_ERROR;
  568.     }

  569.     wev = cycle->write_events;
  570.     for (i = 0; i < cycle->connection_n; i++) {
  571.         wev[i].closed = 1;
  572.     }

  573.     i = cycle->connection_n;
  574.     next = NULL;

  575.     do {
  576.         i--;

  577.         c[i].data = next;
  578.         c[i].read = &cycle->read_events[i];
  579.         c[i].write = &cycle->write_events[i];
  580.         c[i].fd = (ngx_socket_t) -1;

  581.         next = &c[i];
  582.     } while (i);

  583.     cycle->free_connections = next;
  584.     cycle->free_connection_n = cycle->connection_n;

  585.     /* for each listening socket */

  586.     ls = cycle->listening.elts;
  587.     for (i = 0; i < cycle->listening.nelts; i++) {

  588. #if (NGX_HAVE_REUSEPORT)
  589.         if (ls[i].reuseport && ls[i].worker != ngx_worker) {
  590.             continue;
  591.         }
  592. #endif

  593.         c = ngx_get_connection(ls[i].fd, cycle->log);

  594.         if (c == NULL) {
  595.             return NGX_ERROR;
  596.         }

  597.         c->type = ls[i].type;
  598.         c->log = &ls[i].log;

  599.         c->listening = &ls[i];
  600.         ls[i].connection = c;

  601.         rev = c->read;

  602.         rev->log = c->log;
  603.         rev->accept = 1;

  604. #if (NGX_HAVE_DEFERRED_ACCEPT)
  605.         rev->deferred_accept = ls[i].deferred_accept;
  606. #endif

  607.         if (cycle->old_cycle) {
  608.             if (ls[i].previous) {

  609.                 /*
  610.                  * delete the old accept events that were bound to
  611.                  * the old cycle read events array
  612.                  */

  613.                 old = ls[i].previous->connection;

  614.                 if (ngx_del_event(old->read, NGX_READ_EVENT, NGX_CLOSE_EVENT)
  615.                     == NGX_ERROR)
  616.                 {
  617.                     return NGX_ERROR;
  618.                 }

  619.                 old->fd = (ngx_socket_t) -1;
  620.             }
  621.         }

  622. #if (NGX_WIN32)

  623.         rev->handler = ngx_event_accept;

  624.         if (ngx_use_accept_mutex) {
  625.             continue;
  626.         }

  627.         if (ngx_add_event(rev, NGX_READ_EVENT, 0) == NGX_ERROR) {
  628.             return NGX_ERROR;
  629.         }

  630. #else

  631.         if (c->type == SOCK_STREAM) {
  632.             rev->handler = ngx_event_accept;

  633. #if (NGX_QUIC)
  634.         } else if (ls[i].quic) {
  635.             rev->handler = ngx_quic_recvmsg;
  636. #endif
  637.         } else {
  638.             rev->handler = ngx_event_recvmsg;
  639.         }

  640. #if (NGX_HAVE_REUSEPORT)

  641.         if (ls[i].reuseport) {
  642.             if (ngx_add_event(rev, NGX_READ_EVENT, 0) == NGX_ERROR) {
  643.                 return NGX_ERROR;
  644.             }

  645.             continue;
  646.         }

  647. #endif

  648.         if (ngx_use_accept_mutex) {
  649.             continue;
  650.         }

  651. #if (NGX_HAVE_EPOLLEXCLUSIVE)

  652.         if ((ngx_event_flags & NGX_USE_EPOLL_EVENT)
  653.             && ccf->worker_processes > 1)
  654.         {
  655.             ngx_use_exclusive_accept = 1;

  656.             if (ngx_add_event(rev, NGX_READ_EVENT, NGX_EXCLUSIVE_EVENT)
  657.                 == NGX_ERROR)
  658.             {
  659.                 return NGX_ERROR;
  660.             }

  661.             continue;
  662.         }

  663. #endif

  664.         if (ngx_add_event(rev, NGX_READ_EVENT, 0) == NGX_ERROR) {
  665.             return NGX_ERROR;
  666.         }

  667. #endif

  668.     }

  669.     return NGX_OK;
  670. }


  671. ngx_int_t
  672. ‌ngx_send_lowat(ngx_connection_t *c, size_t lowat)
  673. {
  674.     int  sndlowat;

  675. #if (NGX_HAVE_LOWAT_EVENT)

  676.     if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) {
  677.         c->write->available = lowat;
  678.         return NGX_OK;
  679.     }

  680. #endif

  681.     if (lowat == 0 || c->sndlowat) {
  682.         return NGX_OK;
  683.     }

  684.     sndlowat = (int) lowat;

  685.     if (setsockopt(c->fd, SOL_SOCKET, SO_SNDLOWAT,
  686.                    (const void *) &sndlowat, sizeof(int))
  687.         == -1)
  688.     {
  689.         ngx_connection_error(c, ngx_socket_errno,
  690.                              "setsockopt(SO_SNDLOWAT) failed");
  691.         return NGX_ERROR;
  692.     }

  693.     c->sndlowat = 1;

  694.     return NGX_OK;
  695. }


  696. static char *
  697. ‌ngx_events_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
  698. {
  699.     char                 *rv;
  700.     void               ***ctx;
  701.     ngx_uint_t            i;
  702.     ngx_conf_t            pcf;
  703.     ngx_event_module_t   *m;

  704.     if (*(void **) conf) {
  705.         return "is duplicate";
  706.     }

  707.     /* count the number of the event modules and set up their indices */

  708.     ngx_event_max_module = ngx_count_modules(cf->cycle, NGX_EVENT_MODULE);

  709.     ctx = ngx_pcalloc(cf->pool, sizeof(void *));
  710.     if (ctx == NULL) {
  711.         return NGX_CONF_ERROR;
  712.     }

  713.     *ctx = ngx_pcalloc(cf->pool, ngx_event_max_module * sizeof(void *));
  714.     if (*ctx == NULL) {
  715.         return NGX_CONF_ERROR;
  716.     }

  717.     *(void **) conf = ctx;

  718.     for (i = 0; cf->cycle->modules[i]; i++) {
  719.         if (cf->cycle->modules[i]->type != NGX_EVENT_MODULE) {
  720.             continue;
  721.         }

  722.         m = cf->cycle->modules[i]->ctx;

  723.         if (m->create_conf) {
  724.             (*ctx)[cf->cycle->modules[i]->ctx_index] =
  725.                                                      m->create_conf(cf->cycle);
  726.             if ((*ctx)[cf->cycle->modules[i]->ctx_index] == NULL) {
  727.                 return NGX_CONF_ERROR;
  728.             }
  729.         }
  730.     }

  731.     pcf = *cf;
  732.     cf->ctx = ctx;
  733.     cf->module_type = NGX_EVENT_MODULE;
  734.     cf->cmd_type = NGX_EVENT_CONF;

  735.     rv = ngx_conf_parse(cf, NULL);

  736.     *cf = pcf;

  737.     if (rv != NGX_CONF_OK) {
  738.         return rv;
  739.     }

  740.     for (i = 0; cf->cycle->modules[i]; i++) {
  741.         if (cf->cycle->modules[i]->type != NGX_EVENT_MODULE) {
  742.             continue;
  743.         }

  744.         m = cf->cycle->modules[i]->ctx;

  745.         if (m->init_conf) {
  746.             rv = m->init_conf(cf->cycle,
  747.                               (*ctx)[cf->cycle->modules[i]->ctx_index]);
  748.             if (rv != NGX_CONF_OK) {
  749.                 return rv;
  750.             }
  751.         }
  752.     }

  753.     return NGX_CONF_OK;
  754. }


  755. static char *
  756. ‌ngx_event_connections(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
  757. {
  758.     ngx_event_conf_t  *ecf = conf;

  759.     ngx_str_t  *value;

  760.     if (ecf->connections != NGX_CONF_UNSET_UINT) {
  761.         return "is duplicate";
  762.     }

  763.     value = cf->args->elts;
  764.     ecf->connections = ngx_atoi(value[1].data, value[1].len);
  765.     if (ecf->connections == (ngx_uint_t) NGX_ERROR) {
  766.         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  767.                            "invalid number \"%V\"", &value[1]);

  768.         return NGX_CONF_ERROR;
  769.     }

  770.     cf->cycle->connection_n = ecf->connections;

  771.     return NGX_CONF_OK;
  772. }


  773. static char *
  774. ‌ngx_event_use(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
  775. {
  776.     ngx_event_conf_t  *ecf = conf;

  777.     ngx_int_t             m;
  778.     ngx_str_t            *value;
  779.     ngx_event_conf_t     *old_ecf;
  780.     ngx_event_module_t   *module;

  781.     if (ecf->use != NGX_CONF_UNSET_UINT) {
  782.         return "is duplicate";
  783.     }

  784.     value = cf->args->elts;

  785.     if (cf->cycle->old_cycle->conf_ctx) {
  786.         old_ecf = ngx_event_get_conf(cf->cycle->old_cycle->conf_ctx,
  787.                                      ngx_event_core_module);
  788.     } else {
  789.         old_ecf = NULL;
  790.     }


  791.     for (m = 0; cf->cycle->modules[m]; m++) {
  792.         if (cf->cycle->modules[m]->type != NGX_EVENT_MODULE) {
  793.             continue;
  794.         }

  795.         module = cf->cycle->modules[m]->ctx;
  796.         if (module->name->len == value[1].len) {
  797.             if (ngx_strcmp(module->name->data, value[1].data) == 0) {
  798.                 ecf->use = cf->cycle->modules[m]->ctx_index;
  799.                 ecf->name = module->name->data;

  800.                 if (ngx_process == NGX_PROCESS_SINGLE
  801.                     && old_ecf
  802.                     && old_ecf->use != ecf->use)
  803.                 {
  804.                     ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  805.                                "when the server runs without a master process "
  806.                                "the \"%V\" event type must be the same as "
  807.                                "in previous configuration - \"%s\" "
  808.                                "and it cannot be changed on the fly, "
  809.                                "to change it you need to stop server "
  810.                                "and start it again",
  811.                                &value[1], old_ecf->name);

  812.                     return NGX_CONF_ERROR;
  813.                 }

  814.                 return NGX_CONF_OK;
  815.             }
  816.         }
  817.     }

  818.     ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  819.                        "invalid event type \"%V\"", &value[1]);

  820.     return NGX_CONF_ERROR;
  821. }


  822. static char *
  823. ‌ngx_event_debug_connection(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
  824. {
  825. #if (NGX_DEBUG)
  826.     ngx_event_conf_t  *ecf = conf;

  827.     ngx_int_t             rc;
  828.     ngx_str_t            *value;
  829.     ngx_url_t             u;
  830.     ngx_cidr_t            c, *cidr;
  831.     ngx_uint_t            i;
  832.     struct sockaddr_in   *sin;
  833. #if (NGX_HAVE_INET6)
  834.     struct sockaddr_in6  *sin6;
  835. #endif

  836.     value = cf->args->elts;

  837. #if (NGX_HAVE_UNIX_DOMAIN)

  838.     if (ngx_strcmp(value[1].data, "unix:") == 0) {
  839.         cidr = ngx_array_push(&ecf->debug_connection);
  840.         if (cidr == NULL) {
  841.             return NGX_CONF_ERROR;
  842.         }

  843.         cidr->family = AF_UNIX;
  844.         return NGX_CONF_OK;
  845.     }

  846. #endif

  847.     rc = ngx_ptocidr(&value[1], &c);

  848.     if (rc != NGX_ERROR) {
  849.         if (rc == NGX_DONE) {
  850.             ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
  851.                                "low address bits of %V are meaningless",
  852.                                &value[1]);
  853.         }

  854.         cidr = ngx_array_push(&ecf->debug_connection);
  855.         if (cidr == NULL) {
  856.             return NGX_CONF_ERROR;
  857.         }

  858.         *cidr = c;

  859.         return NGX_CONF_OK;
  860.     }

  861.     ngx_memzero(&u, sizeof(ngx_url_t));
  862.     u.host = value[1];

  863.     if (ngx_inet_resolve_host(cf->pool, &u) != NGX_OK) {
  864.         if (u.err) {
  865.             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  866.                                "%s in debug_connection \"%V\"",
  867.                                u.err, &u.host);
  868.         }

  869.         return NGX_CONF_ERROR;
  870.     }

  871.     cidr = ngx_array_push_n(&ecf->debug_connection, u.naddrs);
  872.     if (cidr == NULL) {
  873.         return NGX_CONF_ERROR;
  874.     }

  875.     ngx_memzero(cidr, u.naddrs * sizeof(ngx_cidr_t));

  876.     for (i = 0; i < u.naddrs; i++) {
  877.         cidr[i].family = u.addrs[i].sockaddr->sa_family;

  878.         switch (cidr[i].family) {

  879. #if (NGX_HAVE_INET6)
  880.         case AF_INET6:
  881.             sin6 = (struct sockaddr_in6 *) u.addrs[i].sockaddr;
  882.             cidr[i].u.in6.addr = sin6->sin6_addr;
  883.             ngx_memset(cidr[i].u.in6.mask.s6_addr, 0xff, 16);
  884.             break;
  885. #endif

  886.         default: /* AF_INET */
  887.             sin = (struct sockaddr_in *) u.addrs[i].sockaddr;
  888.             cidr[i].u.in.addr = sin->sin_addr.s_addr;
  889.             cidr[i].u.in.mask = 0xffffffff;
  890.             break;
  891.         }
  892.     }

  893. #else

  894.     ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
  895.                        "\"debug_connection\" is ignored, you need to rebuild "
  896.                        "nginx using --with-debug option to enable it");

  897. #endif

  898.     return NGX_CONF_OK;
  899. }


  900. static void *
  901. ‌ngx_event_core_create_conf(ngx_cycle_t *cycle)
  902. {
  903.     ngx_event_conf_t  *ecf;

  904.     ecf = ngx_palloc(cycle->pool, sizeof(ngx_event_conf_t));
  905.     if (ecf == NULL) {
  906.         return NULL;
  907.     }

  908.     ecf->connections = NGX_CONF_UNSET_UINT;
  909.     ecf->use = NGX_CONF_UNSET_UINT;
  910.     ecf->multi_accept = NGX_CONF_UNSET;
  911.     ecf->accept_mutex = NGX_CONF_UNSET;
  912.     ecf->accept_mutex_delay = NGX_CONF_UNSET_MSEC;
  913.     ecf->name = (void *) NGX_CONF_UNSET;

  914. #if (NGX_DEBUG)

  915.     if (ngx_array_init(&ecf->debug_connection, cycle->pool, 4,
  916.                        sizeof(ngx_cidr_t)) == NGX_ERROR)
  917.     {
  918.         return NULL;
  919.     }

  920. #endif

  921.     return ecf;
  922. }


  923. static char *
  924. ‌ngx_event_core_init_conf(ngx_cycle_t *cycle, void *conf)
  925. {
  926.     ngx_event_conf_t  *ecf = conf;

  927. #if (NGX_HAVE_EPOLL) && !(NGX_TEST_BUILD_EPOLL)
  928.     int                  fd;
  929. #endif
  930.     ngx_int_t            i;
  931.     ngx_module_t        *module;
  932.     ngx_event_module_t  *event_module;

  933.     module = NULL;

  934. #if (NGX_HAVE_EPOLL) && !(NGX_TEST_BUILD_EPOLL)

  935.     fd = epoll_create(100);

  936.     if (fd != -1) {
  937.         (void) close(fd);
  938.         module = &ngx_epoll_module;

  939.     } else if (ngx_errno != NGX_ENOSYS) {
  940.         module = &ngx_epoll_module;
  941.     }

  942. #endif

  943. #if (NGX_HAVE_DEVPOLL) && !(NGX_TEST_BUILD_DEVPOLL)

  944.     module = &ngx_devpoll_module;

  945. #endif

  946. #if (NGX_HAVE_KQUEUE)

  947.     module = &ngx_kqueue_module;

  948. #endif

  949. #if (NGX_HAVE_SELECT)

  950.     if (module == NULL) {
  951.         module = &ngx_select_module;
  952.     }

  953. #endif

  954.     if (module == NULL) {
  955.         for (i = 0; cycle->modules[i]; i++) {

  956.             if (cycle->modules[i]->type != NGX_EVENT_MODULE) {
  957.                 continue;
  958.             }

  959.             event_module = cycle->modules[i]->ctx;

  960.             if (ngx_strcmp(event_module->name->data, event_core_name.data) == 0)
  961.             {
  962.                 continue;
  963.             }

  964.             module = cycle->modules[i];
  965.             break;
  966.         }
  967.     }

  968.     if (module == NULL) {
  969.         ngx_log_error(NGX_LOG_EMERG, cycle->log, 0, "no events module found");
  970.         return NGX_CONF_ERROR;
  971.     }

  972.     ngx_conf_init_uint_value(ecf->connections, DEFAULT_CONNECTIONS);
  973.     cycle->connection_n = ecf->connections;

  974.     ngx_conf_init_uint_value(ecf->use, module->ctx_index);

  975.     event_module = module->ctx;
  976.     ngx_conf_init_ptr_value(ecf->name, event_module->name->data);

  977.     ngx_conf_init_value(ecf->multi_accept, 0);
  978.     ngx_conf_init_value(ecf->accept_mutex, 0);
  979.     ngx_conf_init_msec_value(ecf->accept_mutex_delay, 500);

  980.     return NGX_CONF_OK;
  981. }