• nginx main函数


    源代码:

    int ngx_cdecl
    main(int argc, char *const *argv)
    {
        ngx_int_t         i;
        ngx_log_t        *log;
        ngx_cycle_t      *cycle, init_cycle;
        ngx_core_conf_t  *ccf;
    
        ngx_debug_init();
    
        if (ngx_strerror_init() != NGX_OK) {
            return 1;
        }
    
        if (ngx_get_options(argc, argv) != NGX_OK) {
            return 1;
        }
    
        if (ngx_show_version) {
            ngx_write_stderr("nginx version: " NGINX_VER NGX_LINEFEED);
    
            if (ngx_show_help) {
                ngx_write_stderr(
                    "Usage: nginx [-?hvVtq] [-s signal] [-c filename] "
                                 "[-p prefix] [-g directives]" NGX_LINEFEED
                                 NGX_LINEFEED
                    "Options:" NGX_LINEFEED
                    "  -?,-h         : this help" NGX_LINEFEED
                    "  -v            : show version and exit" NGX_LINEFEED
                    "  -V            : show version and configure options then exit"
                                       NGX_LINEFEED
                    "  -t            : test configuration and exit" NGX_LINEFEED
                    "  -q            : suppress non-error messages "
                                       "during configuration testing" NGX_LINEFEED
                    "  -s signal     : send signal to a master process: "
                                       "stop, quit, reopen, reload" NGX_LINEFEED
    
    #ifdef NGX_PREFIX
                    "  -p prefix     : set prefix path (default: "
                                       NGX_PREFIX ")" NGX_LINEFEED
    #else
                    "  -p prefix     : set prefix path (default: NONE)" NGX_LINEFEED
    #endif
                    "  -c filename   : set configuration file (default: "
                                       NGX_CONF_PATH ")" NGX_LINEFEED
                    "  -g directives : set global directives out of configuration "
                                       "file" NGX_LINEFEED NGX_LINEFEED
                    );
            }
    
            if (ngx_show_configure) {
                ngx_write_stderr(
    #ifdef NGX_COMPILER
                    "built by " NGX_COMPILER NGX_LINEFEED
    #endif
    #if (NGX_SSL)
    #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
                    "TLS SNI support enabled" NGX_LINEFEED
    #else
                    "TLS SNI support disabled" NGX_LINEFEED
    #endif
    #endif
                    "configure arguments:" NGX_CONFIGURE NGX_LINEFEED);
            }
    
            if (!ngx_test_config) {
                return 0;
            }
        }
    
        /* TODO */ ngx_max_sockets = -1;
    
        ngx_time_init();
    
    #if (NGX_PCRE)
        ngx_regex_init();
    #endif
    
        ngx_pid = ngx_getpid();
    
        log = ngx_log_init(ngx_prefix);
        if (log == NULL) {
            return 1;
        }
    
        /* STUB */
    #if (NGX_OPENSSL)
        ngx_ssl_init(log);
    #endif
    
        /*
         * init_cycle->log is required for signal handlers and
         * ngx_process_options()
         */
    
        ngx_memzero(&init_cycle, sizeof(ngx_cycle_t));
        init_cycle.log = log;
        ngx_cycle = &init_cycle;
    
        init_cycle.pool = ngx_create_pool(1024, log);
        if (init_cycle.pool == NULL) {
            return 1;
        }
    
        if (ngx_save_argv(&init_cycle, argc, argv) != NGX_OK) {
            return 1;
        }
    
        if (ngx_process_options(&init_cycle) != NGX_OK) {
            return 1;
     }
    
        if (ngx_os_init(log) != NGX_OK) {
            return 1;
        }
    
        /*
         * ngx_crc32_table_init() requires ngx_cacheline_size set in ngx_os_init()
         */
    
        if (ngx_crc32_table_init() != NGX_OK) {
            return 1;
        }
    
        if (ngx_add_inherited_sockets(&init_cycle) != NGX_OK) {
            return 1;
        }
    
        ngx_max_module = 0;
        for (i = 0; ngx_modules[i]; i++) {
            ngx_modules[i]->index = ngx_max_module++;
        }
    
        cycle = ngx_init_cycle(&init_cycle);
        if (cycle == NULL) {
            if (ngx_test_config) {
                ngx_log_stderr(0, "configuration file %s test failed",
                               init_cycle.conf_file.data);
            }
    
            return 1;
        }
    
        if (ngx_test_config) {
            if (!ngx_quiet_mode) {
                ngx_log_stderr(0, "configuration file %s test is successful",
                               cycle->conf_file.data);
            }
    
            return 0;
        }
    
        if (ngx_signal) {
            return ngx_signal_process(cycle, ngx_signal);
        }
    
        ngx_os_status(cycle->log);
    
        ngx_cycle = cycle;
    
        ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);
    
        if (ccf->master && ngx_process == NGX_PROCESS_SINGLE) {
            ngx_process = NGX_PROCESS_MASTER;
        }
    
    #if !(NGX_WIN32)
    
        if (ngx_init_signals(cycle->log) != NGX_OK) {
            return 1;
        }
    
        if (!ngx_inherited && ccf->daemon) {
            if (ngx_daemon(cycle->log) != NGX_OK) {
                return 1;
            }
    
            ngx_daemonized = 1;
        }
    
        if (ngx_inherited) {
            ngx_daemonized = 1;
        }
    
    #endif
    
        if (ngx_create_pidfile(&ccf->pid, cycle->log) != NGX_OK) {
            return 1;
        }
    
        if (cycle->log->file->fd != ngx_stderr) {
    
            if (ngx_set_stderr(cycle->log->file->fd) == NGX_FILE_ERROR) {
                ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
                              ngx_set_stderr_n " failed");
                return 1;
            }
        }
    
        if (log->file->fd != ngx_stderr) {
            if (ngx_close_file(log->file->fd) == NGX_FILE_ERROR) {
                ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
                              ngx_close_file_n " built-in log failed");
            }
        }
    
        ngx_use_stderr = 0;
    
        if (ngx_process == NGX_PROCESS_SINGLE) {
            ngx_single_process_cycle(cycle);
    
        } else {
            ngx_master_process_cycle(cycle);
        }
    
        return 0;
    }
    ngx_debug_init();

    ngx_linux_config.h文件中定义:

    #define NGX_HAVE_OS_SPECIFIC_INIT 1 

    #define ngx_debug_init()

    其实什么也没做。

    ngx_strerror_init();//初始化了*ngx_sys_errlist 这个全局静态变量,以供ngx_strerror使用
    static ngx_str_t  *ngx_sys_errlist;
    static ngx_str_t   ngx_unknown_error = ngx_string("Unknown error");
    
    
    u_char *
    ngx_strerror(ngx_err_t err, u_char *errstr, size_t size)
    {
        ngx_str_t  *msg;
    
        msg = ((ngx_uint_t) err < NGX_SYS_NERR) ? &ngx_sys_errlist[err]:
                                                  &ngx_unknown_error;
        size = ngx_min(size, msg->len);
    
        return ngx_cpymem(errstr, msg->data, size);
    }
    ngx_get_options(argc, argv);//设置命令行参数
    static ngx_int_t
    ngx_get_options(int argc, char *const *argv)
    {
        u_char     *p;
        ngx_int_t   i;
    
        for (i = 1; i < argc; i++) {
    
            p = (u_char *) argv[i];
    
            if (*p++ != '-') {
                ngx_log_stderr(0, "invalid option: "%s"", argv[i]);
                return NGX_ERROR;
            }
    
            while (*p) {
    
                switch (*p++) {
    
                case '?':
                case 'h':
                    ngx_show_version = 1;
                    ngx_show_help = 1;
                    break;
    
                case 'v':
                    ngx_show_version = 1;
                    break;
    
                case 'V':
                    ngx_show_version = 1;
                    ngx_show_configure = 1;
                    break;
    
                case 't':
                    ngx_test_config = 1;
                    break;
    
                case 'q':
                    ngx_quiet_mode = 1;
                    break;
    
                case 'p':
                    if (*p) {
                        ngx_prefix = p;
                        goto next;
                    }
    
                    if (argv[++i]) {
                        ngx_prefix = (u_char *) argv[i];
                        goto next;
                    }
    
                    ngx_log_stderr(0, "option "-p" requires directory name");
                    return NGX_ERROR;
    
                case 'c':
                    if (*p) {
                        ngx_conf_file = p;
                        goto next;
                    }
    
                    if (argv[++i]) {
                        ngx_conf_file = (u_char *) argv[i];
                        goto next;
                    }
    
                    ngx_log_stderr(0, "option "-c" requires file name");
                    return NGX_ERROR;
    
                case 'g':
                    if (*p) {
                        ngx_conf_params = p;
                        goto next;
                    }
    
                    if (argv[++i]) {
                        ngx_conf_params = (u_char *) argv[i];
                        goto next;
                    }
    
                    ngx_log_stderr(0, "option "-g" requires parameter");
                    return NGX_ERROR;
    
                    break;
    
                case 'V':
                    ngx_show_version = 1;
                    ngx_show_configure = 1;
                    break;
    
                case 't':
                    ngx_test_config = 1;
                    break;
    
                case 'q':
                    ngx_quiet_mode = 1;
                    break;
    
                case 'p':
                    if (*p) {
                        ngx_prefix = p;
                        goto next;
                    }
    
                    if (argv[++i]) {
                        ngx_prefix = (u_char *) argv[i];
                        goto next;
                    }
    
                    ngx_log_stderr(0, "option "-p" requires directory name");
                    return NGX_ERROR;
    
                case 'c':
                    if (*p) {
                        ngx_conf_file = p;
                        goto next;
                    }
    
                    if (argv[++i]) {
                        ngx_conf_file = (u_char *) argv[i];
                        goto next;
                    }
    
                    ngx_log_stderr(0, "option "-c" requires file name");
                    return NGX_ERROR;
    
                case 'g':
                    if (*p) {
                        ngx_conf_params = p;
                        goto next;
                    }
    
                    if (argv[++i]) {
                        ngx_conf_params = (u_char *) argv[i];
                        goto next;
                    }
    
                    ngx_log_stderr(0, "option "-g" requires parameter");
                    return NGX_ERROR;
    
                case 's':
                    if (*p) {
                    if (argv[++i]) {
                        ngx_conf_params = (u_char *) argv[i];
                        goto next;
                    }
    
                    ngx_log_stderr(0, "option "-g" requires parameter");
                    return NGX_ERROR;
    
                case 's':
                    if (*p) {
                        ngx_signal = (char *) p;
    
                    } else if (argv[++i]) {
                        ngx_signal = argv[i];
    
                    } else {
                        ngx_log_stderr(0, "option "-s" requires parameter");
                        return NGX_ERROR;
                    }
    
                    if (ngx_strcmp(ngx_signal, "stop") == 0
                        || ngx_strcmp(ngx_signal, "quit") == 0
                        || ngx_strcmp(ngx_signal, "reopen") == 0
                        || ngx_strcmp(ngx_signal, "reload") == 0)
                    {
                        ngx_process = NGX_PROCESS_SIGNALLER;
                        goto next;
                    }
    
                    ngx_log_stderr(0, "invalid option: "-s %s"", ngx_signal);
                    return NGX_ERROR;
    
                default:
                    ngx_log_stderr(0, "invalid option: "%c"", *(p - 1));
                    return NGX_ERROR;
                }
            }
    
        next:
    
            continue;
        }
    
        return NGX_OK;
    }
    ngx_max_sockets = -1
    ngx_time_init();
    void
    ngx_time_init(void)
    {
        ngx_cached_err_log_time.len = sizeof("1970/09/28 12:00:00") - 1;
        ngx_cached_http_time.len = sizeof("Mon, 28 Sep 1970 06:00:00 GMT") - 1;
        ngx_cached_http_log_time.len = sizeof("28/Sep/1970:12:00:00 +0600") - 1;
        ngx_cached_http_log_iso8601.len = sizeof("1970-09-28T12:00:00+06:00") - 1;
    
        ngx_cached_time = &cached_time[0];
    
        ngx_time_update();
    }
    log = ngx_log_init(ngx_prefix);
        ngx_log_file.fd = ngx_open_file(name, NGX_FILE_APPEND,
                                        NGX_FILE_CREATE_OR_OPEN,
                                        NGX_FILE_DEFAULT_ACCESS);
    
        if (ngx_log_file.fd == NGX_INVALID_FILE) {
            ngx_log_stderr(ngx_errno,
                           "[alert] could not open error log file: "
                           ngx_open_file_n " "%s" failed", name);
    #if (NGX_WIN32)
            ngx_event_log(ngx_errno,
                           "could not open error log file: "
                           ngx_open_file_n " "%s" failed", name);
    #endif
    
            ngx_log_file.fd = ngx_stderr;
        }
        if (ngx_os_init(log) != NGX_OK) {
            return 1;
        }
    ngx_int_t
    ngx_os_init(ngx_log_t *log)
    {
    ngx_uint_t n;
    
    #if (NGX_HAVE_OS_SPECIFIC_INIT)
    if (ngx_os_specific_init(log) != NGX_OK) {
    return NGX_ERROR;
    }
    #endif
    
    ngx_init_setproctitle(log);
    
    ngx_pagesize = getpagesize();
    ngx_cacheline_size = NGX_CPU_CACHE_LINE;
    
    for (n = ngx_pagesize; n >>= 1; ngx_pagesize_shift++) { /* void */ }
    
    #if (NGX_HAVE_SC_NPROCESSORS_ONLN)
    if (ngx_ncpu == 0) {
    ngx_ncpu = sysconf(_SC_NPROCESSORS_ONLN);
    }
    #endif
    
    if (ngx_ncpu < 1) {
    ngx_ncpu = 1;
    }
    
    ngx_cpuinfo();
    
    if (getrlimit(RLIMIT_NOFILE, &rlmt) == -1) {
    ngx_log_error(NGX_LOG_ALERT, log, errno,
    "getrlimit(RLIMIT_NOFILE) failed)");
    return NGX_ERROR;
    }
    
    ngx_max_sockets = (ngx_int_t) rlmt.rlim_cur; //最大打开文件数
    
    #if (NGX_HAVE_INHERITED_NONBLOCK || NGX_HAVE_ACCEPT4)
    ngx_inherited_nonblocking = 1;
    #else
    ngx_inherited_nonblocking = 0;
    #endif
    
    srandom(ngx_time());
    
    return NGX_OK;
    }
    cycle = ngx_init_cycle(&init_cycle);
    #ifndef NGX_CYCLE_POOL_SIZE
    #define NGX_CYCLE_POOL_SIZE     NGX_DEFAULT_POOL_SIZE
    #endif
    
    #define NGX_MAX_ALLOC_FROM_POOL  (ngx_pagesize - 1)
    
    #define NGX_DEFAULT_POOL_SIZE    (16 * 1024)    
    
    #define NGX_POOL_ALIGNMENT       16     
    #define NGX_MIN_POOL_SIZE                                                     
        ngx_align((sizeof(ngx_pool_t) + 2 * sizeof(ngx_pool_large_t)),            
                  NGX_POOL_ALIGNMENT)

    ngx_init_cycle()分析

    初始化过程如下。

    • 调用ngx_timezone_update()更新时区,调用ngx_time_update()更新时间
    • 创建大小为NGX_CYCLE_POOL_SIZE=16384B的内存池,并从中分配ngx_cycle_t结构
    • 简单初始化,如记录pool指针、log指针
    • 初始化配置前缀、前缀、配置文件、配置参数等字符串
    • 初始化pathes数组
    • 初始化open_files链表
    • 初始化shared_memory链表
    • 初始化listening数组
    • 初始化resuable_connections_queue队列
    • poolconf_ctx分配空间
    • 初始化hostname字符串
    • 调用core模块的create_conf()
    • 配置文件解析
    • 调用core模块的init_conf()
    • 遍历open_files链表中的每一个文件并打开
    • 创建共享内存并初始化(新旧shared_memory链表的比较,相同的共享内存保留,旧的不同的共享内存被释放,新的被创建)
    • (尝试5)遍历listening数组并打开所有侦听sockets(socket()->setsockopt()->bind()->listen())
    • 提交新的cycle配置,并调用所有模块的init_module(实际上只有ngx_event_core_module模块定义了该callback,即只有ngx_event_module_init()被调用)
    • 关闭或删除残留在old_cycle中的资源
      • 释放多余的共享内存
      • 关闭多余的侦听sockets
      • 关闭多余的打开文件
    struct ngx_listening_s {
        ngx_socket_t        fd;
    
        struct sockaddr    *sockaddr;
        socklen_t           socklen;    /* size of sockaddr */
        size_t              addr_text_max_len;
        ngx_str_t           addr_text;
    
        int                 type;
    
        int                 backlog;
        int                 rcvbuf;
        int                 sndbuf;
    #if (NGX_HAVE_KEEPALIVE_TUNABLE)
        int                 keepidle;
        int                 keepintvl;
        int                 keepcnt;
    #endif
    
        /* handler of accepted connection */
        ngx_connection_handler_pt   handler;
    
        void               *servers;  /* array of ngx_http_in_addr_t, for example */
    
        ngx_log_t           log;
        ngx_log_t          *logp;
    
        size_t              pool_size;
        /* should be here because of the AcceptEx() preread */
        size_t              post_accept_buffer_size;
        /* should be here because of the deferred accept */
        ngx_msec_t          post_accept_timeout;
        /* should be here because of the AcceptEx() preread */
        size_t              post_accept_buffer_size;
        size_t              post_accept_buffer_size;
        /* should be here because of the deferred accept */
        ngx_msec_t          post_accept_timeout;
    
        ngx_listening_t    *previous;
        ngx_connection_t   *connection;
    
        unsigned            open:1;
        unsigned            remain:1;
        unsigned            ignore:1;
    
        unsigned            bound:1;       /* already bound */
        unsigned            inherited:1;   /* inherited from previous process */
        unsigned            nonblocking_accept:1;
        unsigned            listen:1;
        unsigned            nonblocking:1;
        unsigned            shared:1;    /* shared between threads or processes */
        unsigned            addr_ntop:1;
    
    #if (NGX_HAVE_INET6 && defined IPV6_V6ONLY)
        unsigned            ipv6only:1;
    #endif
        unsigned            keepalive:2;
    
    #if (NGX_HAVE_DEFERRED_ACCEPT)
        unsigned            deferred_accept:1;
        unsigned            delete_deferred:1;
        unsigned            add_deferred:1;
    #ifdef SO_ACCEPTFILTER
        char               *accept_filter;
    #endif
    #endif
    #if (NGX_HAVE_SETFIB)
        int                 setfib;
    #endif
    
    };
     p *ngx_cycle
    $10 = {
      conf_ctx = 0x6a1d10, 
      pool = 0x6a0f30, 
      log = 0x6a0f98, 
      new_log = {
        log_level = 256, 
        file = 0x6a11d8, 
        connection = 0, 
        handler = 0, 
        data = 0x0, 
        action = 0x0
      }, 
      files = 0x0, 
      free_connections = 0x0, 
      free_connection_n = 0, 
      reusable_connections_queue = {
        prev = 0x6a0fe0, 
        next = 0x6a0fe0
      }, 
      listening = {
        elts = 0x6a1540, 
        nelts = 1, 
        size = 200, 
        nalloc = 10, 
        pool = 0x6a0f30
      }, 
      paths = {
        elts = 0x6a1188, 
        nelts = 5, 
        size = 8, 
        nalloc = 10, 
        pool = 0x6a0f30
      }, 
      open_files = {
        last = 0x6a1048, 
        part = {
          elts = 0x6a11d8, 
    ---Type <return> to continue, or q <return> to quit---
          nelts = 3, 
          next = 0x0
        }, 
        size = 40, 
        nalloc = 20, 
        pool = 0x6a0f30
      }, 
      shared_memory = {
        last = 0x6a1080, 
        part = {
          elts = 0x6a14f8, 
          nelts = 0, 
          next = 0x0
        }, 
        size = 72, 
        nalloc = 1, 
        pool = 0x6a0f30
      }, 
      connection_n = 1024, 
      files_n = 0, 
      connections = 0x0, 
      read_events = 0x0, 
      write_events = 0x0, 
      old_cycle = 0x0, 
      conf_file = {
        len = 32, 
        data = 0x6a1167 "/usr/local/nginx/conf/nginx.conf"
      }, 
      conf_param = {
        len = 0, 
        data = 0x6a1188 "37030l"
      }, 
      conf_prefix = {
        len = 22, 
        data = 0x6a1140 "/usr/local/nginx/conf//usr/local/nginx//usr/local/nginx/conf/nginx.conf"
      }, 
      prefix = {
    ---Type <return> to continue, or q <return> to quit---
        len = 17, 
        data = 0x6a1156 "/usr/local/nginx//usr/local/nginx/conf/nginx.conf"
      }, 
      lock_file = {
        len = 33, 
        data = 0x6c60a0 "/usr/local/nginx/logs/nginx.lock.accept"
      }, 
      hostname = {
        len = 6, 
        data = 0x6a1e88 "centos"
      }
    }
    typedef struct {
        int     signo;
        char   *signame;
        char   *name;
        void  (*handler)(int signo);
    } ngx_signal_t;
        if (!ngx_inherited && ccf->daemon) {
            if (ngx_daemon(cycle->log) != NGX_OK) {
                return 1;
            }
    
            ngx_daemonized = 1;
        }
    ngx_int_t
    ngx_daemon(ngx_log_t *log)
    {
        int  fd;
    
        switch (fork()) {   
        case -1:
            ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "fork() failed");  
            return NGX_ERROR;
    
        case 0:
            break;
    
        default:
            exit(0);
        }
    
        ngx_pid = ngx_getpid();     
    
        if (setsid() == -1) {
            ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "setsid() failed");
            return NGX_ERROR;
        }
    
        umask(0);
    
        fd = open("/dev/null", O_RDWR);
        if (fd == -1) {
            ngx_log_error(NGX_LOG_EMERG, log, ngx_errno,
                          "open("/dev/null") failed");
            return NGX_ERROR;
        }
    
        if (dup2(fd, STDIN_FILENO) == -1) {
            ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "dup2(STDIN) failed");
            return NGX_ERROR;


    if (dup2(fd, STDOUT_FILENO) == -1) {
    ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "dup2(STDOUT) failed");
    return NGX_ERROR;
    }

    #if 0
    if (dup2(fd, STDERR_FILENO) == -1) {
    ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "dup2(STDERR) failed");
    return NGX_ERROR;
    }
    #endif

    if (fd > STDERR_FILENO) {
    if (close(fd) == -1) {
    ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "close() failed");
    return NGX_ERROR;
    }
    }

    return NGX_OK;
    }

        if (ngx_process == NGX_PROCESS_SINGLE) {
            ngx_single_process_cycle(cycle);
    
        } else {
            ngx_master_process_cycle(cycle);
        }
    
        return 0;
    void
    ngx_master_process_cycle(ngx_cycle_t *cycle)
    {
        char              *title;
        u_char            *p;
        size_t             size;    
        ngx_int_t          i;
        ngx_uint_t         n, sigio;
        sigset_t           set;
        struct itimerval   itv;
        ngx_uint_t         live;
        ngx_msec_t         delay;
        ngx_listening_t   *ls;
        ngx_core_conf_t   *ccf;
    
        sigemptyset(&set);  
        sigaddset(&set, SIGCHLD);
        sigaddset(&set, SIGALRM);
        sigaddset(&set, SIGIO);
        sigaddset(&set, SIGINT);
        sigaddset(&set, ngx_signal_value(NGX_RECONFIGURE_SIGNAL));
        sigaddset(&set, ngx_signal_value(NGX_REOPEN_SIGNAL));
        sigaddset(&set, ngx_signal_value(NGX_NOACCEPT_SIGNAL));
        sigaddset(&set, ngx_signal_value(NGX_TERMINATE_SIGNAL));
        sigaddset(&set, ngx_signal_value(NGX_SHUTDOWN_SIGNAL));
        sigaddset(&set, ngx_signal_value(NGX_CHANGEBIN_SIGNAL));
    
        if (sigprocmask(SIG_BLOCK, &set, NULL) == -1) {
            ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
                          "sigprocmask() failed");
        }
    
        sigemptyset(&set);
    
    
        size = sizeof(master_process);
    
        for (i = 0; i < ngx_argc; i++) {
        sigaddset(&set, SIGIO);
        sigaddset(&set, SIGINT);
        sigaddset(&set, ngx_signal_value(NGX_RECONFIGURE_SIGNAL));
        sigaddset(&set, ngx_signal_value(NGX_REOPEN_SIGNAL));
        sigaddset(&set, ngx_signal_value(NGX_NOACCEPT_SIGNAL));
        sigaddset(&set, ngx_signal_value(NGX_TERMINATE_SIGNAL));
        sigaddset(&set, ngx_signal_value(NGX_SHUTDOWN_SIGNAL));
        sigaddset(&set, ngx_signal_value(NGX_CHANGEBIN_SIGNAL));
    
        if (sigprocmask(SIG_BLOCK, &set, NULL) == -1) {
            ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
                          "sigprocmask() failed");
        }
    
        sigemptyset(&set);
    
    
        size = sizeof(master_process);
    
        for (i = 0; i < ngx_argc; i++) {
            size += ngx_strlen(ngx_argv[i]) + 1;
        }
    
        title = ngx_pnalloc(cycle->pool, size);
    
        p = ngx_cpymem(title, master_process, sizeof(master_process) - 1);
        for (i = 0; i < ngx_argc; i++) {
            *p++ = ' ';
            p = ngx_cpystrn(p, (u_char *) ngx_argv[i], size);
        }
    
        ngx_setproctitle(title);
    
    
        ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);
    
        ngx_start_worker_processes(cycle, ccf->worker_processes,
                                   NGX_PROCESS_RESPAWN);
        ngx_start_cache_manager_processes(cycle, 0);
    
        ngx_new_binary = 0;
        delay = 0;
        sigio = 0;
        live = 1;
    
        for ( ;; ) {
            if (delay) {
                if (ngx_sigalrm) {
                    sigio = 0;
                    delay *= 2;
                    ngx_sigalrm = 0;
                }
    
                ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
                               "termination cycle: %d", delay);
    
                itv.it_interval.tv_sec = 0;
                itv.it_interval.tv_usec = 0;
                itv.it_value.tv_sec = delay / 1000;
                itv.it_value.tv_usec = (delay % 1000 ) * 1000;
    
                if (setitimer(ITIMER_REAL, &itv, NULL) == -1) {
                    ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
                                  "setitimer() failed");
                }
            }
    
            ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, 0, "sigsuspend");
    
            sigsuspend(&set);
    
            ngx_time_update();
    
            ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
                           "wake up, sigio %i", sigio);
    
            if (ngx_reap) {
                ngx_reap = 0;
                ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, 0, "reap children");
    
                live = ngx_reap_children(cycle);
            }
    
            if (!live && (ngx_terminate || ngx_quit)) {
                ngx_master_process_exit(cycle);
            }
    
            if (ngx_terminate) {
                if (delay == 0) {
                    delay = 50;
                }
    
                if (sigio) {
                    sigio--;
                    continue;
                }
    
                sigio = ccf->worker_processes + 2 /* cache processes */;
    
                if (delay > 1000) {
                    ngx_signal_worker_processes(cycle, SIGKILL);
                } else {
                    ngx_signal_worker_processes(cycle,
                                           ngx_signal_value(NGX_TERMINATE_SIGNAL));
                }
    
                continue;
            }
    
            if (ngx_quit) {
                ngx_signal_worker_processes(cycle,
                                            ngx_signal_value(NGX_SHUTDOWN_SIGNAL));
    
                ls = cycle->listening.elts;
                for (n = 0; n < cycle->listening.nelts; n++) {
                    if (ngx_close_socket(ls[n].fd) == -1) {
                        ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_socket_errno,
                                      ngx_close_socket_n " %V failed",
                                      &ls[n].addr_text);
                    }
                }
                cycle->listening.nelts = 0;
    
                continue;
            }
    
            if (ngx_reconfigure) {
                ngx_reconfigure = 0;
    
                if (ngx_new_binary) {
                    ngx_start_worker_processes(cycle, ccf->worker_processes,
                                               NGX_PROCESS_RESPAWN);
                    ngx_start_cache_manager_processes(cycle, 0);
                    ngx_noaccepting = 0;
    
                    continue;
                }
    
                ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "reconfiguring");
    
                cycle = ngx_init_cycle(cycle);
                if (cycle == NULL) {
                    cycle = (ngx_cycle_t *) ngx_cycle;
                    continue;
                }
    
                ngx_cycle = cycle;
                ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx,
                                                       ngx_core_module);
                ngx_start_worker_processes(cycle, ccf->worker_processes,
                                           NGX_PROCESS_JUST_RESPAWN);
                ngx_start_cache_manager_processes(cycle, 1);
    
                /* allow new processes to start */
                ngx_msleep(100);
    
                live = 1;
                ngx_signal_worker_processes(cycle,
                                            ngx_signal_value(NGX_SHUTDOWN_SIGNAL));
                ngx_msleep(100);
    
                live = 1;
                ngx_signal_worker_processes(cycle,
                                            ngx_signal_value(NGX_SHUTDOWN_SIGNAL));
            }
    
            if (ngx_restart) {
                ngx_restart = 0;
                ngx_start_worker_processes(cycle, ccf->worker_processes,
                                           NGX_PROCESS_RESPAWN);
                ngx_start_cache_manager_processes(cycle, 0);
                live = 1;
            }
    
            if (ngx_reopen) {
                ngx_reopen = 0;
                ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "reopening logs");
                ngx_reopen_files(cycle, ccf->user);
                ngx_signal_worker_processes(cycle,
                                            ngx_signal_value(NGX_REOPEN_SIGNAL));
            }
    
            if (ngx_change_binary) {
                ngx_change_binary = 0;
                ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "changing binary");
                ngx_new_binary = ngx_exec_new_binary(cycle, ngx_argv);
            }
    
            if (ngx_noaccept) {
                ngx_noaccept = 0;
                ngx_noaccepting = 1;
                ngx_signal_worker_processes(cycle,
                                            ngx_signal_value(NGX_SHUTDOWN_SIGNAL));
            }
        }
    }
    static voidngx_start_worker_processes(ngx_cycle_t *cycle, ngx_int_t n, ngx_int_t type)
    {
        ngx_int_t      i;
        ngx_channel_t  ch;  
    
        ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "start worker processes");
    
        ch.command = NGX_CMD_OPEN_CHANNEL;  
    
        for (i = 0; i < n; i++) {   
    
            ngx_spawn_process(cycle, ngx_worker_process_cycle,
                              (void *) (intptr_t) i, "worker process", type);
    
            ch.pid = ngx_processes[ngx_process_slot].pid;
            ch.slot = ngx_process_slot;
            ch.fd = ngx_processes[ngx_process_slot].channel[0];
    
            ngx_pass_open_channel(cycle, &ch);
        }
    }
  • 相关阅读:
    SQLServer 事物与索引
    SQLServer 常见SQL笔试题之语句操作题详解
    测试思想-测试设计 测试用例设计之边界值分析方法
    测试思想-测试设计 测试用例设计之等价类划分方法
    测试思想-测试设计 测试用例设计之因果图方法
    测试思想-测试设计 测试用例设计之判定表驱动分析方法
    MySql 缓存查询原理与缓存监控 和 索引监控
    测试思想-测试设计 授客细说场景测试用例设计与实践
    产品相关 细说软件产品和业务 & 业务过程(流程) & 业务逻辑
    Postman Postman接口测试工具使用简介
  • 原文地址:https://www.cnblogs.com/andyhe/p/3227208.html
Copyright © 2020-2023  润新知