示例#1
0
static char *
ngx_iocp_init_conf(ngx_cycle_t *cycle, void *conf)
{
    ngx_iocp_conf_t *cf = conf;

    ngx_conf_init_value(cf->threads, 0);
    ngx_conf_init_value(cf->post_acceptex, 10);
    ngx_conf_init_value(cf->acceptex_read, 1);

    return NGX_CONF_OK;
}
static char *
ngx_http_geoip2_init_conf(ngx_conf_t *cf, void *conf)
{
    ngx_http_geoip2_conf_t  *gcf = conf;
    ngx_conf_init_value(gcf->proxy_recursive, 0);
    return NGX_CONF_OK;
}
示例#3
0
static char *
ngx_regex_init_conf(ngx_cycle_t *cycle, void *conf)
{
    ngx_regex_conf_t *rcf = conf;
    ngx_conf_init_value(rcf->pcre_jit, 0);
    return NGX_CONF_OK;
}
示例#4
0
static char *
ngx_zeromq_init_conf(ngx_cycle_t *cycle, void *conf)
{
    ngx_zeromq_conf_t  *zcf = conf;

    ngx_conf_init_value(zcf->threads, 1);

    return NGX_CONF_OK;
}
static char *
ngx_http_vhost_traffic_status_init_main_conf(ngx_conf_t *cf, void *conf)
{
    ngx_http_vhost_traffic_status_ctx_t     *ctx = conf;

    ngx_conf_init_value(ctx->enable, 0);

    return NGX_CONF_OK;
}
static char *
ngx_http_req_status_init_main_conf(ngx_conf_t *cf, void *conf)
{
    ngx_http_req_status_main_conf_t *rmcf = conf;

    ngx_conf_init_msec_value(rmcf->interval, 3000);
    ngx_conf_init_value(rmcf->lock_time, 10);

    return NGX_CONF_OK;
}
static char *
ngx_http_timer_init_main_conf(ngx_conf_t *cf, void *conf)
{
    ngx_http_timer_conf_t *tcf = conf;

    ngx_conf_init_value(tcf->enabled, 1);
    ngx_conf_init_msec_value(tcf->period, 5000);

    return NGX_CONF_OK;
}
static char *
ngx_rtmp_auto_push_init_conf(ngx_cycle_t *cycle, void *conf)
{
    ngx_rtmp_auto_push_conf_t      *apcf = conf;

    ngx_conf_init_value(apcf->auto_push, 0);
    ngx_conf_init_msec_value(apcf->push_reconnect, 100);

    if (apcf->socket_dir.len == 0) {
        ngx_str_set(&apcf->socket_dir, "/tmp");
    }

    return NGX_CONF_OK;
}
示例#9
0
//参考:
//http://blog.csdn.net/livelylittlefish/article/details/7262750
static char *
ngx_core_module_init_conf(ngx_cycle_t *cycle, void *conf)
{
    ngx_core_conf_t  *ccf = conf;

    //初始化daemon、master等
    ngx_conf_init_value(ccf->daemon, 1);
    ngx_conf_init_value(ccf->master, 1);
    ngx_conf_init_msec_value(ccf->timer_resolution, 0);

    ngx_conf_init_value(ccf->worker_processes, 1);
    ngx_conf_init_value(ccf->debug_points, 0);

#if (NGX_HAVE_SCHED_SETAFFINITY)

    if (ccf->cpu_affinity_n
        && ccf->cpu_affinity_n != 1
        && ccf->cpu_affinity_n != (ngx_uint_t) ccf->worker_processes)
    {
        ngx_log_error(NGX_LOG_WARN, cycle->log, 0,
                      "number of the \"worker_processes\" is not equal to "
                      "the number of the \"worker_cpu_affinity\" mask, "
                      "using last mask for remaining worker processes");
    }

#endif

#if (NGX_THREADS)

    ngx_conf_init_value(ccf->worker_threads, 0);
    ngx_threads_n = ccf->worker_threads;
    ngx_conf_init_size_value(ccf->thread_stack_size, 2 * 1024 * 1024);

#endif

    //初始化pid、oldpid
    if (ccf->pid.len == 0) {
        ngx_str_set(&ccf->pid, NGX_PID_PATH);
    }

    if (ngx_conf_full_name(cycle, &ccf->pid, 0) != NGX_OK) {
        return NGX_CONF_ERROR;
    }

    ccf->oldpid.len = ccf->pid.len + sizeof(NGX_OLDPID_EXT);

    ccf->oldpid.data = ngx_pnalloc(cycle->pool, ccf->oldpid.len);
    if (ccf->oldpid.data == NULL) {
        return NGX_CONF_ERROR;
    }

    ngx_memcpy(ngx_cpymem(ccf->oldpid.data, ccf->pid.data, ccf->pid.len),
               NGX_OLDPID_EXT, sizeof(NGX_OLDPID_EXT));


#if !(NGX_WIN32)
    //初始化username,user,group
    if (ccf->user == (uid_t) NGX_CONF_UNSET_UINT && geteuid() == 0) {
        struct group   *grp;
        struct passwd  *pwd;

        ngx_set_errno(0);
        pwd = getpwnam(NGX_USER);
        if (pwd == NULL) {
            ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
                          "getpwnam(\"" NGX_USER "\") failed");
            return NGX_CONF_ERROR;
        }

        ccf->username = NGX_USER;
        ccf->user = pwd->pw_uid;

        ngx_set_errno(0);
        grp = getgrnam(NGX_GROUP);
        if (grp == NULL) {
            ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
                          "getgrnam(\"" NGX_GROUP "\") failed");
            return NGX_CONF_ERROR;
        }

        ccf->group = grp->gr_gid;
    }


    if (ccf->lock_file.len == 0) {
        ngx_str_set(&ccf->lock_file, NGX_LOCK_PATH);
    }
    
    //初始化lock_file
    if (ngx_conf_full_name(cycle, &ccf->lock_file, 0) != NGX_OK) {
        return NGX_CONF_ERROR;
    }

    {
    ngx_str_t  lock_file;

    lock_file = cycle->old_cycle->lock_file;

    if (lock_file.len) {
        lock_file.len--;

        if (ccf->lock_file.len != lock_file.len
            || ngx_strncmp(ccf->lock_file.data, lock_file.data, lock_file.len)
               != 0)
        {
            ngx_log_error(NGX_LOG_EMERG, cycle->log, 0,
                          "\"lock_file\" could not be changed, ignored");
        }
        
        //初始化ngx_cycle->lock_file
        cycle->lock_file.len = lock_file.len + 1;
        lock_file.len += sizeof(".accept");

        cycle->lock_file.data = ngx_pstrdup(cycle->pool, &lock_file);
        if (cycle->lock_file.data == NULL) {
            return NGX_CONF_ERROR;
        }

    } else {
        cycle->lock_file.len = ccf->lock_file.len + 1;
        cycle->lock_file.data = ngx_pnalloc(cycle->pool,
                                      ccf->lock_file.len + sizeof(".accept"));
        if (cycle->lock_file.data == NULL) {
            return NGX_CONF_ERROR;
        }

        ngx_memcpy(ngx_cpymem(cycle->lock_file.data, ccf->lock_file.data,
                              ccf->lock_file.len),
                   ".accept", sizeof(".accept"));
    }
    }

#endif

    return NGX_CONF_OK;
}
示例#10
0
static char *
ngx_event_core_init_conf(ngx_cycle_t *cycle, void *conf)
{
    ngx_event_conf_t  *ecf = conf;

#if (NGX_HAVE_EPOLL) && !(NGX_TEST_BUILD_EPOLL)
    int                  fd;
#endif
#if (NGX_HAVE_RTSIG)
    ngx_uint_t           rtsig;
    ngx_core_conf_t     *ccf;
#endif
    ngx_int_t            i;
    ngx_module_t        *module;
    ngx_event_module_t  *event_module;

    module = NULL;

#if (NGX_HAVE_EPOLL) && !(NGX_TEST_BUILD_EPOLL)

    fd = epoll_create(100);

    if (fd != -1) {
        (void) close(fd);
        module = &ngx_epoll_module;

    } else if (ngx_errno != NGX_ENOSYS) {
        module = &ngx_epoll_module;
    }

#endif

#if (NGX_HAVE_RTSIG)

    if (module == NULL) {
        module = &ngx_rtsig_module;
        rtsig = 1;

    } else {
        rtsig = 0;
    }

#endif

#if (NGX_HAVE_DEVPOLL)

    module = &ngx_devpoll_module;

#endif

#if (NGX_HAVE_KQUEUE)

    module = &ngx_kqueue_module;

#endif

#if (NGX_HAVE_SELECT)

    if (module == NULL) {
        module = &ngx_select_module;
    }

#endif

    if (module == NULL) {
        for (i = 0; ngx_modules[i]; i++) {

            if (ngx_modules[i]->type != NGX_EVENT_MODULE) {
                continue;
            }

            event_module = ngx_modules[i]->ctx;

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

            module = ngx_modules[i];
            break;
        }
    }

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

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

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

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

    ngx_conf_init_value(ecf->multi_accept, 0);
    ngx_conf_init_value(ecf->accept_mutex, 1);
    ngx_conf_init_msec_value(ecf->accept_mutex_delay, 500);


#if (NGX_HAVE_RTSIG)

    if (!rtsig) {
        return NGX_CONF_OK;
    }

    if (ecf->accept_mutex) {
        return NGX_CONF_OK;
    }

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

    if (ccf->worker_processes == 0) {
        return NGX_CONF_OK;
    }

    ngx_log_error(NGX_LOG_EMERG, cycle->log, 0,
                  "the \"rtsig\" method requires \"accept_mutex\" to be on");

    return NGX_CONF_ERROR;

#else

    return NGX_CONF_OK;

#endif
}
示例#11
0
// 所有模块配置解析完毕后,对配置进行初始化
// 如果有的指令没有写,就要给正确的默认值
// 模块默认使用epoll
// 默认不接受多个请求,也就是一次只accept一个连接
// 默认使用负载均衡锁
static char *
ngx_event_core_init_conf(ngx_cycle_t *cycle, void *conf)
{
    ngx_event_conf_t  *ecf = conf;

#if (NGX_HAVE_EPOLL) && !(NGX_TEST_BUILD_EPOLL)
    int                  fd;
#endif

    // rtsig在nginx 1.9.x已经删除

    ngx_int_t            i;
    ngx_module_t        *module;
    ngx_event_module_t  *event_module;

    module = NULL;

// 测试epoll是否可用
#if (NGX_HAVE_EPOLL) && !(NGX_TEST_BUILD_EPOLL)

    fd = epoll_create(100);

    // epoll调用可用,那么模块默认使用epoll
    if (fd != -1) {
        (void) close(fd);
        // epoll调用可用,那么模块默认使用epoll
        module = &ngx_epoll_module;

    } else if (ngx_errno != NGX_ENOSYS) {
        // epoll调用可用,那么模块默认使用epoll
        module = &ngx_epoll_module;
    }

#endif

    // rtsig在nginx 1.9.x已经删除

#if (NGX_HAVE_DEVPOLL) && !(NGX_TEST_BUILD_DEVPOLL)

    module = &ngx_devpoll_module;

#endif

#if (NGX_HAVE_KQUEUE)

    module = &ngx_kqueue_module;

#endif

    // 如果epoll不可用,那么默认使用select
#if (NGX_HAVE_SELECT)

    if (module == NULL) {
        module = &ngx_select_module;
    }

#endif

    // 还没有决定默认的事件模型
    if (module == NULL) {
        // 遍历所有的事件模块
        for (i = 0; cycle->modules[i]; i++) {

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

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

            // 跳过event_core模块
            if (ngx_strcmp(event_module->name->data, event_core_name.data) == 0)
            {
                continue;
            }

            // 使用数组里的第一个事件模块
            module = cycle->modules[i];
            break;
        }
    }

    // 最后还没有决定默认的事件模型,出错
    if (module == NULL) {
        ngx_log_error(NGX_LOG_EMERG, cycle->log, 0, "no events module found");
        return NGX_CONF_ERROR;
    }

    // nginx每个进程可使用的连接数量,即cycle里的连接池大小
    ngx_conf_init_uint_value(ecf->connections, DEFAULT_CONNECTIONS);

    // 如果没有使用worker_connections指令,在这里设置
    cycle->connection_n = ecf->connections;

    // 决定使用的事件模型,之前的module只作为默认值,如果已经使用了use则无效
    ngx_conf_init_uint_value(ecf->use, module->ctx_index);

    // 初始化使用的事件模块的名字
    event_module = module->ctx;
    ngx_conf_init_ptr_value(ecf->name, event_module->name->data);

    // 默认不接受多个请求,也就是一次只accept一个连接
    ngx_conf_init_value(ecf->multi_accept, 0);

    // 默认使用负载均衡锁
    ngx_conf_init_value(ecf->accept_mutex, 1);

    // 默认负载均衡锁的等待时间是500毫秒
    ngx_conf_init_msec_value(ecf->accept_mutex_delay, 500);

    return NGX_CONF_OK;
}
示例#12
0
static char *
ngx_core_module_init_conf(ngx_cycle_t *cycle, void *conf)
{
    ngx_core_conf_t  *ccf = conf;

#if (NGX_HAVE_CPU_AFFINITY)
    ngx_int_t         i, n;
    CPU_SET_T        *mask;
#endif

    if (!ccf->worker_processes) {
        ccf->worker_processes = NGX_CONF_UNSET;
    }

    ngx_conf_init_value(ccf->worker_processes, ngx_ncpu);

    ngx_conf_init_value(ccf->daemon, 1);
    ngx_conf_init_value(ccf->master, 1);
    ngx_conf_init_msec_value(ccf->timer_resolution, 0);
    ngx_conf_init_value(ccf->debug_points, 0);

#if (NGX_HAVE_CPU_AFFINITY)

    /* in default, disable cpu affinity */

    if (ccf->cpu_affinity_n == 0 && ccf->cpu_affinity == NULL) {
        ccf->cpu_affinity_n = 1;
    }

    if (ccf->cpu_affinity_n == 0) {

        n = ngx_ncpu - 1;

        if (ngx_ncpu > 0 && ngx_ncpu <= CPU_SETSIZE) {

            mask = ngx_palloc(cycle->pool,
                              ccf->worker_processes * sizeof(CPU_SET_T));
            if (mask == NULL) {
                return NGX_CONF_ERROR;
            }

            ccf->cpu_affinity_n = ccf->worker_processes;
            ccf->cpu_affinity = mask;

            /* RR for cpu assign */
            for (i = 0; i < ccf->worker_processes; i++) {
                CPU_ZERO(&mask[i]);
                CPU_SET(n, &mask[i]);
                if (--n < 0) {
                    n = ngx_ncpu - 1;
                }
            }

        } else {
            ccf->cpu_affinity_n = 0;
            ccf->cpu_affinity = NULL;
        }
    }

    if (ccf->cpu_affinity_n
            && ccf->cpu_affinity_n != 1
            && ccf->cpu_affinity_n != (ngx_uint_t) ccf->worker_processes)
    {
        ngx_log_error(NGX_LOG_WARN, cycle->log, 0,
                      "the number of \"worker_processes\" is not equal to "
                      "the number of \"worker_cpu_affinity\" masks, "
                      "using last mask for remaining worker processes");
    }

#endif

#if (NGX_THREADS)

    ngx_conf_init_value(ccf->worker_threads, 0);
    ngx_threads_n = ccf->worker_threads;
    ngx_conf_init_size_value(ccf->thread_stack_size, 2 * 1024 * 1024);

#endif


    if (ccf->pid.len == 0) {
        ngx_str_set(&ccf->pid, NGX_PID_PATH);
    }

    if (ngx_conf_full_name(cycle, &ccf->pid, 0) != NGX_OK) {
        return NGX_CONF_ERROR;
    }

    ccf->oldpid.len = ccf->pid.len + sizeof(NGX_OLDPID_EXT);

    ccf->oldpid.data = ngx_pnalloc(cycle->pool, ccf->oldpid.len);
    if (ccf->oldpid.data == NULL) {
        return NGX_CONF_ERROR;
    }

    ngx_memcpy(ngx_cpymem(ccf->oldpid.data, ccf->pid.data, ccf->pid.len),
               NGX_OLDPID_EXT, sizeof(NGX_OLDPID_EXT));


#if !(NGX_WIN32)

    if (ccf->user == (uid_t) NGX_CONF_UNSET_UINT && geteuid() == 0) {
        struct group   *grp;
        struct passwd  *pwd;

        ngx_set_errno(0);
        pwd = getpwnam(NGX_USER);
        if (pwd == NULL) {
            ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
                          "getpwnam(\"" NGX_USER "\") failed");
            return NGX_CONF_ERROR;
        }

        ccf->username = NGX_USER;
        ccf->user = pwd->pw_uid;

        ngx_set_errno(0);
        grp = getgrnam(NGX_GROUP);
        if (grp == NULL) {
            ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
                          "getgrnam(\"" NGX_GROUP "\") failed");
            return NGX_CONF_ERROR;
        }

        ccf->group = grp->gr_gid;
    }


    if (ccf->lock_file.len == 0) {
        ngx_str_set(&ccf->lock_file, NGX_LOCK_PATH);
    }

    if (ngx_conf_full_name(cycle, &ccf->lock_file, 0) != NGX_OK) {
        return NGX_CONF_ERROR;
    }

    {
        ngx_str_t  lock_file;

        lock_file = cycle->old_cycle->lock_file;

        if (lock_file.len) {
            lock_file.len--;

            if (ccf->lock_file.len != lock_file.len
                    || ngx_strncmp(ccf->lock_file.data, lock_file.data, lock_file.len)
                    != 0)
            {
                ngx_log_error(NGX_LOG_EMERG, cycle->log, 0,
                              "\"lock_file\" could not be changed, ignored");
            }

            cycle->lock_file.len = lock_file.len + 1;
            lock_file.len += sizeof(".accept");

            cycle->lock_file.data = ngx_pstrdup(cycle->pool, &lock_file);
            if (cycle->lock_file.data == NULL) {
                return NGX_CONF_ERROR;
            }

        } else {
            cycle->lock_file.len = ccf->lock_file.len + 1;
            cycle->lock_file.data = ngx_pnalloc(cycle->pool,
                                                ccf->lock_file.len + sizeof(".accept"));
            if (cycle->lock_file.data == NULL) {
                return NGX_CONF_ERROR;
            }

            ngx_memcpy(ngx_cpymem(cycle->lock_file.data, ccf->lock_file.data,
                                  ccf->lock_file.len),
                       ".accept", sizeof(".accept"));
        }
    }

#endif

    return NGX_CONF_OK;
}
示例#13
0
static char *ngx_event_init_conf(ngx_cycle_t *cycle, void *conf)
{
    ngx_event_conf_t  *ecf = conf;
#if (HAVE_RTSIG)
    ngx_core_conf_t  *ccf;
#endif

#if (HAVE_KQUEUE)

    ngx_conf_init_unsigned_value(ecf->connections, DEFAULT_CONNECTIONS);
    ngx_conf_init_unsigned_value(ecf->use, ngx_kqueue_module.ctx_index);
    ngx_conf_init_ptr_value(ecf->name, ngx_kqueue_module_ctx.name->data);

#elif (HAVE_DEVPOLL)

    ngx_conf_init_unsigned_value(ecf->connections, DEFAULT_CONNECTIONS);
    ngx_conf_init_unsigned_value(ecf->use, ngx_devpoll_module.ctx_index);
    ngx_conf_init_ptr_value(ecf->name, ngx_devpoll_module_ctx.name->data);

#elif (HAVE_EPOLL)

    ngx_conf_init_unsigned_value(ecf->connections, DEFAULT_CONNECTIONS);
    ngx_conf_init_unsigned_value(ecf->use, ngx_epoll_module.ctx_index);
    ngx_conf_init_ptr_value(ecf->name, ngx_epoll_module_ctx.name->data);

#elif (HAVE_RTSIG)

    ngx_conf_init_unsigned_value(ecf->connections, DEFAULT_CONNECTIONS);
    ngx_conf_init_unsigned_value(ecf->use, ngx_rtsig_module.ctx_index);
    ngx_conf_init_ptr_value(ecf->name, ngx_rtsig_module_ctx.name->data);

#elif (HAVE_SELECT)

#if (WIN32)
    ngx_conf_init_unsigned_value(ecf->connections, DEFAULT_CONNECTIONS);
#else
    ngx_conf_init_unsigned_value(ecf->connections,
                                 FD_SETSIZE < DEFAULT_CONNECTIONS ? FD_SETSIZE : DEFAULT_CONNECTIONS);
#endif

    ngx_conf_init_unsigned_value(ecf->use, ngx_select_module.ctx_index);
    ngx_conf_init_ptr_value(ecf->name, ngx_select_module_ctx.name->data);

#else

    ngx_int_t            i, m;
    ngx_event_module_t  *module;

    m = -1;
    module = NULL;

    for (i = 0; ngx_modules[i]; i++) {
        if (ngx_modules[i]->type == NGX_EVENT_MODULE) {
            module = ngx_modules[i]->ctx;

            if (ngx_strcmp(module->name->data, event_core_name.data) == 0) {
                continue;
            }

            m = ngx_modules[i]->ctx_index;
            break;
        }
    }

    if (m == -1) {
        ngx_log_error(NGX_LOG_EMERG, cycle->log, 0, "no events module found");
        return NGX_CONF_ERROR;
    }

    ngx_conf_init_unsigned_value(ecf->connections, DEFAULT_CONNECTIONS);

    ngx_conf_init_unsigned_value(ecf->use, m);
    ngx_conf_init_ptr_value(ecf->name, module->name->data);

#endif

    cycle->connection_n = ecf->connections;

    ngx_conf_init_value(ecf->multi_accept, 0);
    ngx_conf_init_value(ecf->accept_mutex, 1);
    ngx_conf_init_msec_value(ecf->accept_mutex_delay, 500);

#if (HAVE_RTSIG)
    if (ecf->use == ngx_rtsig_module.ctx_index && ecf->accept_mutex == 0) {
        ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx,
                                               ngx_core_module);
        if (ccf->worker_processes) {
            ngx_log_error(NGX_LOG_EMERG, cycle->log, 0,
                          "the \"rtsig\" method requires "
                          "\"accept_mutex\" to be on");
            return NGX_CONF_ERROR;
        }
    }
#endif

    return NGX_CONF_OK;
}
static char *
ngx_btt(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
    ngx_btt_conf_t *bcf = conf;

    ngx_str_t   *value, str;
    ngx_uint_t   i;

    if (bcf->name.data != NULL) {
        return "is duplicate";
    }

    value = cf->args->elts;

    for (i = 1; i < cf->args->nelts; i++) {

        if (ngx_strncmp(value[i].data, "name=", 5) == 0) {
            bcf->name.len = value[i].len - 5;
            bcf->name.data = value[i].data + 5;
            continue;
        }

        if (ngx_strncmp(value[i].data, "size=", 5) == 0) {
            str.len = value[i].len - 5;
            str.data = value[i].data + 5;
            bcf->size = ngx_parse_size(&str);
            if (bcf->size == (size_t) NGX_ERROR) {
                goto invalid;
            }
            continue;
        }

        if (ngx_strncmp(value[i].data, "expire=", 7) == 0) {
            str.len = value[i].len - 7;
            str.data = value[i].data + 7;
            bcf->expire = ngx_parse_time(&str, 1);
            if (bcf->expire == NGX_ERROR) {
                goto invalid;
            }
            continue;
        }

        if (ngx_strncmp(value[i].data, "interval=", 9) == 0) {
            str.len = value[i].len - 9;
            str.data = value[i].data + 9;
            bcf->interval = ngx_parse_time(&str, 1);
            if (bcf->interval == NGX_ERROR) {
                goto invalid;
            }
            continue;
        }

        goto invalid;
    }

    if (bcf->name.data == NULL) {
        ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                           "the directive \"btt\" must be specified");
        return NGX_CONF_ERROR;
    }

    ngx_conf_init_size_value(bcf->size, 1024 * 1024 * 10);
    ngx_conf_init_value(bcf->expire, 60);
    ngx_conf_init_value(bcf->interval, 30);

    bcf->zone = ngx_shared_memory_add(cf, &bcf->name, bcf->size,
                                      &ngx_lua_btt_module);
    if (bcf->zone == NULL) {
        return NGX_CONF_ERROR;
    }

    if (bcf->zone->data) {
        ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                           "duplicate btt name \"%V\"", &bcf->name);
        return NGX_CONF_ERROR;
    }

    bcf->zone->init = ngx_btt_init;
    bcf->zone->data = bcf;

    return NGX_CONF_OK;

invalid:

    ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                       "invalid parameter \"%V\" in btt", &value[i]);

    return NGX_CONF_ERROR;
}
static char *
ngx_event_core_init_conf(ngx_cycle_t *cycle, void *conf)
{
    ngx_event_conf_t  *ecf = conf;

#if (NGX_HAVE_EPOLL) && !(NGX_TEST_BUILD_EPOLL)
    int                  fd;
#endif
    ngx_int_t            i;
    ngx_module_t        *module;
    ngx_event_module_t  *event_module;

    module = NULL;

#if (NGX_HAVE_EPOLL) && !(NGX_TEST_BUILD_EPOLL)

    fd = epoll_create(100);

    if (fd != -1) {
        (void) close(fd);
        module = &ngx_epoll_module;

    } else if (ngx_errno != NGX_ENOSYS) {
        module = &ngx_epoll_module;
    }

#endif

#if (NGX_HAVE_DEVPOLL)

    module = &ngx_devpoll_module;

#endif

#if (NGX_HAVE_KQUEUE)

    module = &ngx_kqueue_module;

#endif

#if (NGX_HAVE_SELECT)

    if (module == NULL) {
        module = &ngx_select_module;
    }

#endif

    //ngx_event_core_module后的第一个NGX_EVENT_MODULE也就是ngx_epoll_module默认作为第一个event模块
    if (module == NULL) {
        for (i = 0; ngx_modules[i]; i++) {

            if (ngx_modules[i]->type != NGX_EVENT_MODULE) {
                continue;
            }

            event_module = ngx_modules[i]->ctx;

            if (ngx_strcmp(event_module->name->data, event_core_name.data) == 0) //不能为ngx_event_core_module
            {
                continue;
            }

            module = ngx_modules[i];
            break;
        }
    }

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

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

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

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

    ngx_conf_init_value(ecf->multi_accept, 0);
    ngx_conf_init_value(ecf->accept_mutex, 1);
    ngx_conf_init_msec_value(ecf->accept_mutex_delay, 500);

    return NGX_CONF_OK;
}
static char *
ngx_http_push_stream_init_main_conf(ngx_conf_t *cf, void *parent)
{
    ngx_http_push_stream_main_conf_t     *conf = parent;

    if (!conf->enabled) {
        return NGX_CONF_OK;
    }

    ngx_conf_init_value(conf->message_ttl, NGX_HTTP_PUSH_STREAM_DEFAULT_MESSAGE_TTL);
    ngx_conf_init_value(conf->channel_inactivity_time, NGX_HTTP_PUSH_STREAM_DEFAULT_CHANNEL_INACTIVITY_TIME);
    ngx_conf_merge_str_value(conf->channel_deleted_message_text, conf->channel_deleted_message_text, NGX_HTTP_PUSH_STREAM_CHANNEL_DELETED_MESSAGE_TEXT);
    ngx_conf_merge_str_value(conf->ping_message_text, conf->ping_message_text, NGX_HTTP_PUSH_STREAM_PING_MESSAGE_TEXT);
    ngx_conf_merge_str_value(conf->wildcard_channel_prefix, conf->wildcard_channel_prefix, NGX_HTTP_PUSH_STREAM_DEFAULT_WILDCARD_CHANNEL_PREFIX);
    ngx_conf_init_value(conf->timeout_with_body, 0);

    // sanity checks
    // shm size should be set
    if (conf->shm_zone == NULL) {
        ngx_conf_log_error(NGX_LOG_ERR, cf, 0, "push stream module: push_stream_shared_memory_size must be set.");
        return NGX_CONF_ERROR;
    }

    // max number of channels cannot be zero
    if ((conf->max_number_of_channels != NGX_CONF_UNSET_UINT) && (conf->max_number_of_channels == 0)) {
        ngx_conf_log_error(NGX_LOG_ERR, cf, 0, "push stream module: push_stream_max_number_of_channels cannot be zero.");
        return NGX_CONF_ERROR;
    }

    // max number of wildcard channels cannot be zero
    if ((conf->max_number_of_wildcard_channels != NGX_CONF_UNSET_UINT) && (conf->max_number_of_wildcard_channels == 0)) {
        ngx_conf_log_error(NGX_LOG_ERR, cf, 0, "push stream module: push_stream_max_number_of_wildcard_channels cannot be zero.");
        return NGX_CONF_ERROR;
    }

    // message ttl cannot be zero
    if ((conf->message_ttl != NGX_CONF_UNSET) && (conf->message_ttl == 0)) {
        ngx_conf_log_error(NGX_LOG_ERR, cf, 0, "push stream module: push_stream_message_ttl cannot be zero.");
        return NGX_CONF_ERROR;
    }

    // max subscriber per channel cannot be zero
    if ((conf->max_subscribers_per_channel != NGX_CONF_UNSET_UINT) && (conf->max_subscribers_per_channel == 0)) {
        ngx_conf_log_error(NGX_LOG_ERR, cf, 0, "push stream module: push_stream_max_subscribers_per_channel cannot be zero.");
        return NGX_CONF_ERROR;
    }

    // max messages stored per channel cannot be zero
    if ((conf->max_messages_stored_per_channel != NGX_CONF_UNSET_UINT) && (conf->max_messages_stored_per_channel == 0)) {
        ngx_conf_log_error(NGX_LOG_ERR, cf, 0, "push stream module: push_stream_max_messages_stored_per_channel cannot be zero.");
        return NGX_CONF_ERROR;
    }

    // max channel id length cannot be zero
    if ((conf->max_channel_id_length != NGX_CONF_UNSET_UINT) && (conf->max_channel_id_length == 0)) {
        ngx_conf_log_error(NGX_LOG_ERR, cf, 0, "push stream module: push_stream_max_channel_id_length cannot be zero.");
        return NGX_CONF_ERROR;
    }

    ngx_regex_compile_t *backtrack_parser = NULL;
    u_char               errstr[NGX_MAX_CONF_ERRSTR];

    if ((backtrack_parser = ngx_pcalloc(cf->pool, sizeof(ngx_regex_compile_t))) == NULL) {
        ngx_conf_log_error(NGX_LOG_ERR, cf, 0, "push stream module: push stream module: unable to allocate memory to compile backtrack parser");
        return NGX_CONF_ERROR;
    }

    backtrack_parser->pattern = NGX_HTTP_PUSH_STREAM_BACKTRACK_PATTERN;
    backtrack_parser->pool = cf->pool;
    backtrack_parser->err.len = NGX_MAX_CONF_ERRSTR;
    backtrack_parser->err.data = errstr;

    if (ngx_regex_compile(backtrack_parser) != NGX_OK) {
        ngx_conf_log_error(NGX_LOG_ERR, cf, 0, "push stream module: unable to compile backtrack parser pattern %V", &NGX_HTTP_PUSH_STREAM_BACKTRACK_PATTERN);
        return NGX_CONF_ERROR;
    }

    conf->backtrack_parser_regex = backtrack_parser->regex;

    return NGX_CONF_OK;
}