Annotation of embedaddon/nginx/src/event/ngx_event.c, revision 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>