comparison src/event/modules/ngx_kqueue_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 dad2fe8ecf08
children ebca9c35e3a6
comparison
equal deleted inserted replaced
111:a175b609c76d 112:408f195b3482
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;