Mercurial > hg > nginx-quic
comparison src/event/modules/ngx_epoll_module.c @ 563:9c2f3ed7a247 release-0.3.3
nginx-0.3.3-RELEASE import
*) 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; the bug had 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 <igor@sysoev.ru> |
---|---|
date | Wed, 19 Oct 2005 12:33:58 +0000 |
parents | c1f965ef9718 |
children | 1af2fcb3be8a |
comparison
equal
deleted
inserted
replaced
562:4b6108f69026 | 563:9c2f3ed7a247 |
---|---|
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 |