Annotation of embedaddon/nginx/src/event/ngx_event.c, revision 1.1.1.1

1.1       misho       1: 
                      2: /*
                      3:  * Copyright (C) Igor Sysoev
                      4:  * Copyright (C) Nginx, Inc.
                      5:  */
                      6: 
                      7: 
                      8: #include <ngx_config.h>
                      9: #include <ngx_core.h>
                     10: #include <ngx_event.h>
                     11: 
                     12: 
                     13: #define DEFAULT_CONNECTIONS  512
                     14: 
                     15: 
                     16: extern ngx_module_t ngx_kqueue_module;
                     17: extern ngx_module_t ngx_eventport_module;
                     18: extern ngx_module_t ngx_devpoll_module;
                     19: extern ngx_module_t ngx_epoll_module;
                     20: extern ngx_module_t ngx_rtsig_module;
                     21: extern ngx_module_t ngx_select_module;
                     22: 
                     23: 
                     24: static char *ngx_event_init_conf(ngx_cycle_t *cycle, void *conf);
                     25: static ngx_int_t ngx_event_module_init(ngx_cycle_t *cycle);
                     26: static ngx_int_t ngx_event_process_init(ngx_cycle_t *cycle);
                     27: static char *ngx_events_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
                     28: 
                     29: static char *ngx_event_connections(ngx_conf_t *cf, ngx_command_t *cmd,
                     30:     void *conf);
                     31: static char *ngx_event_use(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
                     32: static char *ngx_event_debug_connection(ngx_conf_t *cf, ngx_command_t *cmd,
                     33:     void *conf);
                     34: 
                     35: static void *ngx_event_core_create_conf(ngx_cycle_t *cycle);
                     36: static char *ngx_event_core_init_conf(ngx_cycle_t *cycle, void *conf);
                     37: 
                     38: 
                     39: static ngx_uint_t     ngx_timer_resolution;
                     40: sig_atomic_t          ngx_event_timer_alarm;
                     41: 
                     42: static ngx_uint_t     ngx_event_max_module;
                     43: 
                     44: ngx_uint_t            ngx_event_flags;
                     45: ngx_event_actions_t   ngx_event_actions;
                     46: 
                     47: 
                     48: static ngx_atomic_t   connection_counter = 1;
                     49: ngx_atomic_t         *ngx_connection_counter = &connection_counter;
                     50: 
                     51: 
                     52: ngx_atomic_t         *ngx_accept_mutex_ptr;
                     53: ngx_shmtx_t           ngx_accept_mutex;
                     54: ngx_uint_t            ngx_use_accept_mutex;
                     55: ngx_uint_t            ngx_accept_events;
                     56: ngx_uint_t            ngx_accept_mutex_held;
                     57: ngx_msec_t            ngx_accept_mutex_delay;
                     58: ngx_int_t             ngx_accept_disabled;
                     59: ngx_file_t            ngx_accept_mutex_lock_file;
                     60: 
                     61: 
                     62: #if (NGX_STAT_STUB)
                     63: 
                     64: ngx_atomic_t   ngx_stat_accepted0;
                     65: ngx_atomic_t  *ngx_stat_accepted = &ngx_stat_accepted0;
                     66: ngx_atomic_t   ngx_stat_handled0;
                     67: ngx_atomic_t  *ngx_stat_handled = &ngx_stat_handled0;
                     68: ngx_atomic_t   ngx_stat_requests0;
                     69: ngx_atomic_t  *ngx_stat_requests = &ngx_stat_requests0;
                     70: ngx_atomic_t   ngx_stat_active0;
                     71: ngx_atomic_t  *ngx_stat_active = &ngx_stat_active0;
                     72: ngx_atomic_t   ngx_stat_reading0;
                     73: ngx_atomic_t  *ngx_stat_reading = &ngx_stat_reading0;
                     74: ngx_atomic_t   ngx_stat_writing0;
                     75: ngx_atomic_t  *ngx_stat_writing = &ngx_stat_writing0;
                     76: ngx_atomic_t   ngx_stat_waiting0;
                     77: ngx_atomic_t  *ngx_stat_waiting = &ngx_stat_waiting0;
                     78: 
                     79: #endif
                     80: 
                     81: 
                     82: 
                     83: static ngx_command_t  ngx_events_commands[] = {
                     84: 
                     85:     { ngx_string("events"),
                     86:       NGX_MAIN_CONF|NGX_CONF_BLOCK|NGX_CONF_NOARGS,
                     87:       ngx_events_block,
                     88:       0,
                     89:       0,
                     90:       NULL },
                     91: 
                     92:       ngx_null_command
                     93: };
                     94: 
                     95: 
                     96: static ngx_core_module_t  ngx_events_module_ctx = {
                     97:     ngx_string("events"),
                     98:     NULL,
                     99:     ngx_event_init_conf
                    100: };
                    101: 
                    102: 
                    103: ngx_module_t  ngx_events_module = {
                    104:     NGX_MODULE_V1,
                    105:     &ngx_events_module_ctx,                /* module context */
                    106:     ngx_events_commands,                   /* module directives */
                    107:     NGX_CORE_MODULE,                       /* module type */
                    108:     NULL,                                  /* init master */
                    109:     NULL,                                  /* init module */
                    110:     NULL,                                  /* init process */
                    111:     NULL,                                  /* init thread */
                    112:     NULL,                                  /* exit thread */
                    113:     NULL,                                  /* exit process */
                    114:     NULL,                                  /* exit master */
                    115:     NGX_MODULE_V1_PADDING
                    116: };
                    117: 
                    118: 
                    119: static ngx_str_t  event_core_name = ngx_string("event_core");
                    120: 
                    121: 
                    122: static ngx_command_t  ngx_event_core_commands[] = {
                    123: 
                    124:     { ngx_string("worker_connections"),
                    125:       NGX_EVENT_CONF|NGX_CONF_TAKE1,
                    126:       ngx_event_connections,
                    127:       0,
                    128:       0,
                    129:       NULL },
                    130: 
                    131:     { ngx_string("connections"),
                    132:       NGX_EVENT_CONF|NGX_CONF_TAKE1,
                    133:       ngx_event_connections,
                    134:       0,
                    135:       0,
                    136:       NULL },
                    137: 
                    138:     { ngx_string("use"),
                    139:       NGX_EVENT_CONF|NGX_CONF_TAKE1,
                    140:       ngx_event_use,
                    141:       0,
                    142:       0,
                    143:       NULL },
                    144: 
                    145:     { ngx_string("multi_accept"),
                    146:       NGX_EVENT_CONF|NGX_CONF_FLAG,
                    147:       ngx_conf_set_flag_slot,
                    148:       0,
                    149:       offsetof(ngx_event_conf_t, multi_accept),
                    150:       NULL },
                    151: 
                    152:     { ngx_string("accept_mutex"),
                    153:       NGX_EVENT_CONF|NGX_CONF_FLAG,
                    154:       ngx_conf_set_flag_slot,
                    155:       0,
                    156:       offsetof(ngx_event_conf_t, accept_mutex),
                    157:       NULL },
                    158: 
                    159:     { ngx_string("accept_mutex_delay"),
                    160:       NGX_EVENT_CONF|NGX_CONF_TAKE1,
                    161:       ngx_conf_set_msec_slot,
                    162:       0,
                    163:       offsetof(ngx_event_conf_t, accept_mutex_delay),
                    164:       NULL },
                    165: 
                    166:     { ngx_string("debug_connection"),
                    167:       NGX_EVENT_CONF|NGX_CONF_TAKE1,
                    168:       ngx_event_debug_connection,
                    169:       0,
                    170:       0,
                    171:       NULL },
                    172: 
                    173:       ngx_null_command
                    174: };
                    175: 
                    176: 
                    177: ngx_event_module_t  ngx_event_core_module_ctx = {
                    178:     &event_core_name,
                    179:     ngx_event_core_create_conf,            /* create configuration */
                    180:     ngx_event_core_init_conf,              /* init configuration */
                    181: 
                    182:     { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }
                    183: };
                    184: 
                    185: 
                    186: ngx_module_t  ngx_event_core_module = {
                    187:     NGX_MODULE_V1,
                    188:     &ngx_event_core_module_ctx,            /* module context */
                    189:     ngx_event_core_commands,               /* module directives */
                    190:     NGX_EVENT_MODULE,                      /* module type */
                    191:     NULL,                                  /* init master */
                    192:     ngx_event_module_init,                 /* init module */
                    193:     ngx_event_process_init,                /* init process */
                    194:     NULL,                                  /* init thread */
                    195:     NULL,                                  /* exit thread */
                    196:     NULL,                                  /* exit process */
                    197:     NULL,                                  /* exit master */
                    198:     NGX_MODULE_V1_PADDING
                    199: };
                    200: 
                    201: 
                    202: void
                    203: ngx_process_events_and_timers(ngx_cycle_t *cycle)
                    204: {
                    205:     ngx_uint_t  flags;
                    206:     ngx_msec_t  timer, delta;
                    207: 
                    208:     if (ngx_timer_resolution) {
                    209:         timer = NGX_TIMER_INFINITE;
                    210:         flags = 0;
                    211: 
                    212:     } else {
                    213:         timer = ngx_event_find_timer();
                    214:         flags = NGX_UPDATE_TIME;
                    215: 
                    216: #if (NGX_THREADS)
                    217: 
                    218:         if (timer == NGX_TIMER_INFINITE || timer > 500) {
                    219:             timer = 500;
                    220:         }
                    221: 
                    222: #endif
                    223:     }
                    224: 
                    225:     if (ngx_use_accept_mutex) {
                    226:         if (ngx_accept_disabled > 0) {
                    227:             ngx_accept_disabled--;
                    228: 
                    229:         } else {
                    230:             if (ngx_trylock_accept_mutex(cycle) == NGX_ERROR) {
                    231:                 return;
                    232:             }
                    233: 
                    234:             if (ngx_accept_mutex_held) {
                    235:                 flags |= NGX_POST_EVENTS;
                    236: 
                    237:             } else {
                    238:                 if (timer == NGX_TIMER_INFINITE
                    239:                     || timer > ngx_accept_mutex_delay)
                    240:                 {
                    241:                     timer = ngx_accept_mutex_delay;
                    242:                 }
                    243:             }
                    244:         }
                    245:     }
                    246: 
                    247:     delta = ngx_current_msec;
                    248: 
                    249:     (void) ngx_process_events(cycle, timer, flags);
                    250: 
                    251:     delta = ngx_current_msec - delta;
                    252: 
                    253:     ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
                    254:                    "timer delta: %M", delta);
                    255: 
                    256:     if (ngx_posted_accept_events) {
                    257:         ngx_event_process_posted(cycle, &ngx_posted_accept_events);
                    258:     }
                    259: 
                    260:     if (ngx_accept_mutex_held) {
                    261:         ngx_shmtx_unlock(&ngx_accept_mutex);
                    262:     }
                    263: 
                    264:     if (delta) {
                    265:         ngx_event_expire_timers();
                    266:     }
                    267: 
                    268:     ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
                    269:                    "posted events %p", ngx_posted_events);
                    270: 
                    271:     if (ngx_posted_events) {
                    272:         if (ngx_threaded) {
                    273:             ngx_wakeup_worker_thread(cycle);
                    274: 
                    275:         } else {
                    276:             ngx_event_process_posted(cycle, &ngx_posted_events);
                    277:         }
                    278:     }
                    279: }
                    280: 
                    281: 
                    282: ngx_int_t
                    283: ngx_handle_read_event(ngx_event_t *rev, ngx_uint_t flags)
                    284: {
                    285:     if (ngx_event_flags & NGX_USE_CLEAR_EVENT) {
                    286: 
                    287:         /* kqueue, epoll */
                    288: 
                    289:         if (!rev->active && !rev->ready) {
                    290:             if (ngx_add_event(rev, NGX_READ_EVENT, NGX_CLEAR_EVENT)
                    291:                 == NGX_ERROR)
                    292:             {
                    293:                 return NGX_ERROR;
                    294:             }
                    295:         }
                    296: 
                    297:         return NGX_OK;
                    298: 
                    299:     } else if (ngx_event_flags & NGX_USE_LEVEL_EVENT) {
                    300: 
                    301:         /* select, poll, /dev/poll */
                    302: 
                    303:         if (!rev->active && !rev->ready) {
                    304:             if (ngx_add_event(rev, NGX_READ_EVENT, NGX_LEVEL_EVENT)
                    305:                 == NGX_ERROR)
                    306:             {
                    307:                 return NGX_ERROR;
                    308:             }
                    309: 
                    310:             return NGX_OK;
                    311:         }
                    312: 
                    313:         if (rev->active && (rev->ready || (flags & NGX_CLOSE_EVENT))) {
                    314:             if (ngx_del_event(rev, NGX_READ_EVENT, NGX_LEVEL_EVENT | flags)
                    315:                 == NGX_ERROR)
                    316:             {
                    317:                 return NGX_ERROR;
                    318:             }
                    319: 
                    320:             return NGX_OK;
                    321:         }
                    322: 
                    323:     } else if (ngx_event_flags & NGX_USE_EVENTPORT_EVENT) {
                    324: 
                    325:         /* event ports */
                    326: 
                    327:         if (!rev->active && !rev->ready) {
                    328:             if (ngx_add_event(rev, NGX_READ_EVENT, 0) == NGX_ERROR) {
                    329:                 return NGX_ERROR;
                    330:             }
                    331: 
                    332:             return NGX_OK;
                    333:         }
                    334: 
                    335:         if (rev->oneshot && !rev->ready) {
                    336:             if (ngx_del_event(rev, NGX_READ_EVENT, 0) == NGX_ERROR) {
                    337:                 return NGX_ERROR;
                    338:             }
                    339: 
                    340:             return NGX_OK;
                    341:         }
                    342:     }
                    343: 
                    344:     /* aio, iocp, rtsig */
                    345: 
                    346:     return NGX_OK;
                    347: }
                    348: 
                    349: 
                    350: ngx_int_t
                    351: ngx_handle_write_event(ngx_event_t *wev, size_t lowat)
                    352: {
                    353:     ngx_connection_t  *c;
                    354: 
                    355:     if (lowat) {
                    356:         c = wev->data;
                    357: 
                    358:         if (ngx_send_lowat(c, lowat) == NGX_ERROR) {
                    359:             return NGX_ERROR;
                    360:         }
                    361:     }
                    362: 
                    363:     if (ngx_event_flags & NGX_USE_CLEAR_EVENT) {
                    364: 
                    365:         /* kqueue, epoll */
                    366: 
                    367:         if (!wev->active && !wev->ready) {
                    368:             if (ngx_add_event(wev, NGX_WRITE_EVENT,
                    369:                               NGX_CLEAR_EVENT | (lowat ? NGX_LOWAT_EVENT : 0))
                    370:                 == NGX_ERROR)
                    371:             {
                    372:                 return NGX_ERROR;
                    373:             }
                    374:         }
                    375: 
                    376:         return NGX_OK;
                    377: 
                    378:     } else if (ngx_event_flags & NGX_USE_LEVEL_EVENT) {
                    379: 
                    380:         /* select, poll, /dev/poll */
                    381: 
                    382:         if (!wev->active && !wev->ready) {
                    383:             if (ngx_add_event(wev, NGX_WRITE_EVENT, NGX_LEVEL_EVENT)
                    384:                 == NGX_ERROR)
                    385:             {
                    386:                 return NGX_ERROR;
                    387:             }
                    388: 
                    389:             return NGX_OK;
                    390:         }
                    391: 
                    392:         if (wev->active && wev->ready) {
                    393:             if (ngx_del_event(wev, NGX_WRITE_EVENT, NGX_LEVEL_EVENT)
                    394:                 == NGX_ERROR)
                    395:             {
                    396:                 return NGX_ERROR;
                    397:             }
                    398: 
                    399:             return NGX_OK;
                    400:         }
                    401: 
                    402:     } else if (ngx_event_flags & NGX_USE_EVENTPORT_EVENT) {
                    403: 
                    404:         /* event ports */
                    405: 
                    406:         if (!wev->active && !wev->ready) {
                    407:             if (ngx_add_event(wev, NGX_WRITE_EVENT, 0) == NGX_ERROR) {
                    408:                 return NGX_ERROR;
                    409:             }
                    410: 
                    411:             return NGX_OK;
                    412:         }
                    413: 
                    414:         if (wev->oneshot && wev->ready) {
                    415:             if (ngx_del_event(wev, NGX_WRITE_EVENT, 0) == NGX_ERROR) {
                    416:                 return NGX_ERROR;
                    417:             }
                    418: 
                    419:             return NGX_OK;
                    420:         }
                    421:     }
                    422: 
                    423:     /* aio, iocp, rtsig */
                    424: 
                    425:     return NGX_OK;
                    426: }
                    427: 
                    428: 
                    429: static char *
                    430: ngx_event_init_conf(ngx_cycle_t *cycle, void *conf)
                    431: {
                    432:     if (ngx_get_conf(cycle->conf_ctx, ngx_events_module) == NULL) {
                    433:         ngx_log_error(NGX_LOG_EMERG, cycle->log, 0,
                    434:                       "no \"events\" section in configuration");
                    435:         return NGX_CONF_ERROR;
                    436:     }
                    437: 
                    438:     return NGX_CONF_OK;
                    439: }
                    440: 
                    441: 
                    442: static ngx_int_t
                    443: ngx_event_module_init(ngx_cycle_t *cycle)
                    444: {
                    445:     void              ***cf;
                    446:     u_char              *shared;
                    447:     size_t               size, cl;
                    448:     ngx_shm_t            shm;
                    449:     ngx_time_t          *tp;
                    450:     ngx_core_conf_t     *ccf;
                    451:     ngx_event_conf_t    *ecf;
                    452: 
                    453:     cf = ngx_get_conf(cycle->conf_ctx, ngx_events_module);
                    454:     ecf = (*cf)[ngx_event_core_module.ctx_index];
                    455: 
                    456:     if (!ngx_test_config && ngx_process <= NGX_PROCESS_MASTER) {
                    457:         ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0,
                    458:                       "using the \"%s\" event method", ecf->name);
                    459:     }
                    460: 
                    461:     ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);
                    462: 
                    463:     ngx_timer_resolution = ccf->timer_resolution;
                    464: 
                    465: #if !(NGX_WIN32)
                    466:     {
                    467:     ngx_int_t      limit;
                    468:     struct rlimit  rlmt;
                    469: 
                    470:     if (getrlimit(RLIMIT_NOFILE, &rlmt) == -1) {
                    471:         ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
                    472:                       "getrlimit(RLIMIT_NOFILE) failed, ignored");
                    473: 
                    474:     } else {
                    475:         if (ecf->connections > (ngx_uint_t) rlmt.rlim_cur
                    476:             && (ccf->rlimit_nofile == NGX_CONF_UNSET
                    477:                 || ecf->connections > (ngx_uint_t) ccf->rlimit_nofile))
                    478:         {
                    479:             limit = (ccf->rlimit_nofile == NGX_CONF_UNSET) ?
                    480:                          (ngx_int_t) rlmt.rlim_cur : ccf->rlimit_nofile;
                    481: 
                    482:             ngx_log_error(NGX_LOG_WARN, cycle->log, 0,
                    483:                           "%ui worker_connections exceed "
                    484:                           "open file resource limit: %i",
                    485:                           ecf->connections, limit);
                    486:         }
                    487:     }
                    488:     }
                    489: #endif /* !(NGX_WIN32) */
                    490: 
                    491: 
                    492:     if (ccf->master == 0) {
                    493:         return NGX_OK;
                    494:     }
                    495: 
                    496:     if (ngx_accept_mutex_ptr) {
                    497:         return NGX_OK;
                    498:     }
                    499: 
                    500: 
                    501:     /* cl should be equal to or greater than cache line size */
                    502: 
                    503:     cl = 128;
                    504: 
                    505:     size = cl            /* ngx_accept_mutex */
                    506:            + cl          /* ngx_connection_counter */
                    507:            + cl;         /* ngx_temp_number */
                    508: 
                    509: #if (NGX_STAT_STUB)
                    510: 
                    511:     size += cl           /* ngx_stat_accepted */
                    512:            + cl          /* ngx_stat_handled */
                    513:            + cl          /* ngx_stat_requests */
                    514:            + cl          /* ngx_stat_active */
                    515:            + cl          /* ngx_stat_reading */
                    516:            + cl          /* ngx_stat_writing */
                    517:            + cl;         /* ngx_stat_waiting */
                    518: 
                    519: #endif
                    520: 
                    521:     shm.size = size;
                    522:     shm.name.len = sizeof("nginx_shared_zone");
                    523:     shm.name.data = (u_char *) "nginx_shared_zone";
                    524:     shm.log = cycle->log;
                    525: 
                    526:     if (ngx_shm_alloc(&shm) != NGX_OK) {
                    527:         return NGX_ERROR;
                    528:     }
                    529: 
                    530:     shared = shm.addr;
                    531: 
                    532:     ngx_accept_mutex_ptr = (ngx_atomic_t *) shared;
                    533:     ngx_accept_mutex.spin = (ngx_uint_t) -1;
                    534: 
                    535:     if (ngx_shmtx_create(&ngx_accept_mutex, (ngx_shmtx_sh_t *) shared,
                    536:                          cycle->lock_file.data)
                    537:         != NGX_OK)
                    538:     {
                    539:         return NGX_ERROR;
                    540:     }
                    541: 
                    542:     ngx_connection_counter = (ngx_atomic_t *) (shared + 1 * cl);
                    543: 
                    544:     (void) ngx_atomic_cmp_set(ngx_connection_counter, 0, 1);
                    545: 
                    546:     ngx_log_debug2(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
                    547:                    "counter: %p, %d",
                    548:                    ngx_connection_counter, *ngx_connection_counter);
                    549: 
                    550:     ngx_temp_number = (ngx_atomic_t *) (shared + 2 * cl);
                    551: 
                    552:     tp = ngx_timeofday();
                    553: 
                    554:     ngx_random_number = (tp->msec << 16) + ngx_pid;
                    555: 
                    556: #if (NGX_STAT_STUB)
                    557: 
                    558:     ngx_stat_accepted = (ngx_atomic_t *) (shared + 3 * cl);
                    559:     ngx_stat_handled = (ngx_atomic_t *) (shared + 4 * cl);
                    560:     ngx_stat_requests = (ngx_atomic_t *) (shared + 5 * cl);
                    561:     ngx_stat_active = (ngx_atomic_t *) (shared + 6 * cl);
                    562:     ngx_stat_reading = (ngx_atomic_t *) (shared + 7 * cl);
                    563:     ngx_stat_writing = (ngx_atomic_t *) (shared + 8 * cl);
                    564:     ngx_stat_waiting = (ngx_atomic_t *) (shared + 9 * cl);
                    565: 
                    566: #endif
                    567: 
                    568:     return NGX_OK;
                    569: }
                    570: 
                    571: 
                    572: #if !(NGX_WIN32)
                    573: 
                    574: static void
                    575: ngx_timer_signal_handler(int signo)
                    576: {
                    577:     ngx_event_timer_alarm = 1;
                    578: 
                    579: #if 1
                    580:     ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ngx_cycle->log, 0, "timer signal");
                    581: #endif
                    582: }
                    583: 
                    584: #endif
                    585: 
                    586: 
                    587: static ngx_int_t
                    588: ngx_event_process_init(ngx_cycle_t *cycle)
                    589: {
                    590:     ngx_uint_t           m, i;
                    591:     ngx_event_t         *rev, *wev;
                    592:     ngx_listening_t     *ls;
                    593:     ngx_connection_t    *c, *next, *old;
                    594:     ngx_core_conf_t     *ccf;
                    595:     ngx_event_conf_t    *ecf;
                    596:     ngx_event_module_t  *module;
                    597: 
                    598:     ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);
                    599:     ecf = ngx_event_get_conf(cycle->conf_ctx, ngx_event_core_module);
                    600: 
                    601:     if (ccf->master && ccf->worker_processes > 1 && ecf->accept_mutex) {
                    602:         ngx_use_accept_mutex = 1;
                    603:         ngx_accept_mutex_held = 0;
                    604:         ngx_accept_mutex_delay = ecf->accept_mutex_delay;
                    605: 
                    606:     } else {
                    607:         ngx_use_accept_mutex = 0;
                    608:     }
                    609: 
                    610: #if (NGX_WIN32)
                    611: 
                    612:     /*
                    613:      * disable accept mutex on win32 as it may cause deadlock if
                    614:      * grabbed by a process which can't accept connections
                    615:      */
                    616: 
                    617:     ngx_use_accept_mutex = 0;
                    618: 
                    619: #endif
                    620: 
                    621: #if (NGX_THREADS)
                    622:     ngx_posted_events_mutex = ngx_mutex_init(cycle->log, 0);
                    623:     if (ngx_posted_events_mutex == NULL) {
                    624:         return NGX_ERROR;
                    625:     }
                    626: #endif
                    627: 
                    628:     if (ngx_event_timer_init(cycle->log) == NGX_ERROR) {
                    629:         return NGX_ERROR;
                    630:     }
                    631: 
                    632:     for (m = 0; ngx_modules[m]; m++) {
                    633:         if (ngx_modules[m]->type != NGX_EVENT_MODULE) {
                    634:             continue;
                    635:         }
                    636: 
                    637:         if (ngx_modules[m]->ctx_index != ecf->use) {
                    638:             continue;
                    639:         }
                    640: 
                    641:         module = ngx_modules[m]->ctx;
                    642: 
                    643:         if (module->actions.init(cycle, ngx_timer_resolution) != NGX_OK) {
                    644:             /* fatal */
                    645:             exit(2);
                    646:         }
                    647: 
                    648:         break;
                    649:     }
                    650: 
                    651: #if !(NGX_WIN32)
                    652: 
                    653:     if (ngx_timer_resolution && !(ngx_event_flags & NGX_USE_TIMER_EVENT)) {
                    654:         struct sigaction  sa;
                    655:         struct itimerval  itv;
                    656: 
                    657:         ngx_memzero(&sa, sizeof(struct sigaction));
                    658:         sa.sa_handler = ngx_timer_signal_handler;
                    659:         sigemptyset(&sa.sa_mask);
                    660: 
                    661:         if (sigaction(SIGALRM, &sa, NULL) == -1) {
                    662:             ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
                    663:                           "sigaction(SIGALRM) failed");
                    664:             return NGX_ERROR;
                    665:         }
                    666: 
                    667:         itv.it_interval.tv_sec = ngx_timer_resolution / 1000;
                    668:         itv.it_interval.tv_usec = (ngx_timer_resolution % 1000) * 1000;
                    669:         itv.it_value.tv_sec = ngx_timer_resolution / 1000;
                    670:         itv.it_value.tv_usec = (ngx_timer_resolution % 1000 ) * 1000;
                    671: 
                    672:         if (setitimer(ITIMER_REAL, &itv, NULL) == -1) {
                    673:             ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
                    674:                           "setitimer() failed");
                    675:         }
                    676:     }
                    677: 
                    678:     if (ngx_event_flags & NGX_USE_FD_EVENT) {
                    679:         struct rlimit  rlmt;
                    680: 
                    681:         if (getrlimit(RLIMIT_NOFILE, &rlmt) == -1) {
                    682:             ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
                    683:                           "getrlimit(RLIMIT_NOFILE) failed");
                    684:             return NGX_ERROR;
                    685:         }
                    686: 
                    687:         cycle->files_n = (ngx_uint_t) rlmt.rlim_cur;
                    688: 
                    689:         cycle->files = ngx_calloc(sizeof(ngx_connection_t *) * cycle->files_n,
                    690:                                   cycle->log);
                    691:         if (cycle->files == NULL) {
                    692:             return NGX_ERROR;
                    693:         }
                    694:     }
                    695: 
                    696: #endif
                    697: 
                    698:     cycle->connections =
                    699:         ngx_alloc(sizeof(ngx_connection_t) * cycle->connection_n, cycle->log);
                    700:     if (cycle->connections == NULL) {
                    701:         return NGX_ERROR;
                    702:     }
                    703: 
                    704:     c = cycle->connections;
                    705: 
                    706:     cycle->read_events = ngx_alloc(sizeof(ngx_event_t) * cycle->connection_n,
                    707:                                    cycle->log);
                    708:     if (cycle->read_events == NULL) {
                    709:         return NGX_ERROR;
                    710:     }
                    711: 
                    712:     rev = cycle->read_events;
                    713:     for (i = 0; i < cycle->connection_n; i++) {
                    714:         rev[i].closed = 1;
                    715:         rev[i].instance = 1;
                    716: #if (NGX_THREADS)
                    717:         rev[i].lock = &c[i].lock;
                    718:         rev[i].own_lock = &c[i].lock;
                    719: #endif
                    720:     }
                    721: 
                    722:     cycle->write_events = ngx_alloc(sizeof(ngx_event_t) * cycle->connection_n,
                    723:                                     cycle->log);
                    724:     if (cycle->write_events == NULL) {
                    725:         return NGX_ERROR;
                    726:     }
                    727: 
                    728:     wev = cycle->write_events;
                    729:     for (i = 0; i < cycle->connection_n; i++) {
                    730:         wev[i].closed = 1;
                    731: #if (NGX_THREADS)
                    732:         wev[i].lock = &c[i].lock;
                    733:         wev[i].own_lock = &c[i].lock;
                    734: #endif
                    735:     }
                    736: 
                    737:     i = cycle->connection_n;
                    738:     next = NULL;
                    739: 
                    740:     do {
                    741:         i--;
                    742: 
                    743:         c[i].data = next;
                    744:         c[i].read = &cycle->read_events[i];
                    745:         c[i].write = &cycle->write_events[i];
                    746:         c[i].fd = (ngx_socket_t) -1;
                    747: 
                    748:         next = &c[i];
                    749: 
                    750: #if (NGX_THREADS)
                    751:         c[i].lock = 0;
                    752: #endif
                    753:     } while (i);
                    754: 
                    755:     cycle->free_connections = next;
                    756:     cycle->free_connection_n = cycle->connection_n;
                    757: 
                    758:     /* for each listening socket */
                    759: 
                    760:     ls = cycle->listening.elts;
                    761:     for (i = 0; i < cycle->listening.nelts; i++) {
                    762: 
                    763:         c = ngx_get_connection(ls[i].fd, cycle->log);
                    764: 
                    765:         if (c == NULL) {
                    766:             return NGX_ERROR;
                    767:         }
                    768: 
                    769:         c->log = &ls[i].log;
                    770: 
                    771:         c->listening = &ls[i];
                    772:         ls[i].connection = c;
                    773: 
                    774:         rev = c->read;
                    775: 
                    776:         rev->log = c->log;
                    777:         rev->accept = 1;
                    778: 
                    779: #if (NGX_HAVE_DEFERRED_ACCEPT)
                    780:         rev->deferred_accept = ls[i].deferred_accept;
                    781: #endif
                    782: 
                    783:         if (!(ngx_event_flags & NGX_USE_IOCP_EVENT)) {
                    784:             if (ls[i].previous) {
                    785: 
                    786:                 /*
                    787:                  * delete the old accept events that were bound to
                    788:                  * the old cycle read events array
                    789:                  */
                    790: 
                    791:                 old = ls[i].previous->connection;
                    792: 
                    793:                 if (ngx_del_event(old->read, NGX_READ_EVENT, NGX_CLOSE_EVENT)
                    794:                     == NGX_ERROR)
                    795:                 {
                    796:                     return NGX_ERROR;
                    797:                 }
                    798: 
                    799:                 old->fd = (ngx_socket_t) -1;
                    800:             }
                    801:         }
                    802: 
                    803: #if (NGX_WIN32)
                    804: 
                    805:         if (ngx_event_flags & NGX_USE_IOCP_EVENT) {
                    806:             ngx_iocp_conf_t  *iocpcf;
                    807: 
                    808:             rev->handler = ngx_event_acceptex;
                    809: 
                    810:             if (ngx_use_accept_mutex) {
                    811:                 continue;
                    812:             }
                    813: 
                    814:             if (ngx_add_event(rev, 0, NGX_IOCP_ACCEPT) == NGX_ERROR) {
                    815:                 return NGX_ERROR;
                    816:             }
                    817: 
                    818:             ls[i].log.handler = ngx_acceptex_log_error;
                    819: 
                    820:             iocpcf = ngx_event_get_conf(cycle->conf_ctx, ngx_iocp_module);
                    821:             if (ngx_event_post_acceptex(&ls[i], iocpcf->post_acceptex)
                    822:                 == NGX_ERROR)
                    823:             {
                    824:                 return NGX_ERROR;
                    825:             }
                    826: 
                    827:         } else {
                    828:             rev->handler = ngx_event_accept;
                    829: 
                    830:             if (ngx_use_accept_mutex) {
                    831:                 continue;
                    832:             }
                    833: 
                    834:             if (ngx_add_event(rev, NGX_READ_EVENT, 0) == NGX_ERROR) {
                    835:                 return NGX_ERROR;
                    836:             }
                    837:         }
                    838: 
                    839: #else
                    840: 
                    841:         rev->handler = ngx_event_accept;
                    842: 
                    843:         if (ngx_use_accept_mutex) {
                    844:             continue;
                    845:         }
                    846: 
                    847:         if (ngx_event_flags & NGX_USE_RTSIG_EVENT) {
                    848:             if (ngx_add_conn(c) == NGX_ERROR) {
                    849:                 return NGX_ERROR;
                    850:             }
                    851: 
                    852:         } else {
                    853:             if (ngx_add_event(rev, NGX_READ_EVENT, 0) == NGX_ERROR) {
                    854:                 return NGX_ERROR;
                    855:             }
                    856:         }
                    857: 
                    858: #endif
                    859: 
                    860:     }
                    861: 
                    862:     return NGX_OK;
                    863: }
                    864: 
                    865: 
                    866: ngx_int_t
                    867: ngx_send_lowat(ngx_connection_t *c, size_t lowat)
                    868: {
                    869:     int  sndlowat;
                    870: 
                    871: #if (NGX_HAVE_LOWAT_EVENT)
                    872: 
                    873:     if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) {
                    874:         c->write->available = lowat;
                    875:         return NGX_OK;
                    876:     }
                    877: 
                    878: #endif
                    879: 
                    880:     if (lowat == 0 || c->sndlowat) {
                    881:         return NGX_OK;
                    882:     }
                    883: 
                    884:     sndlowat = (int) lowat;
                    885: 
                    886:     if (setsockopt(c->fd, SOL_SOCKET, SO_SNDLOWAT,
                    887:                    (const void *) &sndlowat, sizeof(int))
                    888:         == -1)
                    889:     {
                    890:         ngx_connection_error(c, ngx_socket_errno,
                    891:                              "setsockopt(SO_SNDLOWAT) failed");
                    892:         return NGX_ERROR;
                    893:     }
                    894: 
                    895:     c->sndlowat = 1;
                    896: 
                    897:     return NGX_OK;
                    898: }
                    899: 
                    900: 
                    901: static char *
                    902: ngx_events_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
                    903: {
                    904:     char                 *rv;
                    905:     void               ***ctx;
                    906:     ngx_uint_t            i;
                    907:     ngx_conf_t            pcf;
                    908:     ngx_event_module_t   *m;
                    909: 
                    910:     if (*(void **) conf) {
                    911:         return "is duplicate";
                    912:     }
                    913: 
                    914:     /* count the number of the event modules and set up their indices */
                    915: 
                    916:     ngx_event_max_module = 0;
                    917:     for (i = 0; ngx_modules[i]; i++) {
                    918:         if (ngx_modules[i]->type != NGX_EVENT_MODULE) {
                    919:             continue;
                    920:         }
                    921: 
                    922:         ngx_modules[i]->ctx_index = ngx_event_max_module++;
                    923:     }
                    924: 
                    925:     ctx = ngx_pcalloc(cf->pool, sizeof(void *));
                    926:     if (ctx == NULL) {
                    927:         return NGX_CONF_ERROR;
                    928:     }
                    929: 
                    930:     *ctx = ngx_pcalloc(cf->pool, ngx_event_max_module * sizeof(void *));
                    931:     if (*ctx == NULL) {
                    932:         return NGX_CONF_ERROR;
                    933:     }
                    934: 
                    935:     *(void **) conf = ctx;
                    936: 
                    937:     for (i = 0; ngx_modules[i]; i++) {
                    938:         if (ngx_modules[i]->type != NGX_EVENT_MODULE) {
                    939:             continue;
                    940:         }
                    941: 
                    942:         m = ngx_modules[i]->ctx;
                    943: 
                    944:         if (m->create_conf) {
                    945:             (*ctx)[ngx_modules[i]->ctx_index] = m->create_conf(cf->cycle);
                    946:             if ((*ctx)[ngx_modules[i]->ctx_index] == NULL) {
                    947:                 return NGX_CONF_ERROR;
                    948:             }
                    949:         }
                    950:     }
                    951: 
                    952:     pcf = *cf;
                    953:     cf->ctx = ctx;
                    954:     cf->module_type = NGX_EVENT_MODULE;
                    955:     cf->cmd_type = NGX_EVENT_CONF;
                    956: 
                    957:     rv = ngx_conf_parse(cf, NULL);
                    958: 
                    959:     *cf = pcf;
                    960: 
                    961:     if (rv != NGX_CONF_OK)
                    962:         return rv;
                    963: 
                    964:     for (i = 0; ngx_modules[i]; i++) {
                    965:         if (ngx_modules[i]->type != NGX_EVENT_MODULE) {
                    966:             continue;
                    967:         }
                    968: 
                    969:         m = ngx_modules[i]->ctx;
                    970: 
                    971:         if (m->init_conf) {
                    972:             rv = m->init_conf(cf->cycle, (*ctx)[ngx_modules[i]->ctx_index]);
                    973:             if (rv != NGX_CONF_OK) {
                    974:                 return rv;
                    975:             }
                    976:         }
                    977:     }
                    978: 
                    979:     return NGX_CONF_OK;
                    980: }
                    981: 
                    982: 
                    983: static char *
                    984: ngx_event_connections(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
                    985: {
                    986:     ngx_event_conf_t  *ecf = conf;
                    987: 
                    988:     ngx_str_t  *value;
                    989: 
                    990:     if (ecf->connections != NGX_CONF_UNSET_UINT) {
                    991:         return "is duplicate";
                    992:     }
                    993: 
                    994:     if (ngx_strcmp(cmd->name.data, "connections") == 0) {
                    995:         ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
                    996:                            "the \"connections\" directive is deprecated, "
                    997:                            "use the \"worker_connections\" directive instead");
                    998:     }
                    999: 
                   1000:     value = cf->args->elts;
                   1001:     ecf->connections = ngx_atoi(value[1].data, value[1].len);
                   1002:     if (ecf->connections == (ngx_uint_t) NGX_ERROR) {
                   1003:         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                   1004:                            "invalid number \"%V\"", &value[1]);
                   1005: 
                   1006:         return NGX_CONF_ERROR;
                   1007:     }
                   1008: 
                   1009:     cf->cycle->connection_n = ecf->connections;
                   1010: 
                   1011:     return NGX_CONF_OK;
                   1012: }
                   1013: 
                   1014: 
                   1015: static char *
                   1016: ngx_event_use(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
                   1017: {
                   1018:     ngx_event_conf_t  *ecf = conf;
                   1019: 
                   1020:     ngx_int_t             m;
                   1021:     ngx_str_t            *value;
                   1022:     ngx_event_conf_t     *old_ecf;
                   1023:     ngx_event_module_t   *module;
                   1024: 
                   1025:     if (ecf->use != NGX_CONF_UNSET_UINT) {
                   1026:         return "is duplicate";
                   1027:     }
                   1028: 
                   1029:     value = cf->args->elts;
                   1030: 
                   1031:     if (cf->cycle->old_cycle->conf_ctx) {
                   1032:         old_ecf = ngx_event_get_conf(cf->cycle->old_cycle->conf_ctx,
                   1033:                                      ngx_event_core_module);
                   1034:     } else {
                   1035:         old_ecf = NULL;
                   1036:     }
                   1037: 
                   1038: 
                   1039:     for (m = 0; ngx_modules[m]; m++) {
                   1040:         if (ngx_modules[m]->type != NGX_EVENT_MODULE) {
                   1041:             continue;
                   1042:         }
                   1043: 
                   1044:         module = ngx_modules[m]->ctx;
                   1045:         if (module->name->len == value[1].len) {
                   1046:             if (ngx_strcmp(module->name->data, value[1].data) == 0) {
                   1047:                 ecf->use = ngx_modules[m]->ctx_index;
                   1048:                 ecf->name = module->name->data;
                   1049: 
                   1050:                 if (ngx_process == NGX_PROCESS_SINGLE
                   1051:                     && old_ecf
                   1052:                     && old_ecf->use != ecf->use)
                   1053:                 {
                   1054:                     ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                   1055:                                "when the server runs without a master process "
                   1056:                                "the \"%V\" event type must be the same as "
                   1057:                                "in previous configuration - \"%s\" "
                   1058:                                "and it cannot be changed on the fly, "
                   1059:                                "to change it you need to stop server "
                   1060:                                "and start it again",
                   1061:                                &value[1], old_ecf->name);
                   1062: 
                   1063:                     return NGX_CONF_ERROR;
                   1064:                 }
                   1065: 
                   1066:                 return NGX_CONF_OK;
                   1067:             }
                   1068:         }
                   1069:     }
                   1070: 
                   1071:     ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                   1072:                        "invalid event type \"%V\"", &value[1]);
                   1073: 
                   1074:     return NGX_CONF_ERROR;
                   1075: }
                   1076: 
                   1077: 
                   1078: static char *
                   1079: ngx_event_debug_connection(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
                   1080: {
                   1081: #if (NGX_DEBUG)
                   1082:     ngx_event_conf_t  *ecf = conf;
                   1083: 
                   1084:     ngx_int_t             rc;
                   1085:     ngx_str_t            *value;
                   1086:     ngx_url_t             u;
                   1087:     ngx_cidr_t            c, *cidr;
                   1088:     ngx_uint_t            i;
                   1089:     struct sockaddr_in   *sin;
                   1090: #if (NGX_HAVE_INET6)
                   1091:     struct sockaddr_in6  *sin6;
                   1092: #endif
                   1093: 
                   1094:     value = cf->args->elts;
                   1095: 
                   1096: #if (NGX_HAVE_UNIX_DOMAIN)
                   1097: 
                   1098:     if (ngx_strcmp(value[1].data, "unix:") == 0) {
                   1099:         cidr = ngx_array_push(&ecf->debug_connection);
                   1100:         if (cidr == NULL) {
                   1101:             return NGX_CONF_ERROR;
                   1102:         }
                   1103: 
                   1104:         cidr->family = AF_UNIX;
                   1105:         return NGX_CONF_OK;
                   1106:     }
                   1107: 
                   1108: #endif
                   1109: 
                   1110:     rc = ngx_ptocidr(&value[1], &c);
                   1111: 
                   1112:     if (rc != NGX_ERROR) {
                   1113:         if (rc == NGX_DONE) {
                   1114:             ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
                   1115:                                "low address bits of %V are meaningless",
                   1116:                                &value[1]);
                   1117:         }
                   1118: 
                   1119:         cidr = ngx_array_push(&ecf->debug_connection);
                   1120:         if (cidr == NULL) {
                   1121:             return NGX_CONF_ERROR;
                   1122:         }
                   1123: 
                   1124:         *cidr = c;
                   1125: 
                   1126:         return NGX_CONF_OK;
                   1127:     }
                   1128: 
                   1129:     ngx_memzero(&u, sizeof(ngx_url_t));
                   1130:     u.host = value[1];
                   1131: 
                   1132:     if (ngx_inet_resolve_host(cf->pool, &u) != NGX_OK) {
                   1133:         if (u.err) {
                   1134:             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                   1135:                                "%s in debug_connection \"%V\"",
                   1136:                                u.err, &u.host);
                   1137:         }
                   1138: 
                   1139:         return NGX_CONF_ERROR;
                   1140:     }
                   1141: 
                   1142:     cidr = ngx_array_push_n(&ecf->debug_connection, u.naddrs);
                   1143:     if (cidr == NULL) {
                   1144:         return NGX_CONF_ERROR;
                   1145:     }
                   1146: 
                   1147:     ngx_memzero(cidr, u.naddrs * sizeof(ngx_cidr_t));
                   1148: 
                   1149:     for (i = 0; i < u.naddrs; i++) {
                   1150:         cidr[i].family = u.addrs[i].sockaddr->sa_family;
                   1151: 
                   1152:         switch (cidr[i].family) {
                   1153: 
                   1154: #if (NGX_HAVE_INET6)
                   1155:         case AF_INET6:
                   1156:             sin6 = (struct sockaddr_in6 *) u.addrs[i].sockaddr;
                   1157:             cidr[i].u.in6.addr = sin6->sin6_addr;
                   1158:             ngx_memset(cidr[i].u.in6.mask.s6_addr, 0xff, 16);
                   1159:             break;
                   1160: #endif
                   1161: 
                   1162:         default: /* AF_INET */
                   1163:             sin = (struct sockaddr_in *) u.addrs[i].sockaddr;
                   1164:             cidr[i].u.in.addr = sin->sin_addr.s_addr;
                   1165:             cidr[i].u.in.mask = 0xffffffff;
                   1166:             break;
                   1167:         }
                   1168:     }
                   1169: 
                   1170: #else
                   1171: 
                   1172:     ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
                   1173:                        "\"debug_connection\" is ignored, you need to rebuild "
                   1174:                        "nginx using --with-debug option to enable it");
                   1175: 
                   1176: #endif
                   1177: 
                   1178:     return NGX_CONF_OK;
                   1179: }
                   1180: 
                   1181: 
                   1182: static void *
                   1183: ngx_event_core_create_conf(ngx_cycle_t *cycle)
                   1184: {
                   1185:     ngx_event_conf_t  *ecf;
                   1186: 
                   1187:     ecf = ngx_palloc(cycle->pool, sizeof(ngx_event_conf_t));
                   1188:     if (ecf == NULL) {
                   1189:         return NULL;
                   1190:     }
                   1191: 
                   1192:     ecf->connections = NGX_CONF_UNSET_UINT;
                   1193:     ecf->use = NGX_CONF_UNSET_UINT;
                   1194:     ecf->multi_accept = NGX_CONF_UNSET;
                   1195:     ecf->accept_mutex = NGX_CONF_UNSET;
                   1196:     ecf->accept_mutex_delay = NGX_CONF_UNSET_MSEC;
                   1197:     ecf->name = (void *) NGX_CONF_UNSET;
                   1198: 
                   1199: #if (NGX_DEBUG)
                   1200: 
                   1201:     if (ngx_array_init(&ecf->debug_connection, cycle->pool, 4,
                   1202:                        sizeof(ngx_cidr_t)) == NGX_ERROR)
                   1203:     {
                   1204:         return NULL;
                   1205:     }
                   1206: 
                   1207: #endif
                   1208: 
                   1209:     return ecf;
                   1210: }
                   1211: 
                   1212: 
                   1213: static char *
                   1214: ngx_event_core_init_conf(ngx_cycle_t *cycle, void *conf)
                   1215: {
                   1216:     ngx_event_conf_t  *ecf = conf;
                   1217: 
                   1218: #if (NGX_HAVE_EPOLL) && !(NGX_TEST_BUILD_EPOLL)
                   1219:     int                  fd;
                   1220: #endif
                   1221: #if (NGX_HAVE_RTSIG)
                   1222:     ngx_uint_t           rtsig;
                   1223:     ngx_core_conf_t     *ccf;
                   1224: #endif
                   1225:     ngx_int_t            i;
                   1226:     ngx_module_t        *module;
                   1227:     ngx_event_module_t  *event_module;
                   1228: 
                   1229:     module = NULL;
                   1230: 
                   1231: #if (NGX_HAVE_EPOLL) && !(NGX_TEST_BUILD_EPOLL)
                   1232: 
                   1233:     fd = epoll_create(100);
                   1234: 
                   1235:     if (fd != -1) {
                   1236:         (void) close(fd);
                   1237:         module = &ngx_epoll_module;
                   1238: 
                   1239:     } else if (ngx_errno != NGX_ENOSYS) {
                   1240:         module = &ngx_epoll_module;
                   1241:     }
                   1242: 
                   1243: #endif
                   1244: 
                   1245: #if (NGX_HAVE_RTSIG)
                   1246: 
                   1247:     if (module == NULL) {
                   1248:         module = &ngx_rtsig_module;
                   1249:         rtsig = 1;
                   1250: 
                   1251:     } else {
                   1252:         rtsig = 0;
                   1253:     }
                   1254: 
                   1255: #endif
                   1256: 
                   1257: #if (NGX_HAVE_DEVPOLL)
                   1258: 
                   1259:     module = &ngx_devpoll_module;
                   1260: 
                   1261: #endif
                   1262: 
                   1263: #if (NGX_HAVE_KQUEUE)
                   1264: 
                   1265:     module = &ngx_kqueue_module;
                   1266: 
                   1267: #endif
                   1268: 
                   1269: #if (NGX_HAVE_SELECT)
                   1270: 
                   1271:     if (module == NULL) {
                   1272:         module = &ngx_select_module;
                   1273:     }
                   1274: 
                   1275: #endif
                   1276: 
                   1277:     if (module == NULL) {
                   1278:         for (i = 0; ngx_modules[i]; i++) {
                   1279: 
                   1280:             if (ngx_modules[i]->type != NGX_EVENT_MODULE) {
                   1281:                 continue;
                   1282:             }
                   1283: 
                   1284:             event_module = ngx_modules[i]->ctx;
                   1285: 
                   1286:             if (ngx_strcmp(event_module->name->data, event_core_name.data) == 0)
                   1287:             {
                   1288:                 continue;
                   1289:             }
                   1290: 
                   1291:             module = ngx_modules[i];
                   1292:             break;
                   1293:         }
                   1294:     }
                   1295: 
                   1296:     if (module == NULL) {
                   1297:         ngx_log_error(NGX_LOG_EMERG, cycle->log, 0, "no events module found");
                   1298:         return NGX_CONF_ERROR;
                   1299:     }
                   1300: 
                   1301:     ngx_conf_init_uint_value(ecf->connections, DEFAULT_CONNECTIONS);
                   1302:     cycle->connection_n = ecf->connections;
                   1303: 
                   1304:     ngx_conf_init_uint_value(ecf->use, module->ctx_index);
                   1305: 
                   1306:     event_module = module->ctx;
                   1307:     ngx_conf_init_ptr_value(ecf->name, event_module->name->data);
                   1308: 
                   1309:     ngx_conf_init_value(ecf->multi_accept, 0);
                   1310:     ngx_conf_init_value(ecf->accept_mutex, 1);
                   1311:     ngx_conf_init_msec_value(ecf->accept_mutex_delay, 500);
                   1312: 
                   1313: 
                   1314: #if (NGX_HAVE_RTSIG)
                   1315: 
                   1316:     if (!rtsig) {
                   1317:         return NGX_CONF_OK;
                   1318:     }
                   1319: 
                   1320:     if (ecf->accept_mutex) {
                   1321:         return NGX_CONF_OK;
                   1322:     }
                   1323: 
                   1324:     ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);
                   1325: 
                   1326:     if (ccf->worker_processes == 0) {
                   1327:         return NGX_CONF_OK;
                   1328:     }
                   1329: 
                   1330:     ngx_log_error(NGX_LOG_EMERG, cycle->log, 0,
                   1331:                   "the \"rtsig\" method requires \"accept_mutex\" to be on");
                   1332: 
                   1333:     return NGX_CONF_ERROR;
                   1334: 
                   1335: #else
                   1336: 
                   1337:     return NGX_CONF_OK;
                   1338: 
                   1339: #endif
                   1340: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>