ngx_event.c

来自「Nginx是一个高性能的HTTP和反向代理服务器」· C语言 代码 · 共 1,266 行 · 第 1/3 页

C
1,266
字号
static ngx_int_tngx_event_module_init(ngx_cycle_t *cycle){    void              ***cf;    u_char              *shared;    size_t               size, cl;    ngx_shm_t            shm;    ngx_core_conf_t     *ccf;    ngx_event_conf_t    *ecf;    cf = ngx_get_conf(cycle->conf_ctx, ngx_events_module);    if (cf == NULL) {        ngx_log_error(NGX_LOG_EMERG, cycle->log, 0,                      "no \"events\" section in configuration");        return NGX_ERROR;    }    ecf = (*cf)[ngx_event_core_module.ctx_index];    if (!ngx_test_config) {        ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0,                      "using the \"%s\" event method", ecf->name);    }    ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);    ngx_timer_resolution = ccf->timer_resolution;#if !(NGX_WIN32)    {    ngx_int_t      limit;    struct rlimit  rlmt;    if (getrlimit(RLIMIT_NOFILE, &rlmt) == -1) {        ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,                      "getrlimit(RLIMIT_NOFILE) failed, ignored");    } else {        if (ecf->connections > (ngx_uint_t) rlmt.rlim_cur            && (ccf->rlimit_nofile == NGX_CONF_UNSET                || ecf->connections > (ngx_uint_t) ccf->rlimit_nofile))        {            limit = (ccf->rlimit_nofile == NGX_CONF_UNSET) ?                         (ngx_int_t) rlmt.rlim_cur : ccf->rlimit_nofile;            ngx_log_error(NGX_LOG_WARN, cycle->log, 0,                          "%ui worker_connections are more than "                          "open file resource limit: %i",                          ecf->connections, limit);        }    }    }#endif /* !(NGX_WIN32) */    if (ccf->master == 0) {        return NGX_OK;    }    if (ngx_accept_mutex_ptr) {        return NGX_OK;    }    /* cl should be equal or bigger than cache line size */    cl = 128;    size = cl            /* ngx_accept_mutex */           + cl;         /* ngx_connection_counter */#if (NGX_STAT_STUB)    size += cl           /* ngx_stat_accepted */           + cl          /* ngx_stat_handled */           + cl          /* ngx_stat_requests */           + cl          /* ngx_stat_active */           + cl          /* ngx_stat_reading */           + cl;         /* ngx_stat_writing */#endif    shm.size = size;    shm.log = cycle->log;    if (ngx_shm_alloc(&shm) != NGX_OK) {        return NGX_ERROR;    }    shared = shm.addr;    ngx_accept_mutex_ptr = (ngx_atomic_t *) shared;    if (ngx_shmtx_create(&ngx_accept_mutex, shared, cycle->lock_file.data)        != NGX_OK)    {        return NGX_ERROR;    }    ngx_connection_counter = (ngx_atomic_t *) (shared + 1 * cl);#if (NGX_STAT_STUB)    ngx_stat_accepted = (ngx_atomic_t *) (shared + 2 * cl);    ngx_stat_handled = (ngx_atomic_t *) (shared + 3 * cl);    ngx_stat_requests = (ngx_atomic_t *) (shared + 4 * cl);    ngx_stat_active = (ngx_atomic_t *) (shared + 5 * cl);    ngx_stat_reading = (ngx_atomic_t *) (shared + 6 * cl);    ngx_stat_writing = (ngx_atomic_t *) (shared + 7 * cl);#endif    *ngx_connection_counter = 1;    ngx_log_debug2(NGX_LOG_DEBUG_EVENT, cycle->log, 0,                   "counter: %p, %d",                   ngx_connection_counter, *ngx_connection_counter);    return NGX_OK;}#if !(NGX_WIN32)voidngx_timer_signal_handler(int signo){    ngx_event_timer_alarm = 1;    ngx_time_update(0, 0);#if 1    ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ngx_cycle->log, 0, "timer signal");#endif}#endifstatic ngx_int_tngx_event_process_init(ngx_cycle_t *cycle){    ngx_uint_t           m, i;    ngx_event_t         *rev, *wev;    ngx_listening_t     *ls;    ngx_connection_t    *c, *next, *old;    ngx_core_conf_t     *ccf;    ngx_event_conf_t    *ecf;    ngx_event_module_t  *module;    ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);    ecf = ngx_event_get_conf(cycle->conf_ctx, ngx_event_core_module);    if (ccf->master && ccf->worker_processes > 1 && ecf->accept_mutex) {        ngx_use_accept_mutex = 1;        ngx_accept_mutex_held = 0;        ngx_accept_mutex_delay = ecf->accept_mutex_delay;    } else {        ngx_use_accept_mutex = 0;    }#if (NGX_THREADS)    ngx_posted_events_mutex = ngx_mutex_init(cycle->log, 0);    if (ngx_posted_events_mutex == NULL) {        return NGX_ERROR;    }#endif    if (ngx_event_timer_init(cycle->log) == NGX_ERROR) {        return NGX_ERROR;    }    cycle->connection_n = ecf->connections;    for (m = 0; ngx_modules[m]; m++) {        if (ngx_modules[m]->type != NGX_EVENT_MODULE) {            continue;        }        if (ngx_modules[m]->ctx_index == ecf->use) {            module = ngx_modules[m]->ctx;            if (module->actions.init(cycle, ngx_timer_resolution) == NGX_ERROR)            {                /* fatal */                exit(2);            }            break;        }    }#if !(NGX_WIN32)    if (ngx_timer_resolution && !(ngx_event_flags & NGX_USE_TIMER_EVENT)) {        struct sigaction  sa;        struct itimerval  itv;        ngx_memzero(&sa, sizeof(struct sigaction));        sa.sa_handler = ngx_timer_signal_handler;        sigemptyset(&sa.sa_mask);        if (sigaction(SIGALRM, &sa, NULL) == -1) {            ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,                          "sigaction(SIGALRM) failed");            return NGX_ERROR;        }        itv.it_interval.tv_sec = ngx_timer_resolution / 1000;        itv.it_interval.tv_usec = (ngx_timer_resolution % 1000) * 1000;        itv.it_value.tv_sec = ngx_timer_resolution / 1000;        itv.it_value.tv_usec = (ngx_timer_resolution % 1000 ) * 1000;        if (setitimer(ITIMER_REAL, &itv, NULL) == -1) {            ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,                          "setitimer() failed");        }    }    if (ngx_event_flags & NGX_USE_FD_EVENT) {        struct rlimit  rlmt;        if (getrlimit(RLIMIT_NOFILE, &rlmt) == -1) {            ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,                          "getrlimit(RLIMIT_NOFILE) failed");            return NGX_ERROR;        }        cycle->files_n = (ngx_uint_t) rlmt.rlim_cur;        cycle->files = ngx_calloc(sizeof(ngx_connection_t *) * cycle->files_n,                                  cycle->log);        if (cycle->files == NULL) {            return NGX_ERROR;        }    }#endif    cycle->connections = ngx_alloc(sizeof(ngx_connection_t) * ecf->connections,                                   cycle->log);    if (cycle->connections == NULL) {        return NGX_ERROR;    }    c = cycle->connections;    cycle->read_events = ngx_alloc(sizeof(ngx_event_t) * ecf->connections,                                   cycle->log);    if (cycle->read_events == NULL) {        return NGX_ERROR;    }    rev = cycle->read_events;    for (i = 0; i < cycle->connection_n; i++) {        rev[i].closed = 1;        rev[i].instance = 1;#if (NGX_THREADS)        rev[i].lock = &c[i].lock;        rev[i].own_lock = &c[i].lock;#endif    }    cycle->write_events = ngx_alloc(sizeof(ngx_event_t) * ecf->connections,                                    cycle->log);    if (cycle->write_events == NULL) {        return NGX_ERROR;    }    wev = cycle->write_events;    for (i = 0; i < cycle->connection_n; i++) {        wev[i].closed = 1;#if (NGX_THREADS)        wev[i].lock = &c[i].lock;        wev[i].own_lock = &c[i].lock;#endif    }    i = cycle->connection_n;    next = NULL;    do {        i--;        c[i].data = next;        c[i].read = &cycle->read_events[i];        c[i].write = &cycle->write_events[i];        c[i].fd = (ngx_socket_t) -1;        next = &c[i];#if (NGX_THREADS)        c[i].lock = 0;#endif    } while (i);    cycle->free_connections = next;    cycle->free_connection_n = ecf->connections;    /* for each listening socket */    ls = cycle->listening.elts;    for (i = 0; i < cycle->listening.nelts; i++) {        c = ngx_get_connection(ls[i].fd, cycle->log);        if (c == NULL) {            return NGX_ERROR;        }        c->log = &ls[i].log;        c->listening = &ls[i];        ls[i].connection = c;        rev = c->read;        rev->log = c->log;        rev->accept = 1;#if (NGX_HAVE_DEFERRED_ACCEPT)        rev->deferred_accept = ls[i].deferred_accept;#endif        if (!(ngx_event_flags & NGX_USE_IOCP_EVENT)) {            if (ls[i].previous) {                /*                 * delete the old accept events that were bound to                 * the old cycle read events array                 */                old = ls[i].previous->connection;                if (ngx_del_event(old->read, NGX_READ_EVENT, NGX_CLOSE_EVENT)                    == NGX_ERROR)                {                    return NGX_ERROR;                }                old->fd = (ngx_socket_t) -1;            }        }#if (NGX_WIN32)        if (ngx_event_flags & NGX_USE_IOCP_EVENT) {            ngx_iocp_conf_t  *iocpcf;            rev->handler = ngx_event_acceptex;            if (ngx_add_event(rev, 0, NGX_IOCP_ACCEPT) == NGX_ERROR) {                return NGX_ERROR;            }            ls[i].log.handler = ngx_acceptex_log_error;            iocpcf = ngx_event_get_conf(cycle->conf_ctx, ngx_iocp_module);            if (ngx_event_post_acceptex(&ls[i], iocpcf->post_acceptex)                == NGX_ERROR)            {                return NGX_ERROR;            }        } else {            rev->handler = ngx_event_accept;            if (ngx_add_event(rev, NGX_READ_EVENT, 0) == NGX_ERROR) {                return NGX_ERROR;            }        }#else        rev->handler = ngx_event_accept;        if (ngx_use_accept_mutex) {            continue;        }        if (ngx_event_flags & NGX_USE_RTSIG_EVENT) {            if (ngx_add_conn(c) == NGX_ERROR) {                return NGX_ERROR;            }        } else {            if (ngx_add_event(rev, NGX_READ_EVENT, 0) == NGX_ERROR) {                return NGX_ERROR;            }        }#endif    }    return NGX_OK;}ngx_int_tngx_send_lowat(ngx_connection_t *c, size_t lowat){    int  sndlowat;#if (NGX_HAVE_LOWAT_EVENT)    if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) {        c->write->available = lowat;        return NGX_OK;    }#endif    if (lowat == 0 || c->sndlowat) {        return NGX_OK;    }    sndlowat = (int) lowat;    if (setsockopt(c->fd, SOL_SOCKET, SO_SNDLOWAT,

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?