comparison src/event/modules/ngx_epoll_module.c @ 112:408f195b3482 NGINX_0_3_3

nginx 0.3.3 *) Change: the "bl" and "af" parameters of the "listen" directive was renamed to the "backlog" and "accept_filter". *) Feature: the "rcvbuf" and "sndbuf" parameters of the "listen" directive. *) Change: the "$msec" log parameter does not require now the additional the gettimeofday() system call. *) Feature: the -t switch now tests the "listen" directives. *) Bugfix: if the invalid address was specified in the "listen" directive, then after the -HUP signal nginx left an open socket in the CLOSED state. *) Bugfix: the mime type may be incorrectly set to default value for index file with variable in the name; bug appeared in 0.3.0. *) Feature: the "timer_resolution" directive. *) Feature: the millisecond "$upstream_response_time" log parameter. *) Bugfix: a temporary file with client request body now is removed just after the response header was transferred to a client. *) Bugfix: OpenSSL 0.9.6 compatibility. *) Bugfix: the SSL certificate and key file paths could not be relative. *) Bugfix: the "ssl_prefer_server_ciphers" directive did not work in the ngx_imap_ssl_module. *) Bugfix: the "ssl_protocols" directive allowed to specify the single protocol only.
author Igor Sysoev <http://sysoev.ru>
date Wed, 19 Oct 2005 00:00:00 +0400
parents cf3d6edb3ad6
children e38f51cd0905
comparison
equal deleted inserted replaced
111:a175b609c76d 112:408f195b3482
68 typedef struct { 68 typedef struct {
69 u_int events; 69 u_int events;
70 } ngx_epoll_conf_t; 70 } ngx_epoll_conf_t;
71 71
72 72
73 static ngx_int_t ngx_epoll_init(ngx_cycle_t *cycle); 73 static ngx_int_t ngx_epoll_init(ngx_cycle_t *cycle, ngx_msec_t timer);
74 static void ngx_epoll_done(ngx_cycle_t *cycle); 74 static void ngx_epoll_done(ngx_cycle_t *cycle);
75 static ngx_int_t ngx_epoll_add_event(ngx_event_t *ev, int event, u_int flags); 75 static ngx_int_t ngx_epoll_add_event(ngx_event_t *ev, int event, u_int flags);
76 static ngx_int_t ngx_epoll_del_event(ngx_event_t *ev, int event, u_int flags); 76 static ngx_int_t ngx_epoll_del_event(ngx_event_t *ev, int event, u_int flags);
77 static ngx_int_t ngx_epoll_add_connection(ngx_connection_t *c); 77 static ngx_int_t ngx_epoll_add_connection(ngx_connection_t *c);
78 static ngx_int_t ngx_epoll_del_connection(ngx_connection_t *c, u_int flags); 78 static ngx_int_t ngx_epoll_del_connection(ngx_connection_t *c, u_int flags);
79 static ngx_int_t ngx_epoll_process_events(ngx_cycle_t *cycle); 79 static ngx_int_t ngx_epoll_process_events(ngx_cycle_t *cycle, ngx_msec_t timer,
80 ngx_uint_t flags);
80 81
81 static void *ngx_epoll_create_conf(ngx_cycle_t *cycle); 82 static void *ngx_epoll_create_conf(ngx_cycle_t *cycle);
82 static char *ngx_epoll_init_conf(ngx_cycle_t *cycle, void *conf); 83 static char *ngx_epoll_init_conf(ngx_cycle_t *cycle, void *conf);
83 84
84 static int ep = -1; 85 static int ep = -1;
135 NGX_MODULE_V1_PADDING 136 NGX_MODULE_V1_PADDING
136 }; 137 };
137 138
138 139
139 static ngx_int_t 140 static ngx_int_t
140 ngx_epoll_init(ngx_cycle_t *cycle) 141 ngx_epoll_init(ngx_cycle_t *cycle, ngx_msec_t timer)
141 { 142 {
142 ngx_event_conf_t *ecf; 143 ngx_event_conf_t *ecf;
143 ngx_epoll_conf_t *epcf; 144 ngx_epoll_conf_t *epcf;
144 145
145 ecf = ngx_event_get_conf(cycle->conf_ctx, ngx_event_core_module); 146 ecf = ngx_event_get_conf(cycle->conf_ctx, ngx_event_core_module);
380 return NGX_OK; 381 return NGX_OK;
381 } 382 }
382 383
383 384
384 static ngx_int_t 385 static ngx_int_t
385 ngx_epoll_process_events(ngx_cycle_t *cycle) 386 ngx_epoll_process_events(ngx_cycle_t *cycle, ngx_msec_t timer, ngx_uint_t flags)
386 { 387 {
387 int events; 388 int events;
388 uint32_t revents; 389 uint32_t revents;
389 ngx_int_t instance, i; 390 ngx_int_t instance, i;
390 ngx_uint_t lock, accept_lock; 391 ngx_uint_t level;
391 ngx_err_t err; 392 ngx_err_t err;
392 ngx_log_t *log; 393 ngx_log_t *log;
393 ngx_msec_t timer, delta; 394 ngx_msec_t delta;
394 ngx_event_t *rev, *wev; 395 ngx_event_t *rev, *wev, **queue;
395 struct timeval tv;
396 ngx_connection_t *c; 396 ngx_connection_t *c;
397 397
398 timer = ngx_event_find_timer();
399
400 #if (NGX_THREADS)
401
402 if (timer == NGX_TIMER_ERROR) {
403 return NGX_ERROR;
404 }
405
406 if (timer == NGX_TIMER_INFINITE || timer > 500) {
407 timer = 500;
408 }
409
410 #endif
411
412 /* NGX_TIMER_INFINITE == INFTIM */ 398 /* NGX_TIMER_INFINITE == INFTIM */
413
414 accept_lock = 0;
415
416 if (ngx_accept_mutex) {
417 if (ngx_accept_disabled > 0) {
418 ngx_accept_disabled--;
419
420 } else {
421 if (ngx_trylock_accept_mutex(cycle) == NGX_ERROR) {
422 return NGX_ERROR;
423 }
424
425 if (ngx_accept_mutex_held) {
426 accept_lock = 1;
427
428 } else if (timer == NGX_TIMER_INFINITE
429 || timer > ngx_accept_mutex_delay)
430 {
431 timer = ngx_accept_mutex_delay;
432 }
433 }
434 }
435 399
436 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0, 400 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
437 "epoll timer: %M", timer); 401 "epoll timer: %M", timer);
438 402
439 events = epoll_wait(ep, event_list, nevents, timer); 403 events = epoll_wait(ep, event_list, nevents, timer);
442 err = ngx_errno; 406 err = ngx_errno;
443 } else { 407 } else {
444 err = 0; 408 err = 0;
445 } 409 }
446 410
447 ngx_gettimeofday(&tv); 411 delta = ngx_current_msec;
448 ngx_time_update(tv.tv_sec); 412
449 413 if (flags & NGX_UPDATE_TIME) {
450 delta = ngx_current_time; 414 ngx_time_update(0, 0);
451 ngx_current_time = (ngx_msec_t) tv.tv_sec * 1000 + tv.tv_usec / 1000; 415 }
452 416
453 if (timer != NGX_TIMER_INFINITE) { 417 if (timer != NGX_TIMER_INFINITE) {
454 delta = ngx_current_time - delta; 418 delta = ngx_current_msec - delta;
455 419
456 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, cycle->log, 0, 420 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
457 "epoll timer: %M, delta: %M", timer, delta); 421 "epoll timer: %M, delta: %M", timer, delta);
458 } else { 422 } else {
459 if (events == 0) { 423 if (events == 0) {
460 ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, 424 ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
461 "epoll_wait() returned no events without timeout"); 425 "epoll_wait() returned no events without timeout");
462 ngx_accept_mutex_unlock();
463 return NGX_ERROR; 426 return NGX_ERROR;
464 } 427 }
465 } 428 }
466 429
467 if (err) { 430 if (err) {
468 ngx_log_error((err == NGX_EINTR) ? NGX_LOG_INFO : NGX_LOG_ALERT, 431 if (err == NGX_EINTR) {
469 cycle->log, err, "epoll_wait() failed"); 432
470 ngx_accept_mutex_unlock(); 433 if (ngx_event_timer_alarm) {
434 ngx_event_timer_alarm = 0;
435 return NGX_OK;
436 }
437
438 level = NGX_LOG_INFO;
439
440 } else {
441 level = NGX_LOG_ALERT;
442 }
443
444 ngx_log_error(level, cycle->log, err, "epoll_wait() failed");
471 return NGX_ERROR; 445 return NGX_ERROR;
472 } 446 }
473 447
474 if (events > 0) { 448 if (events == 0) {
475 if (ngx_mutex_lock(ngx_posted_events_mutex) == NGX_ERROR) { 449 return NGX_OK;
476 ngx_accept_mutex_unlock(); 450 }
477 return NGX_ERROR; 451
478 } 452 ngx_mutex_lock(ngx_posted_events_mutex);
479
480 lock = 1;
481
482 } else {
483 lock =0;
484 }
485 453
486 log = cycle->log; 454 log = cycle->log;
487 455
488 for (i = 0; i < events; i++) { 456 for (i = 0; i < events; i++) {
489 c = event_list[i].data.ptr; 457 c = event_list[i].data.ptr;
537 */ 505 */
538 506
539 revents |= EPOLLIN|EPOLLOUT; 507 revents |= EPOLLIN|EPOLLOUT;
540 } 508 }
541 509
510 if ((revents & EPOLLIN) && rev->active) {
511
512 if ((flags & NGX_POST_THREAD_EVENTS) && !rev->accept) {
513 rev->posted_ready = 1;
514
515 } else {
516 rev->ready = 1;
517 }
518
519 if (flags & NGX_POST_EVENTS) {
520 queue = (ngx_event_t **) (rev->accept ?
521 &ngx_posted_accept_events : &ngx_posted_events);
522
523 ngx_locked_post_event(rev, queue);
524
525 } else {
526 rev->handler(rev);
527 }
528 }
529
542 wev = c->write; 530 wev = c->write;
543 531
544 if ((revents & EPOLLOUT) && wev->active) { 532 if ((revents & EPOLLOUT) && wev->active) {
545 533
546 if (ngx_threaded) { 534 if (flags & NGX_POST_THREAD_EVENTS) {
547 wev->posted_ready = 1; 535 wev->posted_ready = 1;
548 ngx_post_event(wev);
549 536
550 } else { 537 } else {
551 wev->ready = 1; 538 wev->ready = 1;
552
553 if (!ngx_accept_mutex_held) {
554 wev->handler(wev);
555
556 } else {
557 ngx_post_event(wev);
558 }
559 } 539 }
560 } 540
561 541 if (flags & NGX_POST_EVENTS) {
562 /* 542 ngx_locked_post_event(wev, &ngx_posted_events);
563 * EPOLLIN must be handled after EPOLLOUT because we use 543
564 * the optimization to avoid the unnecessary mutex locking/unlocking 544 } else {
565 * if the accept event is the last one. 545 wev->handler(wev);
566 */
567
568 if ((revents & EPOLLIN) && rev->active) {
569
570 if (ngx_threaded && !rev->accept) {
571 rev->posted_ready = 1;
572
573 ngx_post_event(rev);
574
575 continue;
576 } 546 }
577 547 }
578 rev->ready = 1; 548 }
579 549
580 if (!ngx_threaded && !ngx_accept_mutex_held) { 550 ngx_mutex_unlock(ngx_posted_events_mutex);
581 rev->handler(rev);
582
583 } else if (!rev->accept) {
584 ngx_post_event(rev);
585
586 } else if (ngx_accept_disabled <= 0) {
587
588 ngx_mutex_unlock(ngx_posted_events_mutex);
589
590 rev->handler(rev);
591
592 if (ngx_accept_disabled > 0) {
593 ngx_accept_mutex_unlock();
594 accept_lock = 0;
595 }
596
597 if (i + 1 == events) {
598 lock = 0;
599 break;
600 }
601
602 if (ngx_mutex_lock(ngx_posted_events_mutex) == NGX_ERROR) {
603 if (accept_lock) {
604 ngx_accept_mutex_unlock();
605 }
606 return NGX_ERROR;
607 }
608 }
609 }
610 }
611
612 if (accept_lock) {
613 ngx_accept_mutex_unlock();
614 }
615
616 if (lock) {
617 ngx_mutex_unlock(ngx_posted_events_mutex);
618 }
619
620 ngx_event_expire_timers();
621
622 if (ngx_posted_events) {
623 if (ngx_threaded) {
624 ngx_wakeup_worker_thread(cycle);
625
626 } else {
627 ngx_event_process_posted(cycle);
628 }
629 }
630 551
631 return NGX_OK; 552 return NGX_OK;
632 } 553 }
633 554
634 555