src/core/ngx_cycle.c - nginx source code

Global variables defined

Functions 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. static void ngx_destroy_cycle_pools(ngx_conf_t *conf);
  9. static ngx_int_t ngx_init_zone_pool(ngx_cycle_t *cycle,
  10.     ngx_shm_zone_t *shm_zone);
  11. static ngx_int_t ngx_test_lockfile(u_char *file, ngx_log_t *log);
  12. static void ngx_clean_old_cycles(ngx_event_t *ev);
  13. static void ngx_shutdown_timer_handler(ngx_event_t *ev);


  14. volatile ngx_cycle_t  *ngx_cycle;
  15. ngx_array_t            ngx_old_cycles;

  16. static ngx_pool_t     *ngx_temp_pool;
  17. static ngx_event_t     ngx_cleaner_event;
  18. static ngx_event_t     ngx_shutdown_event;

  19. ngx_uint_t             ngx_test_config;
  20. ngx_uint_t             ngx_dump_config;
  21. ngx_uint_t             ngx_quiet_mode;


  22. /* STUB NAME */
  23. static ngx_connection_t  dumb;
  24. /* STUB */


  25. ngx_cycle_t *
  26. ngx_init_cycle(ngx_cycle_t *old_cycle)
  27. {
  28.     void                *rv, *data;
  29.     char               **senv;
  30.     ngx_uint_t           i, n;
  31.     ngx_log_t           *log;
  32.     ngx_time_t          *tp;
  33.     ngx_conf_t           conf;
  34.     ngx_pool_t          *pool;
  35.     ngx_cycle_t         *cycle, **old;
  36.     ngx_shm_zone_t      *shm_zone, *oshm_zone;
  37.     ngx_list_part_t     *part, *opart;
  38.     ngx_open_file_t     *file;
  39.     ngx_listening_t     *ls, *nls;
  40.     ngx_core_conf_t     *ccf, *old_ccf;
  41.     ngx_core_module_t   *module;
  42.     char                 hostname[NGX_MAXHOSTNAMELEN];

  43.     ngx_timezone_update();

  44.     /* force localtime update with a new timezone */

  45.     tp = ngx_timeofday();
  46.     tp->sec = 0;

  47.     ngx_time_update();


  48.     log = old_cycle->log;

  49.     pool = ngx_create_pool(NGX_CYCLE_POOL_SIZE, log);
  50.     if (pool == NULL) {
  51.         return NULL;
  52.     }
  53.     pool->log = log;

  54.     cycle = ngx_pcalloc(pool, sizeof(ngx_cycle_t));
  55.     if (cycle == NULL) {
  56.         ngx_destroy_pool(pool);
  57.         return NULL;
  58.     }

  59.     cycle->pool = pool;
  60.     cycle->log = log;
  61.     cycle->old_cycle = old_cycle;

  62.     cycle->conf_prefix.len = old_cycle->conf_prefix.len;
  63.     cycle->conf_prefix.data = ngx_pstrdup(pool, &old_cycle->conf_prefix);
  64.     if (cycle->conf_prefix.data == NULL) {
  65.         ngx_destroy_pool(pool);
  66.         return NULL;
  67.     }

  68.     cycle->prefix.len = old_cycle->prefix.len;
  69.     cycle->prefix.data = ngx_pstrdup(pool, &old_cycle->prefix);
  70.     if (cycle->prefix.data == NULL) {
  71.         ngx_destroy_pool(pool);
  72.         return NULL;
  73.     }

  74.     cycle->error_log.len = old_cycle->error_log.len;
  75.     cycle->error_log.data = ngx_pnalloc(pool, old_cycle->error_log.len + 1);
  76.     if (cycle->error_log.data == NULL) {
  77.         ngx_destroy_pool(pool);
  78.         return NULL;
  79.     }
  80.     ngx_cpystrn(cycle->error_log.data, old_cycle->error_log.data,
  81.                 old_cycle->error_log.len + 1);

  82.     cycle->conf_file.len = old_cycle->conf_file.len;
  83.     cycle->conf_file.data = ngx_pnalloc(pool, old_cycle->conf_file.len + 1);
  84.     if (cycle->conf_file.data == NULL) {
  85.         ngx_destroy_pool(pool);
  86.         return NULL;
  87.     }
  88.     ngx_cpystrn(cycle->conf_file.data, old_cycle->conf_file.data,
  89.                 old_cycle->conf_file.len + 1);

  90.     cycle->conf_param.len = old_cycle->conf_param.len;
  91.     cycle->conf_param.data = ngx_pstrdup(pool, &old_cycle->conf_param);
  92.     if (cycle->conf_param.data == NULL) {
  93.         ngx_destroy_pool(pool);
  94.         return NULL;
  95.     }


  96.     n = old_cycle->paths.nelts ? old_cycle->paths.nelts : 10;

  97.     if (ngx_array_init(&cycle->paths, pool, n, sizeof(ngx_path_t *))
  98.         != NGX_OK)
  99.     {
  100.         ngx_destroy_pool(pool);
  101.         return NULL;
  102.     }

  103.     ngx_memzero(cycle->paths.elts, n * sizeof(ngx_path_t *));


  104.     if (ngx_array_init(&cycle->config_dump, pool, 1, sizeof(ngx_conf_dump_t))
  105.         != NGX_OK)
  106.     {
  107.         ngx_destroy_pool(pool);
  108.         return NULL;
  109.     }

  110.     ngx_rbtree_init(&cycle->config_dump_rbtree, &cycle->config_dump_sentinel,
  111.                     ngx_str_rbtree_insert_value);

  112.     if (old_cycle->open_files.part.nelts) {
  113.         n = old_cycle->open_files.part.nelts;
  114.         for (part = old_cycle->open_files.part.next; part; part = part->next) {
  115.             n += part->nelts;
  116.         }

  117.     } else {
  118.         n = 20;
  119.     }

  120.     if (ngx_list_init(&cycle->open_files, pool, n, sizeof(ngx_open_file_t))
  121.         != NGX_OK)
  122.     {
  123.         ngx_destroy_pool(pool);
  124.         return NULL;
  125.     }


  126.     if (old_cycle->shared_memory.part.nelts) {
  127.         n = old_cycle->shared_memory.part.nelts;
  128.         for (part = old_cycle->shared_memory.part.next; part; part = part->next)
  129.         {
  130.             n += part->nelts;
  131.         }

  132.     } else {
  133.         n = 1;
  134.     }

  135.     if (ngx_list_init(&cycle->shared_memory, pool, n, sizeof(ngx_shm_zone_t))
  136.         != NGX_OK)
  137.     {
  138.         ngx_destroy_pool(pool);
  139.         return NULL;
  140.     }

  141.     n = old_cycle->listening.nelts ? old_cycle->listening.nelts : 10;

  142.     if (ngx_array_init(&cycle->listening, pool, n, sizeof(ngx_listening_t))
  143.         != NGX_OK)
  144.     {
  145.         ngx_destroy_pool(pool);
  146.         return NULL;
  147.     }

  148.     ngx_memzero(cycle->listening.elts, n * sizeof(ngx_listening_t));


  149.     ngx_queue_init(&cycle->reusable_connections_queue);


  150.     cycle->conf_ctx = ngx_pcalloc(pool, ngx_max_module * sizeof(void *));
  151.     if (cycle->conf_ctx == NULL) {
  152.         ngx_destroy_pool(pool);
  153.         return NULL;
  154.     }


  155.     if (gethostname(hostname, NGX_MAXHOSTNAMELEN) == -1) {
  156.         ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "gethostname() failed");
  157.         ngx_destroy_pool(pool);
  158.         return NULL;
  159.     }

  160.     /* on Linux gethostname() silently truncates name that does not fit */

  161.     hostname[NGX_MAXHOSTNAMELEN - 1] = '\0';
  162.     cycle->hostname.len = ngx_strlen(hostname);

  163.     cycle->hostname.data = ngx_pnalloc(pool, cycle->hostname.len);
  164.     if (cycle->hostname.data == NULL) {
  165.         ngx_destroy_pool(pool);
  166.         return NULL;
  167.     }

  168.     ngx_strlow(cycle->hostname.data, (u_char *) hostname, cycle->hostname.len);


  169.     if (ngx_cycle_modules(cycle) != NGX_OK) {
  170.         ngx_destroy_pool(pool);
  171.         return NULL;
  172.     }


  173.     for (i = 0; cycle->modules[i]; i++) {
  174.         if (cycle->modules[i]->type != NGX_CORE_MODULE) {
  175.             continue;
  176.         }

  177.         module = cycle->modules[i]->ctx;

  178.         if (module->create_conf) {
  179.             rv = module->create_conf(cycle);
  180.             if (rv == NULL) {
  181.                 ngx_destroy_pool(pool);
  182.                 return NULL;
  183.             }
  184.             cycle->conf_ctx[cycle->modules[i]->index] = rv;
  185.         }
  186.     }


  187.     senv = environ;


  188.     ngx_memzero(&conf, sizeof(ngx_conf_t));
  189.     /* STUB: init array ? */
  190.     conf.args = ngx_array_create(pool, 10, sizeof(ngx_str_t));
  191.     if (conf.args == NULL) {
  192.         ngx_destroy_pool(pool);
  193.         return NULL;
  194.     }

  195.     conf.temp_pool = ngx_create_pool(NGX_CYCLE_POOL_SIZE, log);
  196.     if (conf.temp_pool == NULL) {
  197.         ngx_destroy_pool(pool);
  198.         return NULL;
  199.     }


  200.     conf.ctx = cycle->conf_ctx;
  201.     conf.cycle = cycle;
  202.     conf.pool = pool;
  203.     conf.log = log;
  204.     conf.module_type = NGX_CORE_MODULE;
  205.     conf.cmd_type = NGX_MAIN_CONF;

  206. #if 0
  207.     log->log_level = NGX_LOG_DEBUG_ALL;
  208. #endif

  209.     if (ngx_conf_param(&conf) != NGX_CONF_OK) {
  210.         environ = senv;
  211.         ngx_destroy_cycle_pools(&conf);
  212.         return NULL;
  213.     }

  214.     if (ngx_conf_parse(&conf, &cycle->conf_file) != NGX_CONF_OK) {
  215.         environ = senv;
  216.         ngx_destroy_cycle_pools(&conf);
  217.         return NULL;
  218.     }

  219.     if (ngx_test_config && !ngx_quiet_mode) {
  220.         ngx_log_stderr(0, "the configuration file %s syntax is ok",
  221.                        cycle->conf_file.data);
  222.     }

  223.     for (i = 0; cycle->modules[i]; i++) {
  224.         if (cycle->modules[i]->type != NGX_CORE_MODULE) {
  225.             continue;
  226.         }

  227.         module = cycle->modules[i]->ctx;

  228.         if (module->init_conf) {
  229.             if (module->init_conf(cycle,
  230.                                   cycle->conf_ctx[cycle->modules[i]->index])
  231.                 == NGX_CONF_ERROR)
  232.             {
  233.                 environ = senv;
  234.                 ngx_destroy_cycle_pools(&conf);
  235.                 return NULL;
  236.             }
  237.         }
  238.     }

  239.     if (ngx_process == NGX_PROCESS_SIGNALLER) {
  240.         return cycle;
  241.     }

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

  243.     if (ngx_test_config) {

  244.         if (ngx_create_pidfile(&ccf->pid, log) != NGX_OK) {
  245.             goto failed;
  246.         }

  247.     } else if (!ngx_is_init_cycle(old_cycle)) {

  248.         /*
  249.          * we do not create the pid file in the first ngx_init_cycle() call
  250.          * because we need to write the demonized process pid
  251.          */

  252.         old_ccf = (ngx_core_conf_t *) ngx_get_conf(old_cycle->conf_ctx,
  253.                                                    ngx_core_module);
  254.         if (ccf->pid.len != old_ccf->pid.len
  255.             || ngx_strcmp(ccf->pid.data, old_ccf->pid.data) != 0)
  256.         {
  257.             /* new pid file name */

  258.             if (ngx_create_pidfile(&ccf->pid, log) != NGX_OK) {
  259.                 goto failed;
  260.             }

  261.             ngx_delete_pidfile(old_cycle);
  262.         }
  263.     }


  264.     if (ngx_test_lockfile(cycle->lock_file.data, log) != NGX_OK) {
  265.         goto failed;
  266.     }


  267.     if (ngx_create_paths(cycle, ccf->user) != NGX_OK) {
  268.         goto failed;
  269.     }


  270.     if (ngx_log_open_default(cycle) != NGX_OK) {
  271.         goto failed;
  272.     }

  273.     /* open the new files */

  274.     part = &cycle->open_files.part;
  275.     file = part->elts;

  276.     for (i = 0; /* void */ ; i++) {

  277.         if (i >= part->nelts) {
  278.             if (part->next == NULL) {
  279.                 break;
  280.             }
  281.             part = part->next;
  282.             file = part->elts;
  283.             i = 0;
  284.         }

  285.         if (file[i].name.len == 0) {
  286.             continue;
  287.         }

  288.         file[i].fd = ngx_open_file(file[i].name.data,
  289.                                    NGX_FILE_APPEND,
  290.                                    NGX_FILE_CREATE_OR_OPEN,
  291.                                    NGX_FILE_DEFAULT_ACCESS);

  292.         ngx_log_debug3(NGX_LOG_DEBUG_CORE, log, 0,
  293.                        "log: %p %d \"%s\"",
  294.                        &file[i], file[i].fd, file[i].name.data);

  295.         if (file[i].fd == NGX_INVALID_FILE) {
  296.             ngx_log_error(NGX_LOG_EMERG, log, ngx_errno,
  297.                           ngx_open_file_n " \"%s\" failed",
  298.                           file[i].name.data);
  299.             goto failed;
  300.         }

  301. #if !(NGX_WIN32)
  302.         if (fcntl(file[i].fd, F_SETFD, FD_CLOEXEC) == -1) {
  303.             ngx_log_error(NGX_LOG_EMERG, log, ngx_errno,
  304.                           "fcntl(FD_CLOEXEC) \"%s\" failed",
  305.                           file[i].name.data);
  306.             goto failed;
  307.         }
  308. #endif
  309.     }

  310.     cycle->log = &cycle->new_log;
  311.     pool->log = &cycle->new_log;


  312.     /* create shared memory */

  313.     part = &cycle->shared_memory.part;
  314.     shm_zone = part->elts;

  315.     for (i = 0; /* void */ ; i++) {

  316.         if (i >= part->nelts) {
  317.             if (part->next == NULL) {
  318.                 break;
  319.             }
  320.             part = part->next;
  321.             shm_zone = part->elts;
  322.             i = 0;
  323.         }

  324.         if (shm_zone[i].shm.size == 0) {
  325.             ngx_log_error(NGX_LOG_EMERG, log, 0,
  326.                           "zero size shared memory zone \"%V\"",
  327.                           &shm_zone[i].shm.name);
  328.             goto failed;
  329.         }

  330.         shm_zone[i].shm.log = cycle->log;

  331.         opart = &old_cycle->shared_memory.part;
  332.         oshm_zone = opart->elts;

  333.         data = NULL;

  334.         for (n = 0; /* void */ ; n++) {

  335.             if (n >= opart->nelts) {
  336.                 if (opart->next == NULL) {
  337.                     break;
  338.                 }
  339.                 opart = opart->next;
  340.                 oshm_zone = opart->elts;
  341.                 n = 0;
  342.             }

  343.             if (shm_zone[i].shm.name.len != oshm_zone[n].shm.name.len) {
  344.                 continue;
  345.             }

  346.             if (ngx_strncmp(shm_zone[i].shm.name.data,
  347.                             oshm_zone[n].shm.name.data,
  348.                             shm_zone[i].shm.name.len)
  349.                 != 0)
  350.             {
  351.                 continue;
  352.             }

  353.             if (shm_zone[i].tag == oshm_zone[n].tag && shm_zone[i].noreuse) {
  354.                 data = oshm_zone[n].data;
  355.                 break;
  356.             }

  357.             if (shm_zone[i].tag == oshm_zone[n].tag
  358.                 && shm_zone[i].shm.size == oshm_zone[n].shm.size)
  359.             {
  360.                 shm_zone[i].shm.addr = oshm_zone[n].shm.addr;
  361. #if (NGX_WIN32)
  362.                 shm_zone[i].shm.handle = oshm_zone[n].shm.handle;
  363. #endif

  364.                 if (shm_zone[i].init(&shm_zone[i], oshm_zone[n].data)
  365.                     != NGX_OK)
  366.                 {
  367.                     goto failed;
  368.                 }

  369.                 goto shm_zone_found;
  370.             }

  371.             break;
  372.         }

  373.         if (ngx_shm_alloc(&shm_zone[i].shm) != NGX_OK) {
  374.             goto failed;
  375.         }

  376.         if (ngx_init_zone_pool(cycle, &shm_zone[i]) != NGX_OK) {
  377.             goto failed;
  378.         }

  379.         if (shm_zone[i].init(&shm_zone[i], data) != NGX_OK) {
  380.             goto failed;
  381.         }

  382.     shm_zone_found:

  383.         continue;
  384.     }


  385.     /* handle the listening sockets */

  386.     if (old_cycle->listening.nelts) {
  387.         ls = old_cycle->listening.elts;
  388.         for (i = 0; i < old_cycle->listening.nelts; i++) {
  389.             ls[i].remain = 0;
  390.         }

  391.         nls = cycle->listening.elts;
  392.         for (n = 0; n < cycle->listening.nelts; n++) {

  393.             for (i = 0; i < old_cycle->listening.nelts; i++) {
  394.                 if (ls[i].ignore) {
  395.                     continue;
  396.                 }

  397.                 if (ls[i].remain) {
  398.                     continue;
  399.                 }

  400.                 if (ls[i].type != nls[n].type) {
  401.                     continue;
  402.                 }

  403.                 if (ngx_cmp_sockaddr(nls[n].sockaddr, nls[n].socklen,
  404.                                      ls[i].sockaddr, ls[i].socklen, 1)
  405.                     == NGX_OK)
  406.                 {
  407.                     nls[n].fd = ls[i].fd;
  408.                     nls[n].inherited = ls[i].inherited;
  409.                     nls[n].previous = &ls[i];
  410.                     ls[i].remain = 1;

  411.                     if (ls[i].backlog != nls[n].backlog) {
  412.                         nls[n].listen = 1;
  413.                     }

  414. #if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER)

  415.                     /*
  416.                      * FreeBSD, except the most recent versions,
  417.                      * could not remove accept filter
  418.                      */
  419.                     nls[n].deferred_accept = ls[i].deferred_accept;

  420.                     if (ls[i].accept_filter && nls[n].accept_filter) {
  421.                         if (ngx_strcmp(ls[i].accept_filter,
  422.                                        nls[n].accept_filter)
  423.                             != 0)
  424.                         {
  425.                             nls[n].delete_deferred = 1;
  426.                             nls[n].add_deferred = 1;
  427.                         }

  428.                     } else if (ls[i].accept_filter) {
  429.                         nls[n].delete_deferred = 1;

  430.                     } else if (nls[n].accept_filter) {
  431.                         nls[n].add_deferred = 1;
  432.                     }
  433. #endif

  434. #if (NGX_HAVE_DEFERRED_ACCEPT && defined TCP_DEFER_ACCEPT)

  435.                     if (ls[i].deferred_accept && !nls[n].deferred_accept) {
  436.                         nls[n].delete_deferred = 1;

  437.                     } else if (ls[i].deferred_accept != nls[n].deferred_accept)
  438.                     {
  439.                         nls[n].add_deferred = 1;
  440.                     }
  441. #endif

  442. #if (NGX_HAVE_REUSEPORT)
  443.                     if (nls[n].reuseport && !ls[i].reuseport) {
  444.                         nls[n].add_reuseport = 1;
  445.                     }
  446. #endif

  447.                     break;
  448.                 }
  449.             }

  450.             if (nls[n].fd == (ngx_socket_t) -1) {
  451.                 nls[n].open = 1;
  452. #if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER)
  453.                 if (nls[n].accept_filter) {
  454.                     nls[n].add_deferred = 1;
  455.                 }
  456. #endif
  457. #if (NGX_HAVE_DEFERRED_ACCEPT && defined TCP_DEFER_ACCEPT)
  458.                 if (nls[n].deferred_accept) {
  459.                     nls[n].add_deferred = 1;
  460.                 }
  461. #endif
  462.             }
  463.         }

  464.     } else {
  465.         ls = cycle->listening.elts;
  466.         for (i = 0; i < cycle->listening.nelts; i++) {
  467.             ls[i].open = 1;
  468. #if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER)
  469.             if (ls[i].accept_filter) {
  470.                 ls[i].add_deferred = 1;
  471.             }
  472. #endif
  473. #if (NGX_HAVE_DEFERRED_ACCEPT && defined TCP_DEFER_ACCEPT)
  474.             if (ls[i].deferred_accept) {
  475.                 ls[i].add_deferred = 1;
  476.             }
  477. #endif
  478.         }
  479.     }

  480.     if (ngx_open_listening_sockets(cycle) != NGX_OK) {
  481.         goto failed;
  482.     }

  483.     if (!ngx_test_config) {
  484.         ngx_configure_listening_sockets(cycle);
  485.     }


  486.     /* commit the new cycle configuration */

  487.     if (!ngx_use_stderr) {
  488.         (void) ngx_log_redirect_stderr(cycle);
  489.     }

  490.     pool->log = cycle->log;

  491.     if (ngx_init_modules(cycle) != NGX_OK) {
  492.         /* fatal */
  493.         exit(1);
  494.     }


  495.     /* close and delete stuff that lefts from an old cycle */

  496.     /* free the unnecessary shared memory */

  497.     opart = &old_cycle->shared_memory.part;
  498.     oshm_zone = opart->elts;

  499.     for (i = 0; /* void */ ; i++) {

  500.         if (i >= opart->nelts) {
  501.             if (opart->next == NULL) {
  502.                 goto old_shm_zone_done;
  503.             }
  504.             opart = opart->next;
  505.             oshm_zone = opart->elts;
  506.             i = 0;
  507.         }

  508.         part = &cycle->shared_memory.part;
  509.         shm_zone = part->elts;

  510.         for (n = 0; /* void */ ; n++) {

  511.             if (n >= part->nelts) {
  512.                 if (part->next == NULL) {
  513.                     break;
  514.                 }
  515.                 part = part->next;
  516.                 shm_zone = part->elts;
  517.                 n = 0;
  518.             }

  519.             if (oshm_zone[i].shm.name.len != shm_zone[n].shm.name.len) {
  520.                 continue;
  521.             }

  522.             if (ngx_strncmp(oshm_zone[i].shm.name.data,
  523.                             shm_zone[n].shm.name.data,
  524.                             oshm_zone[i].shm.name.len)
  525.                 != 0)
  526.             {
  527.                 continue;
  528.             }

  529.             if (oshm_zone[i].tag == shm_zone[n].tag
  530.                 && oshm_zone[i].shm.size == shm_zone[n].shm.size
  531.                 && !oshm_zone[i].noreuse)
  532.             {
  533.                 goto live_shm_zone;
  534.             }

  535.             break;
  536.         }

  537.         ngx_shm_free(&oshm_zone[i].shm);

  538.     live_shm_zone:

  539.         continue;
  540.     }

  541. old_shm_zone_done:


  542.     /* close the unnecessary listening sockets */

  543.     ls = old_cycle->listening.elts;
  544.     for (i = 0; i < old_cycle->listening.nelts; i++) {

  545.         if (ls[i].remain || ls[i].fd == (ngx_socket_t) -1) {
  546.             continue;
  547.         }

  548.         if (ngx_close_socket(ls[i].fd) == -1) {
  549.             ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
  550.                           ngx_close_socket_n " listening socket on %V failed",
  551.                           &ls[i].addr_text);
  552.         }

  553. #if (NGX_HAVE_UNIX_DOMAIN)

  554.         if (ls[i].sockaddr->sa_family == AF_UNIX) {
  555.             u_char  *name;

  556.             name = ls[i].addr_text.data + sizeof("unix:") - 1;

  557.             ngx_log_error(NGX_LOG_WARN, cycle->log, 0,
  558.                           "deleting socket %s", name);

  559.             if (ngx_delete_file(name) == NGX_FILE_ERROR) {
  560.                 ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_socket_errno,
  561.                               ngx_delete_file_n " %s failed", name);
  562.             }
  563.         }

  564. #endif
  565.     }


  566.     /* close the unnecessary open files */

  567.     part = &old_cycle->open_files.part;
  568.     file = part->elts;

  569.     for (i = 0; /* void */ ; i++) {

  570.         if (i >= part->nelts) {
  571.             if (part->next == NULL) {
  572.                 break;
  573.             }
  574.             part = part->next;
  575.             file = part->elts;
  576.             i = 0;
  577.         }

  578.         if (file[i].fd == NGX_INVALID_FILE || file[i].fd == ngx_stderr) {
  579.             continue;
  580.         }

  581.         if (ngx_close_file(file[i].fd) == NGX_FILE_ERROR) {
  582.             ngx_log_error(NGX_LOG_EMERG, log, ngx_errno,
  583.                           ngx_close_file_n " \"%s\" failed",
  584.                           file[i].name.data);
  585.         }
  586.     }

  587.     ngx_destroy_pool(conf.temp_pool);

  588.     if (ngx_process == NGX_PROCESS_MASTER || ngx_is_init_cycle(old_cycle)) {

  589.         ngx_destroy_pool(old_cycle->pool);
  590.         cycle->old_cycle = NULL;

  591.         return cycle;
  592.     }


  593.     if (ngx_temp_pool == NULL) {
  594.         ngx_temp_pool = ngx_create_pool(128, cycle->log);
  595.         if (ngx_temp_pool == NULL) {
  596.             ngx_log_error(NGX_LOG_EMERG, cycle->log, 0,
  597.                           "could not create ngx_temp_pool");
  598.             exit(1);
  599.         }

  600.         n = 10;

  601.         if (ngx_array_init(&ngx_old_cycles, ngx_temp_pool, n,
  602.                            sizeof(ngx_cycle_t *))
  603.             != NGX_OK)
  604.         {
  605.             exit(1);
  606.         }

  607.         ngx_memzero(ngx_old_cycles.elts, n * sizeof(ngx_cycle_t *));

  608.         ngx_cleaner_event.handler = ngx_clean_old_cycles;
  609.         ngx_cleaner_event.log = cycle->log;
  610.         ngx_cleaner_event.data = &dumb;
  611.         dumb.fd = (ngx_socket_t) -1;
  612.     }

  613.     ngx_temp_pool->log = cycle->log;

  614.     old = ngx_array_push(&ngx_old_cycles);
  615.     if (old == NULL) {
  616.         exit(1);
  617.     }
  618.     *old = old_cycle;

  619.     if (!ngx_cleaner_event.timer_set) {
  620.         ngx_add_timer(&ngx_cleaner_event, 30000);
  621.         ngx_cleaner_event.timer_set = 1;
  622.     }

  623.     return cycle;


  624. failed:

  625.     if (!ngx_is_init_cycle(old_cycle)) {
  626.         old_ccf = (ngx_core_conf_t *) ngx_get_conf(old_cycle->conf_ctx,
  627.                                                    ngx_core_module);
  628.         if (old_ccf->environment) {
  629.             environ = old_ccf->environment;
  630.         }
  631.     }

  632.     /* rollback the new cycle configuration */

  633.     part = &cycle->open_files.part;
  634.     file = part->elts;

  635.     for (i = 0; /* void */ ; i++) {

  636.         if (i >= part->nelts) {
  637.             if (part->next == NULL) {
  638.                 break;
  639.             }
  640.             part = part->next;
  641.             file = part->elts;
  642.             i = 0;
  643.         }

  644.         if (file[i].fd == NGX_INVALID_FILE || file[i].fd == ngx_stderr) {
  645.             continue;
  646.         }

  647.         if (ngx_close_file(file[i].fd) == NGX_FILE_ERROR) {
  648.             ngx_log_error(NGX_LOG_EMERG, log, ngx_errno,
  649.                           ngx_close_file_n " \"%s\" failed",
  650.                           file[i].name.data);
  651.         }
  652.     }

  653.     /* free the newly created shared memory */

  654.     part = &cycle->shared_memory.part;
  655.     shm_zone = part->elts;

  656.     for (i = 0; /* void */ ; i++) {

  657.         if (i >= part->nelts) {
  658.             if (part->next == NULL) {
  659.                 break;
  660.             }
  661.             part = part->next;
  662.             shm_zone = part->elts;
  663.             i = 0;
  664.         }

  665.         if (shm_zone[i].shm.addr == NULL) {
  666.             continue;
  667.         }

  668.         opart = &old_cycle->shared_memory.part;
  669.         oshm_zone = opart->elts;

  670.         for (n = 0; /* void */ ; n++) {

  671.             if (n >= opart->nelts) {
  672.                 if (opart->next == NULL) {
  673.                     break;
  674.                 }
  675.                 opart = opart->next;
  676.                 oshm_zone = opart->elts;
  677.                 n = 0;
  678.             }

  679.             if (shm_zone[i].shm.name.len != oshm_zone[n].shm.name.len) {
  680.                 continue;
  681.             }

  682.             if (ngx_strncmp(shm_zone[i].shm.name.data,
  683.                             oshm_zone[n].shm.name.data,
  684.                             shm_zone[i].shm.name.len)
  685.                 != 0)
  686.             {
  687.                 continue;
  688.             }

  689.             if (shm_zone[i].tag == oshm_zone[n].tag
  690.                 && shm_zone[i].shm.size == oshm_zone[n].shm.size
  691.                 && !shm_zone[i].noreuse)
  692.             {
  693.                 goto old_shm_zone_found;
  694.             }

  695.             break;
  696.         }

  697.         ngx_shm_free(&shm_zone[i].shm);

  698.     old_shm_zone_found:

  699.         continue;
  700.     }

  701.     if (ngx_test_config) {
  702.         ngx_destroy_cycle_pools(&conf);
  703.         return NULL;
  704.     }

  705.     ls = cycle->listening.elts;
  706.     for (i = 0; i < cycle->listening.nelts; i++) {
  707.         if (ls[i].fd == (ngx_socket_t) -1 || !ls[i].open) {
  708.             continue;
  709.         }

  710.         if (ngx_close_socket(ls[i].fd) == -1) {
  711.             ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
  712.                           ngx_close_socket_n " %V failed",
  713.                           &ls[i].addr_text);
  714.         }
  715.     }

  716.     ngx_destroy_cycle_pools(&conf);

  717.     return NULL;
  718. }


  719. static void
  720. ngx_destroy_cycle_pools(ngx_conf_t *conf)
  721. {
  722.     ngx_destroy_pool(conf->temp_pool);
  723.     ngx_destroy_pool(conf->pool);
  724. }


  725. static ngx_int_t
  726. ngx_init_zone_pool(ngx_cycle_t *cycle, ngx_shm_zone_t *zn)
  727. {
  728.     u_char           *file;
  729.     ngx_slab_pool_t  *sp;

  730.     sp = (ngx_slab_pool_t *) zn->shm.addr;

  731.     if (zn->shm.exists) {

  732.         if (sp == sp->addr) {
  733.             return NGX_OK;
  734.         }

  735. #if (NGX_WIN32)

  736.         /* remap at the required address */

  737.         if (ngx_shm_remap(&zn->shm, sp->addr) != NGX_OK) {
  738.             return NGX_ERROR;
  739.         }

  740.         sp = (ngx_slab_pool_t *) zn->shm.addr;

  741.         if (sp == sp->addr) {
  742.             return NGX_OK;
  743.         }

  744. #endif

  745.         ngx_log_error(NGX_LOG_EMERG, cycle->log, 0,
  746.                       "shared zone \"%V\" has no equal addresses: %p vs %p",
  747.                       &zn->shm.name, sp->addr, sp);
  748.         return NGX_ERROR;
  749.     }

  750.     sp->end = zn->shm.addr + zn->shm.size;
  751.     sp->min_shift = 3;
  752.     sp->addr = zn->shm.addr;

  753. #if (NGX_HAVE_ATOMIC_OPS)

  754.     file = NULL;

  755. #else

  756.     file = ngx_pnalloc(cycle->pool,
  757.                        cycle->lock_file.len + zn->shm.name.len + 1);
  758.     if (file == NULL) {
  759.         return NGX_ERROR;
  760.     }

  761.     (void) ngx_sprintf(file, "%V%V%Z", &cycle->lock_file, &zn->shm.name);

  762. #endif

  763.     if (ngx_shmtx_create(&sp->mutex, &sp->lock, file) != NGX_OK) {
  764.         return NGX_ERROR;
  765.     }

  766.     ngx_slab_init(sp);

  767.     return NGX_OK;
  768. }


  769. ngx_int_t
  770. ngx_create_pidfile(ngx_str_t *name, ngx_log_t *log)
  771. {
  772.     size_t      len;
  773.     ngx_int_t   rc;
  774.     ngx_uint_t  create;
  775.     ngx_file_t  file;
  776.     u_char      pid[NGX_INT64_LEN + 2];

  777.     if (ngx_process > NGX_PROCESS_MASTER) {
  778.         return NGX_OK;
  779.     }

  780.     ngx_memzero(&file, sizeof(ngx_file_t));

  781.     file.name = *name;
  782.     file.log = log;

  783.     create = ngx_test_config ? NGX_FILE_CREATE_OR_OPEN : NGX_FILE_TRUNCATE;

  784.     file.fd = ngx_open_file(file.name.data, NGX_FILE_RDWR,
  785.                             create, NGX_FILE_DEFAULT_ACCESS);

  786.     if (file.fd == NGX_INVALID_FILE) {
  787.         ngx_log_error(NGX_LOG_EMERG, log, ngx_errno,
  788.                       ngx_open_file_n " \"%s\" failed", file.name.data);
  789.         return NGX_ERROR;
  790.     }

  791.     rc = NGX_OK;

  792.     if (!ngx_test_config) {
  793.         len = ngx_snprintf(pid, NGX_INT64_LEN + 2, "%P%N", ngx_pid) - pid;

  794.         if (ngx_write_file(&file, pid, len, 0) == NGX_ERROR) {
  795.             rc = NGX_ERROR;
  796.         }
  797.     }

  798.     if (ngx_close_file(file.fd) == NGX_FILE_ERROR) {
  799.         ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
  800.                       ngx_close_file_n " \"%s\" failed", file.name.data);
  801.     }

  802.     return rc;
  803. }


  804. void
  805. ngx_delete_pidfile(ngx_cycle_t *cycle)
  806. {
  807.     u_char           *name;
  808.     ngx_core_conf_t  *ccf;

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

  810.     name = ngx_new_binary ? ccf->oldpid.data : ccf->pid.data;

  811.     if (ngx_delete_file(name) == NGX_FILE_ERROR) {
  812.         ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
  813.                       ngx_delete_file_n " \"%s\" failed", name);
  814.     }
  815. }


  816. ngx_int_t
  817. ngx_signal_process(ngx_cycle_t *cycle, char *sig)
  818. {
  819.     ssize_t           n;
  820.     ngx_pid_t         pid;
  821.     ngx_file_t        file;
  822.     ngx_core_conf_t  *ccf;
  823.     u_char            buf[NGX_INT64_LEN + 2];

  824.     ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "signal process started");

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

  826.     ngx_memzero(&file, sizeof(ngx_file_t));

  827.     file.name = ccf->pid;
  828.     file.log = cycle->log;

  829.     file.fd = ngx_open_file(file.name.data, NGX_FILE_RDONLY,
  830.                             NGX_FILE_OPEN, NGX_FILE_DEFAULT_ACCESS);

  831.     if (file.fd == NGX_INVALID_FILE) {
  832.         ngx_log_error(NGX_LOG_ERR, cycle->log, ngx_errno,
  833.                       ngx_open_file_n " \"%s\" failed", file.name.data);
  834.         return 1;
  835.     }

  836.     n = ngx_read_file(&file, buf, NGX_INT64_LEN + 2, 0);

  837.     if (ngx_close_file(file.fd) == NGX_FILE_ERROR) {
  838.         ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
  839.                       ngx_close_file_n " \"%s\" failed", file.name.data);
  840.     }

  841.     if (n == NGX_ERROR) {
  842.         return 1;
  843.     }

  844.     while (n-- && (buf[n] == CR || buf[n] == LF)) { /* void */ }

  845.     pid = ngx_atoi(buf, ++n);

  846.     if (pid == (ngx_pid_t) NGX_ERROR) {
  847.         ngx_log_error(NGX_LOG_ERR, cycle->log, 0,
  848.                       "invalid PID number \"%*s\" in \"%s\"",
  849.                       n, buf, file.name.data);
  850.         return 1;
  851.     }

  852.     return ngx_os_signal_process(cycle, sig, pid);

  853. }


  854. static ngx_int_t
  855. ngx_test_lockfile(u_char *file, ngx_log_t *log)
  856. {
  857. #if !(NGX_HAVE_ATOMIC_OPS)
  858.     ngx_fd_t  fd;

  859.     fd = ngx_open_file(file, NGX_FILE_RDWR, NGX_FILE_CREATE_OR_OPEN,
  860.                        NGX_FILE_DEFAULT_ACCESS);

  861.     if (fd == NGX_INVALID_FILE) {
  862.         ngx_log_error(NGX_LOG_EMERG, log, ngx_errno,
  863.                       ngx_open_file_n " \"%s\" failed", file);
  864.         return NGX_ERROR;
  865.     }

  866.     if (ngx_close_file(fd) == NGX_FILE_ERROR) {
  867.         ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
  868.                       ngx_close_file_n " \"%s\" failed", file);
  869.     }

  870.     if (ngx_delete_file(file) == NGX_FILE_ERROR) {
  871.         ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
  872.                       ngx_delete_file_n " \"%s\" failed", file);
  873.     }

  874. #endif

  875.     return NGX_OK;
  876. }


  877. void
  878. ngx_reopen_files(ngx_cycle_t *cycle, ngx_uid_t user)
  879. {
  880.     ngx_fd_t          fd;
  881.     ngx_uint_t        i;
  882.     ngx_list_part_t  *part;
  883.     ngx_open_file_t  *file;

  884.     part = &cycle->open_files.part;
  885.     file = part->elts;

  886.     for (i = 0; /* void */ ; i++) {

  887.         if (i >= part->nelts) {
  888.             if (part->next == NULL) {
  889.                 break;
  890.             }
  891.             part = part->next;
  892.             file = part->elts;
  893.             i = 0;
  894.         }

  895.         if (file[i].name.len == 0) {
  896.             continue;
  897.         }

  898.         if (file[i].flush) {
  899.             file[i].flush(&file[i], cycle->log);
  900.         }

  901.         fd = ngx_open_file(file[i].name.data, NGX_FILE_APPEND,
  902.                            NGX_FILE_CREATE_OR_OPEN, NGX_FILE_DEFAULT_ACCESS);

  903.         ngx_log_debug3(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
  904.                        "reopen file \"%s\", old:%d new:%d",
  905.                        file[i].name.data, file[i].fd, fd);

  906.         if (fd == NGX_INVALID_FILE) {
  907.             ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
  908.                           ngx_open_file_n " \"%s\" failed", file[i].name.data);
  909.             continue;
  910.         }

  911. #if !(NGX_WIN32)
  912.         if (user != (ngx_uid_t) NGX_CONF_UNSET_UINT) {
  913.             ngx_file_info_t  fi;

  914.             if (ngx_file_info(file[i].name.data, &fi) == NGX_FILE_ERROR) {
  915.                 ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
  916.                               ngx_file_info_n " \"%s\" failed",
  917.                               file[i].name.data);

  918.                 if (ngx_close_file(fd) == NGX_FILE_ERROR) {
  919.                     ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
  920.                                   ngx_close_file_n " \"%s\" failed",
  921.                                   file[i].name.data);
  922.                 }

  923.                 continue;
  924.             }

  925.             if (fi.st_uid != user) {
  926.                 if (chown((const char *) file[i].name.data, user, -1) == -1) {
  927.                     ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
  928.                                   "chown(\"%s\", %d) failed",
  929.                                   file[i].name.data, user);

  930.                     if (ngx_close_file(fd) == NGX_FILE_ERROR) {
  931.                         ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
  932.                                       ngx_close_file_n " \"%s\" failed",
  933.                                       file[i].name.data);
  934.                     }

  935.                     continue;
  936.                 }
  937.             }

  938.             if ((fi.st_mode & (S_IRUSR|S_IWUSR)) != (S_IRUSR|S_IWUSR)) {

  939.                 fi.st_mode |= (S_IRUSR|S_IWUSR);

  940.                 if (chmod((const char *) file[i].name.data, fi.st_mode) == -1) {
  941.                     ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
  942.                                   "chmod() \"%s\" failed", file[i].name.data);

  943.                     if (ngx_close_file(fd) == NGX_FILE_ERROR) {
  944.                         ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
  945.                                       ngx_close_file_n " \"%s\" failed",
  946.                                       file[i].name.data);
  947.                     }

  948.                     continue;
  949.                 }
  950.             }
  951.         }

  952.         if (fcntl(fd, F_SETFD, FD_CLOEXEC) == -1) {
  953.             ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
  954.                           "fcntl(FD_CLOEXEC) \"%s\" failed",
  955.                           file[i].name.data);

  956.             if (ngx_close_file(fd) == NGX_FILE_ERROR) {
  957.                 ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
  958.                               ngx_close_file_n " \"%s\" failed",
  959.                               file[i].name.data);
  960.             }

  961.             continue;
  962.         }
  963. #endif

  964.         if (ngx_close_file(file[i].fd) == NGX_FILE_ERROR) {
  965.             ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
  966.                           ngx_close_file_n " \"%s\" failed",
  967.                           file[i].name.data);
  968.         }

  969.         file[i].fd = fd;
  970.     }

  971.     (void) ngx_log_redirect_stderr(cycle);
  972. }


  973. ngx_shm_zone_t *
  974. ngx_shared_memory_add(ngx_conf_t *cf, ngx_str_t *name, size_t size, void *tag)
  975. {
  976.     ngx_uint_t        i;
  977.     ngx_shm_zone_t   *shm_zone;
  978.     ngx_list_part_t  *part;

  979.     part = &cf->cycle->shared_memory.part;
  980.     shm_zone = part->elts;

  981.     for (i = 0; /* void */ ; i++) {

  982.         if (i >= part->nelts) {
  983.             if (part->next == NULL) {
  984.                 break;
  985.             }
  986.             part = part->next;
  987.             shm_zone = part->elts;
  988.             i = 0;
  989.         }

  990.         if (name->len != shm_zone[i].shm.name.len) {
  991.             continue;
  992.         }

  993.         if (ngx_strncmp(name->data, shm_zone[i].shm.name.data, name->len)
  994.             != 0)
  995.         {
  996.             continue;
  997.         }

  998.         if (tag != shm_zone[i].tag) {
  999.             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  1000.                             "the shared memory zone \"%V\" is "
  1001.                             "already declared for a different use",
  1002.                             &shm_zone[i].shm.name);
  1003.             return NULL;
  1004.         }

  1005.         if (shm_zone[i].shm.size == 0) {
  1006.             shm_zone[i].shm.size = size;
  1007.         }

  1008.         if (size && size != shm_zone[i].shm.size) {
  1009.             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  1010.                             "the size %uz of shared memory zone \"%V\" "
  1011.                             "conflicts with already declared size %uz",
  1012.                             size, &shm_zone[i].shm.name, shm_zone[i].shm.size);
  1013.             return NULL;
  1014.         }

  1015.         return &shm_zone[i];
  1016.     }

  1017.     shm_zone = ngx_list_push(&cf->cycle->shared_memory);

  1018.     if (shm_zone == NULL) {
  1019.         return NULL;
  1020.     }

  1021.     shm_zone->data = NULL;
  1022.     shm_zone->shm.log = cf->cycle->log;
  1023.     shm_zone->shm.addr = NULL;
  1024.     shm_zone->shm.size = size;
  1025.     shm_zone->shm.name = *name;
  1026.     shm_zone->shm.exists = 0;
  1027.     shm_zone->init = NULL;
  1028.     shm_zone->tag = tag;
  1029.     shm_zone->noreuse = 0;

  1030.     return shm_zone;
  1031. }


  1032. static void
  1033. ngx_clean_old_cycles(ngx_event_t *ev)
  1034. {
  1035.     ngx_uint_t     i, n, found, live;
  1036.     ngx_log_t     *log;
  1037.     ngx_cycle_t  **cycle;

  1038.     log = ngx_cycle->log;
  1039.     ngx_temp_pool->log = log;

  1040.     ngx_log_debug0(NGX_LOG_DEBUG_CORE, log, 0, "clean old cycles");

  1041.     live = 0;

  1042.     cycle = ngx_old_cycles.elts;
  1043.     for (i = 0; i < ngx_old_cycles.nelts; i++) {

  1044.         if (cycle[i] == NULL) {
  1045.             continue;
  1046.         }

  1047.         found = 0;

  1048.         for (n = 0; n < cycle[i]->connection_n; n++) {
  1049.             if (cycle[i]->connections[n].fd != (ngx_socket_t) -1) {
  1050.                 found = 1;

  1051.                 ngx_log_debug1(NGX_LOG_DEBUG_CORE, log, 0, "live fd:%ui", n);

  1052.                 break;
  1053.             }
  1054.         }

  1055.         if (found) {
  1056.             live = 1;
  1057.             continue;
  1058.         }

  1059.         ngx_log_debug1(NGX_LOG_DEBUG_CORE, log, 0, "clean old cycle: %ui", i);

  1060.         ngx_destroy_pool(cycle[i]->pool);
  1061.         cycle[i] = NULL;
  1062.     }

  1063.     ngx_log_debug1(NGX_LOG_DEBUG_CORE, log, 0, "old cycles status: %ui", live);

  1064.     if (live) {
  1065.         ngx_add_timer(ev, 30000);

  1066.     } else {
  1067.         ngx_destroy_pool(ngx_temp_pool);
  1068.         ngx_temp_pool = NULL;
  1069.         ngx_old_cycles.nelts = 0;
  1070.     }
  1071. }


  1072. void
  1073. ngx_set_shutdown_timer(ngx_cycle_t *cycle)
  1074. {
  1075.     ngx_core_conf_t  *ccf;

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

  1077.     if (ccf->shutdown_timeout) {
  1078.         ngx_shutdown_event.handler = ngx_shutdown_timer_handler;
  1079.         ngx_shutdown_event.data = cycle;
  1080.         ngx_shutdown_event.log = cycle->log;
  1081.         ngx_shutdown_event.cancelable = 1;

  1082.         ngx_add_timer(&ngx_shutdown_event, ccf->shutdown_timeout);
  1083.     }
  1084. }


  1085. static void
  1086. ngx_shutdown_timer_handler(ngx_event_t *ev)
  1087. {
  1088.     ngx_uint_t         i;
  1089.     ngx_cycle_t       *cycle;
  1090.     ngx_connection_t  *c;

  1091.     cycle = ev->data;

  1092.     c = cycle->connections;

  1093.     for (i = 0; i < cycle->connection_n; i++) {

  1094.         if (c[i].fd == (ngx_socket_t) -1
  1095.             || c[i].read == NULL
  1096.             || c[i].read->accept
  1097.             || c[i].read->channel
  1098.             || c[i].read->resolver)
  1099.         {
  1100.             continue;
  1101.         }

  1102.         ngx_log_debug1(NGX_LOG_DEBUG_CORE, ev->log, 0,
  1103.                        "*%uA shutdown timeout", c[i].number);

  1104.         c[i].close = 1;
  1105.         c[i].error = 1;

  1106.         c[i].read->handler(c[i].read);
  1107.     }
  1108. }