Mercurial > hg > nginx
comparison src/event/modules/ngx_kqueue_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 | e48ebafc6939 |
children | 7c1369d37c7e |
comparison
equal
deleted
inserted
replaced
562:4b6108f69026 | 563:9c2f3ed7a247 |
---|---|
14 int changes; | 14 int changes; |
15 int events; | 15 int events; |
16 } ngx_kqueue_conf_t; | 16 } ngx_kqueue_conf_t; |
17 | 17 |
18 | 18 |
19 static ngx_int_t ngx_kqueue_init(ngx_cycle_t *cycle); | 19 static ngx_int_t ngx_kqueue_init(ngx_cycle_t *cycle, ngx_msec_t timer); |
20 static void ngx_kqueue_done(ngx_cycle_t *cycle); | 20 static void ngx_kqueue_done(ngx_cycle_t *cycle); |
21 static ngx_int_t ngx_kqueue_add_event(ngx_event_t *ev, int event, u_int flags); | 21 static ngx_int_t ngx_kqueue_add_event(ngx_event_t *ev, int event, u_int flags); |
22 static ngx_int_t ngx_kqueue_del_event(ngx_event_t *ev, int event, u_int flags); | 22 static ngx_int_t ngx_kqueue_del_event(ngx_event_t *ev, int event, u_int flags); |
23 static ngx_int_t ngx_kqueue_set_event(ngx_event_t *ev, int filter, u_int flags); | 23 static ngx_int_t ngx_kqueue_set_event(ngx_event_t *ev, int filter, u_int flags); |
24 static ngx_int_t ngx_kqueue_process_changes(ngx_cycle_t *cycle, ngx_uint_t try); | 24 static ngx_int_t ngx_kqueue_process_changes(ngx_cycle_t *cycle, ngx_uint_t try); |
25 static ngx_int_t ngx_kqueue_process_events(ngx_cycle_t *cycle); | 25 static ngx_int_t ngx_kqueue_process_events(ngx_cycle_t *cycle, ngx_msec_t timer, |
26 ngx_uint_t flags); | |
26 static ngx_inline void ngx_kqueue_dump_event(ngx_log_t *log, | 27 static ngx_inline void ngx_kqueue_dump_event(ngx_log_t *log, |
27 struct kevent *kev); | 28 struct kevent *kev); |
28 | 29 |
29 static void *ngx_kqueue_create_conf(ngx_cycle_t *cycle); | 30 static void *ngx_kqueue_create_conf(ngx_cycle_t *cycle); |
30 static char *ngx_kqueue_init_conf(ngx_cycle_t *cycle, void *conf); | 31 static char *ngx_kqueue_init_conf(ngx_cycle_t *cycle, void *conf); |
109 }; | 110 }; |
110 | 111 |
111 | 112 |
112 | 113 |
113 static ngx_int_t | 114 static ngx_int_t |
114 ngx_kqueue_init(ngx_cycle_t *cycle) | 115 ngx_kqueue_init(ngx_cycle_t *cycle, ngx_msec_t timer) |
115 { | 116 { |
117 struct kevent kev; | |
116 struct timespec ts; | 118 struct timespec ts; |
117 ngx_kqueue_conf_t *kcf; | 119 ngx_kqueue_conf_t *kcf; |
118 | 120 |
119 kcf = ngx_event_get_conf(cycle->conf_ctx, ngx_kqueue_module); | 121 kcf = ngx_event_get_conf(cycle->conf_ctx, ngx_kqueue_module); |
120 | 122 |
189 if (event_list == NULL) { | 191 if (event_list == NULL) { |
190 return NGX_ERROR; | 192 return NGX_ERROR; |
191 } | 193 } |
192 } | 194 } |
193 | 195 |
196 ngx_event_flags = 0; | |
197 | |
198 #if (NGX_HAVE_TIMER_EVENT) | |
199 | |
200 if (timer) { | |
201 kev.ident = 0; | |
202 kev.filter = EVFILT_TIMER; | |
203 kev.flags = EV_ADD|EV_ENABLE; | |
204 kev.fflags = 0; | |
205 kev.data = timer; | |
206 kev.udata = 0; | |
207 | |
208 ts.tv_sec = 0; | |
209 ts.tv_nsec = 0; | |
210 | |
211 if (kevent(ngx_kqueue, &kev, 1, NULL, 0, &ts) == -1) { | |
212 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, | |
213 "kevent(EVFILT_TIMER) failed"); | |
214 return NGX_ERROR; | |
215 } | |
216 | |
217 ngx_event_flags |= NGX_USE_TIMER_EVENT; | |
218 } | |
219 | |
220 #endif | |
221 | |
222 ngx_event_flags |= NGX_USE_ONESHOT_EVENT|NGX_USE_KQUEUE_EVENT; | |
223 | |
224 #if (NGX_HAVE_CLEAR_EVENT) | |
225 ngx_event_flags |= NGX_USE_CLEAR_EVENT; | |
226 #else | |
227 ngx_event_flags |= NGX_USE_LEVEL_EVENT; | |
228 #endif | |
229 | |
230 #if (NGX_HAVE_LOWAT_EVENT) | |
231 ngx_event_flags |= NGX_USE_LOWAT_EVENT; | |
232 #endif | |
233 | |
194 nevents = kcf->events; | 234 nevents = kcf->events; |
195 | 235 |
196 ngx_io = ngx_os_io; | 236 ngx_io = ngx_os_io; |
197 | 237 |
198 ngx_event_actions = ngx_kqueue_module_ctx.actions; | 238 ngx_event_actions = ngx_kqueue_module_ctx.actions; |
199 | |
200 ngx_event_flags = NGX_USE_ONESHOT_EVENT | |
201 #if 1 | |
202 #if (NGX_HAVE_CLEAR_EVENT) | |
203 |NGX_USE_CLEAR_EVENT | |
204 #else | |
205 |NGX_USE_LEVEL_EVENT | |
206 #endif | |
207 #endif | |
208 #if (NGX_HAVE_LOWAT_EVENT) | |
209 |NGX_USE_LOWAT_EVENT | |
210 #endif | |
211 |NGX_USE_KQUEUE_EVENT; | |
212 | 239 |
213 return NGX_OK; | 240 return NGX_OK; |
214 } | 241 } |
215 | 242 |
216 | 243 |
252 | 279 |
253 ev->active = 1; | 280 ev->active = 1; |
254 ev->disabled = 0; | 281 ev->disabled = 0; |
255 ev->oneshot = (flags & NGX_ONESHOT_EVENT) ? 1 : 0; | 282 ev->oneshot = (flags & NGX_ONESHOT_EVENT) ? 1 : 0; |
256 | 283 |
257 if (ngx_mutex_lock(list_mutex) == NGX_ERROR) { | 284 ngx_mutex_lock(list_mutex); |
258 return NGX_ERROR; | |
259 } | |
260 | 285 |
261 #if 1 | 286 #if 1 |
262 | 287 |
263 if (nchanges > 0 | 288 if (nchanges > 0 |
264 && ev->index < (u_int) nchanges | 289 && ev->index < (u_int) nchanges |
315 ngx_event_t *e; | 340 ngx_event_t *e; |
316 | 341 |
317 ev->active = 0; | 342 ev->active = 0; |
318 ev->disabled = 0; | 343 ev->disabled = 0; |
319 | 344 |
320 if (ngx_mutex_lock(list_mutex) == NGX_ERROR) { | 345 ngx_mutex_lock(list_mutex); |
321 return NGX_ERROR; | |
322 } | |
323 | 346 |
324 #if 1 | 347 #if 1 |
325 | 348 |
326 if (nchanges > 0 | 349 if (nchanges > 0 |
327 && ev->index < (u_int) nchanges | 350 && ev->index < (u_int) nchanges |
439 return NGX_OK; | 462 return NGX_OK; |
440 } | 463 } |
441 | 464 |
442 | 465 |
443 static ngx_int_t | 466 static ngx_int_t |
444 ngx_kqueue_process_events(ngx_cycle_t *cycle) | 467 ngx_kqueue_process_events(ngx_cycle_t *cycle, ngx_msec_t timer, |
445 { | 468 ngx_uint_t flags) |
446 int events, n; | 469 { |
447 ngx_int_t i, instance; | 470 int events, n; |
448 ngx_uint_t lock, accept_lock; | 471 ngx_int_t i, instance; |
449 ngx_err_t err; | 472 ngx_uint_t level; |
450 ngx_msec_t timer, delta; | 473 ngx_err_t err; |
451 ngx_event_t *ev; | 474 ngx_msec_t delta; |
452 struct timeval tv; | 475 ngx_event_t *ev, **queue; |
453 struct timespec ts, *tp; | 476 struct timespec ts, *tp; |
454 | |
455 timer = ngx_event_find_timer(); | |
456 | |
457 #if (NGX_THREADS) | |
458 | |
459 if (timer == NGX_TIMER_ERROR) { | |
460 return NGX_ERROR; | |
461 } | |
462 | |
463 if (timer == NGX_TIMER_INFINITE || timer > 500) { | |
464 timer = 500; | |
465 } | |
466 | |
467 #endif | |
468 | |
469 accept_lock = 0; | |
470 | |
471 if (ngx_accept_mutex) { | |
472 if (ngx_accept_disabled > 0) { | |
473 ngx_accept_disabled--; | |
474 | |
475 } else { | |
476 if (ngx_trylock_accept_mutex(cycle) == NGX_ERROR) { | |
477 return NGX_ERROR; | |
478 } | |
479 | |
480 if (ngx_accept_mutex_held) { | |
481 accept_lock = 1; | |
482 | |
483 } else if (timer == NGX_TIMER_INFINITE | |
484 || timer > ngx_accept_mutex_delay) | |
485 { | |
486 timer = ngx_accept_mutex_delay; | |
487 } | |
488 } | |
489 } | |
490 | 477 |
491 if (ngx_threaded) { | 478 if (ngx_threaded) { |
492 if (ngx_kqueue_process_changes(cycle, 0) == NGX_ERROR) { | 479 if (ngx_kqueue_process_changes(cycle, 0) == NGX_ERROR) { |
493 ngx_accept_mutex_unlock(); | |
494 return NGX_ERROR; | 480 return NGX_ERROR; |
495 } | 481 } |
496 | 482 |
497 n = 0; | 483 n = 0; |
498 | 484 |
519 err = ngx_errno; | 505 err = ngx_errno; |
520 } else { | 506 } else { |
521 err = 0; | 507 err = 0; |
522 } | 508 } |
523 | 509 |
524 ngx_gettimeofday(&tv); | 510 delta = ngx_current_msec; |
525 ngx_time_update(tv.tv_sec); | 511 |
512 if (flags & NGX_UPDATE_TIME) { | |
513 ngx_time_update(0, 0); | |
514 } | |
526 | 515 |
527 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0, | 516 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0, |
528 "kevent events: %d", events); | 517 "kevent events: %d", events); |
529 | 518 |
530 delta = ngx_current_time; | |
531 ngx_current_time = (ngx_msec_t) tv.tv_sec * 1000 + tv.tv_usec / 1000; | |
532 | |
533 if (err) { | 519 if (err) { |
534 ngx_log_error((err == NGX_EINTR) ? NGX_LOG_INFO : NGX_LOG_ALERT, | 520 if (err == NGX_EINTR) { |
535 cycle->log, err, "kevent() failed"); | 521 |
536 ngx_accept_mutex_unlock(); | 522 if (ngx_event_timer_alarm) { |
523 ngx_event_timer_alarm = 0; | |
524 return NGX_OK; | |
525 } | |
526 | |
527 level = NGX_LOG_INFO; | |
528 | |
529 } else { | |
530 level = NGX_LOG_ALERT; | |
531 } | |
532 | |
533 ngx_log_error(level, cycle->log, err, "kevent() failed"); | |
537 return NGX_ERROR; | 534 return NGX_ERROR; |
538 } | 535 } |
539 | 536 |
540 if (timer != NGX_TIMER_INFINITE) { | 537 if (timer != NGX_TIMER_INFINITE) { |
541 delta = ngx_current_time - delta; | 538 delta = ngx_current_msec - delta; |
542 | 539 |
543 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, cycle->log, 0, | 540 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, cycle->log, 0, |
544 "kevent timer: %M, delta: %M", timer, delta); | 541 "kevent timer: %M, delta: %M", timer, delta); |
545 | 542 |
546 } else { | 543 } else { |
547 if (events == 0) { | 544 if (events == 0) { |
548 ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, | 545 ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, |
549 "kevent() returned no events without timeout"); | 546 "kevent() returned no events without timeout"); |
550 ngx_accept_mutex_unlock(); | 547 return NGX_ERROR; |
551 return NGX_ERROR; | 548 } |
552 } | 549 } |
553 } | 550 |
554 | 551 if (events == 0) { |
555 if (events > 0) { | 552 return NGX_OK; |
556 if (ngx_mutex_lock(ngx_posted_events_mutex) == NGX_ERROR) { | 553 } |
557 ngx_accept_mutex_unlock(); | 554 |
558 return NGX_ERROR; | 555 ngx_mutex_lock(ngx_posted_events_mutex); |
559 } | |
560 | |
561 lock = 1; | |
562 | |
563 } else { | |
564 lock =0; | |
565 } | |
566 | 556 |
567 for (i = 0; i < events; i++) { | 557 for (i = 0; i < events; i++) { |
568 | 558 |
569 ngx_kqueue_dump_event(cycle->log, &event_list[i]); | 559 ngx_kqueue_dump_event(cycle->log, &event_list[i]); |
570 | 560 |
572 ngx_log_error(NGX_LOG_ALERT, cycle->log, event_list[i].data, | 562 ngx_log_error(NGX_LOG_ALERT, cycle->log, event_list[i].data, |
573 "kevent() error on %d", event_list[i].ident); | 563 "kevent() error on %d", event_list[i].ident); |
574 continue; | 564 continue; |
575 } | 565 } |
576 | 566 |
567 #if (NGX_HAVE_TIMER_EVENT) | |
568 | |
569 if (event_list[i].filter == EVFILT_TIMER) { | |
570 ngx_time_update(0, 0); | |
571 continue; | |
572 } | |
573 | |
574 #endif | |
575 | |
577 ev = (ngx_event_t *) event_list[i].udata; | 576 ev = (ngx_event_t *) event_list[i].udata; |
578 | 577 |
579 switch (event_list[i].filter) { | 578 switch (event_list[i].filter) { |
580 | 579 |
581 case EVFILT_READ: | 580 case EVFILT_READ: |
604 ev->active = 0; | 603 ev->active = 0; |
605 } | 604 } |
606 | 605 |
607 #if (NGX_THREADS) | 606 #if (NGX_THREADS) |
608 | 607 |
609 if (ngx_threaded && !ev->accept) { | 608 if ((flags & NGX_POST_THREAD_EVENTS) && !ev->accept) { |
610 ev->posted_ready = 1; | 609 ev->posted_ready = 1; |
611 ev->posted_available = event_list[i].data; | 610 ev->posted_available = event_list[i].data; |
612 | 611 |
613 if (event_list[i].flags & EV_EOF) { | 612 if (event_list[i].flags & EV_EOF) { |
614 ev->posted_eof = 1; | 613 ev->posted_eof = 1; |
615 ev->posted_errno = event_list[i].fflags; | 614 ev->posted_errno = event_list[i].fflags; |
616 } | 615 } |
617 | 616 |
618 ngx_post_event(ev); | 617 ngx_locked_post_event(ev, &ngx_posted_events); |
619 | 618 |
620 continue; | 619 continue; |
621 } | 620 } |
622 | 621 |
623 #endif | 622 #endif |
649 "unexpected kevent() filter %d", | 648 "unexpected kevent() filter %d", |
650 event_list[i].filter); | 649 event_list[i].filter); |
651 continue; | 650 continue; |
652 } | 651 } |
653 | 652 |
654 if (!ngx_threaded && !ngx_accept_mutex_held) { | 653 if (flags & NGX_POST_EVENTS) { |
655 ev->handler(ev); | 654 queue = (ngx_event_t **) (ev->accept ? &ngx_posted_accept_events: |
655 &ngx_posted_events); | |
656 ngx_locked_post_event(ev, queue); | |
657 | |
656 continue; | 658 continue; |
657 } | 659 } |
658 | 660 |
659 if (!ev->accept) { | |
660 ngx_post_event(ev); | |
661 continue; | |
662 } | |
663 | |
664 if (ngx_accept_disabled > 0) { | |
665 continue; | |
666 } | |
667 | |
668 ngx_mutex_unlock(ngx_posted_events_mutex); | |
669 | |
670 ev->handler(ev); | 661 ev->handler(ev); |
671 | 662 } |
672 if (ngx_accept_disabled > 0) { | 663 |
673 ngx_accept_mutex_unlock(); | 664 ngx_mutex_unlock(ngx_posted_events_mutex); |
674 accept_lock = 0; | |
675 } | |
676 | |
677 if (i + 1 == events) { | |
678 lock = 0; | |
679 break; | |
680 } | |
681 | |
682 if (ngx_mutex_lock(ngx_posted_events_mutex) == NGX_ERROR) { | |
683 if (accept_lock) { | |
684 ngx_accept_mutex_unlock(); | |
685 } | |
686 return NGX_ERROR; | |
687 } | |
688 } | |
689 | |
690 if (accept_lock) { | |
691 ngx_accept_mutex_unlock(); | |
692 } | |
693 | |
694 if (lock) { | |
695 ngx_mutex_unlock(ngx_posted_events_mutex); | |
696 } | |
697 | |
698 ngx_event_expire_timers(); | |
699 | |
700 if (ngx_posted_events) { | |
701 if (ngx_threaded) { | |
702 ngx_wakeup_worker_thread(cycle); | |
703 | |
704 } else { | |
705 ngx_event_process_posted(cycle); | |
706 } | |
707 } | |
708 | 665 |
709 return NGX_OK; | 666 return NGX_OK; |
710 } | 667 } |
711 | 668 |
712 | 669 |
717 ngx_int_t rc; | 674 ngx_int_t rc; |
718 ngx_err_t err; | 675 ngx_err_t err; |
719 struct timespec ts; | 676 struct timespec ts; |
720 struct kevent *changes; | 677 struct kevent *changes; |
721 | 678 |
722 if (ngx_mutex_lock(kevent_mutex) == NGX_ERROR) { | 679 ngx_mutex_lock(kevent_mutex); |
723 return NGX_ERROR; | 680 |
724 } | 681 ngx_mutex_lock(list_mutex); |
725 | |
726 if (ngx_mutex_lock(list_mutex) == NGX_ERROR) { | |
727 ngx_mutex_unlock(kevent_mutex); | |
728 return NGX_ERROR; | |
729 } | |
730 | 682 |
731 if (nchanges == 0) { | 683 if (nchanges == 0) { |
732 ngx_mutex_unlock(list_mutex); | 684 ngx_mutex_unlock(list_mutex); |
733 ngx_mutex_unlock(kevent_mutex); | 685 ngx_mutex_unlock(kevent_mutex); |
734 return NGX_OK; | 686 return NGX_OK; |