comparison src/event/modules/ngx_kqueue_module.c @ 6020:e5f1d83360ef

Events: implemented kqueue notification mechanism.
author Valentin Bartenev <vbart@nginx.com>
date Sat, 14 Mar 2015 17:37:16 +0300
parents 466bd63b63d1
children e284f3ff6831
comparison
equal deleted inserted replaced
6019:40e244e042a7 6020:e5f1d83360ef
15 ngx_uint_t events; 15 ngx_uint_t 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, ngx_msec_t timer); 19 static ngx_int_t ngx_kqueue_init(ngx_cycle_t *cycle, ngx_msec_t timer);
20 #ifdef EVFILT_USER
21 static ngx_int_t ngx_kqueue_notify_init(ngx_log_t *log);
22 #endif
20 static void ngx_kqueue_done(ngx_cycle_t *cycle); 23 static void ngx_kqueue_done(ngx_cycle_t *cycle);
21 static ngx_int_t ngx_kqueue_add_event(ngx_event_t *ev, ngx_int_t event, 24 static ngx_int_t ngx_kqueue_add_event(ngx_event_t *ev, ngx_int_t event,
22 ngx_uint_t flags); 25 ngx_uint_t flags);
23 static ngx_int_t ngx_kqueue_del_event(ngx_event_t *ev, ngx_int_t event, 26 static ngx_int_t ngx_kqueue_del_event(ngx_event_t *ev, ngx_int_t event,
24 ngx_uint_t flags); 27 ngx_uint_t flags);
25 static ngx_int_t ngx_kqueue_set_event(ngx_event_t *ev, ngx_int_t filter, 28 static ngx_int_t ngx_kqueue_set_event(ngx_event_t *ev, ngx_int_t filter,
26 ngx_uint_t flags); 29 ngx_uint_t flags);
30 #ifdef EVFILT_USER
31 static ngx_int_t ngx_kqueue_notify(ngx_event_handler_pt handler);
32 #endif
27 static ngx_int_t ngx_kqueue_process_changes(ngx_cycle_t *cycle, ngx_uint_t try); 33 static ngx_int_t ngx_kqueue_process_changes(ngx_cycle_t *cycle, ngx_uint_t try);
28 static ngx_int_t ngx_kqueue_process_events(ngx_cycle_t *cycle, ngx_msec_t timer, 34 static ngx_int_t ngx_kqueue_process_events(ngx_cycle_t *cycle, ngx_msec_t timer,
29 ngx_uint_t flags); 35 ngx_uint_t flags);
30 static ngx_inline void ngx_kqueue_dump_event(ngx_log_t *log, 36 static ngx_inline void ngx_kqueue_dump_event(ngx_log_t *log,
31 struct kevent *kev); 37 struct kevent *kev);
46 52
47 static struct kevent *change_list, *change_list0, *change_list1; 53 static struct kevent *change_list, *change_list0, *change_list1;
48 static struct kevent *event_list; 54 static struct kevent *event_list;
49 static ngx_uint_t max_changes, nchanges, nevents; 55 static ngx_uint_t max_changes, nchanges, nevents;
50 56
57 #ifdef EVFILT_USER
58 static ngx_event_t notify_event;
59 static struct kevent notify_kev;
60 #endif
61
51 #if (NGX_OLD_THREADS) 62 #if (NGX_OLD_THREADS)
52 static ngx_mutex_t *list_mutex; 63 static ngx_mutex_t *list_mutex;
53 static ngx_mutex_t *kevent_mutex; 64 static ngx_mutex_t *kevent_mutex;
54 #endif 65 #endif
55 66
87 ngx_kqueue_del_event, /* delete an event */ 98 ngx_kqueue_del_event, /* delete an event */
88 ngx_kqueue_add_event, /* enable an event */ 99 ngx_kqueue_add_event, /* enable an event */
89 ngx_kqueue_del_event, /* disable an event */ 100 ngx_kqueue_del_event, /* disable an event */
90 NULL, /* add an connection */ 101 NULL, /* add an connection */
91 NULL, /* delete an connection */ 102 NULL, /* delete an connection */
103 #ifdef EVFILT_USER
104 ngx_kqueue_notify, /* trigger a notify */
105 #else
92 NULL, /* trigger a notify */ 106 NULL, /* trigger a notify */
107 #endif
93 ngx_kqueue_process_changes, /* process the changes */ 108 ngx_kqueue_process_changes, /* process the changes */
94 ngx_kqueue_process_events, /* process the events */ 109 ngx_kqueue_process_events, /* process the events */
95 ngx_kqueue_init, /* init the events */ 110 ngx_kqueue_init, /* init the events */
96 ngx_kqueue_done /* done the events */ 111 ngx_kqueue_done /* done the events */
97 } 112 }
132 ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno, 147 ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
133 "kqueue() failed"); 148 "kqueue() failed");
134 return NGX_ERROR; 149 return NGX_ERROR;
135 } 150 }
136 151
152 #ifdef EVFILT_USER
153 if (ngx_kqueue_notify_init(cycle->log) != NGX_OK) {
154 return NGX_ERROR;
155 }
156 #endif
157
137 #if (NGX_OLD_THREADS) 158 #if (NGX_OLD_THREADS)
138 159
139 list_mutex = ngx_mutex_init(cycle->log, 0); 160 list_mutex = ngx_mutex_init(cycle->log, 0);
140 if (list_mutex == NULL) { 161 if (list_mutex == NULL) {
141 return NGX_ERROR; 162 return NGX_ERROR;
246 267
247 return NGX_OK; 268 return NGX_OK;
248 } 269 }
249 270
250 271
272 #ifdef EVFILT_USER
273
274 static ngx_int_t
275 ngx_kqueue_notify_init(ngx_log_t *log)
276 {
277 notify_kev.ident = 0;
278 notify_kev.filter = EVFILT_USER;
279 notify_kev.data = 0;
280 notify_kev.flags = EV_ADD|EV_CLEAR;
281 notify_kev.fflags = 0;
282 notify_kev.udata = 0;
283
284 if (kevent(ngx_kqueue, &notify_kev, 1, NULL, 0, NULL) == -1) {
285 ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
286 "kevent(EVFILT_USER, EV_ADD) failed");
287 return NGX_ERROR;
288 }
289
290 notify_event.active = 1;
291 notify_event.log = log;
292
293 notify_kev.flags = 0;
294 notify_kev.fflags = NOTE_TRIGGER;
295 notify_kev.udata = NGX_KQUEUE_UDATA_T ((uintptr_t) &notify_event);
296
297 return NGX_OK;
298 }
299
300 #endif
301
302
251 static void 303 static void
252 ngx_kqueue_done(ngx_cycle_t *cycle) 304 ngx_kqueue_done(ngx_cycle_t *cycle)
253 { 305 {
254 if (close(ngx_kqueue) == -1) { 306 if (close(ngx_kqueue) == -1) {
255 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, 307 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
486 538
487 return NGX_OK; 539 return NGX_OK;
488 } 540 }
489 541
490 542
543 #ifdef EVFILT_USER
544
545 static ngx_int_t
546 ngx_kqueue_notify(ngx_event_handler_pt handler)
547 {
548 notify_event.handler = handler;
549
550 if (kevent(ngx_kqueue, &notify_kev, 1, NULL, 0, NULL) == -1) {
551 ngx_log_error(NGX_LOG_ALERT, notify_event.log, ngx_errno,
552 "kevent(EVFILT_USER, NOTE_TRIGGER) failed");
553 return NGX_ERROR;
554 }
555
556 return NGX_OK;
557 }
558
559 #endif
560
561
491 static ngx_int_t 562 static ngx_int_t
492 ngx_kqueue_process_events(ngx_cycle_t *cycle, ngx_msec_t timer, 563 ngx_kqueue_process_events(ngx_cycle_t *cycle, ngx_msec_t timer,
493 ngx_uint_t flags) 564 ngx_uint_t flags)
494 { 565 {
495 int events, n; 566 int events, n;
646 ev->complete = 1; 717 ev->complete = 1;
647 ev->ready = 1; 718 ev->ready = 1;
648 719
649 break; 720 break;
650 721
722 #ifdef EVFILT_USER
723 case EVFILT_USER:
724 break;
725 #endif
726
651 default: 727 default:
652 ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, 728 ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
653 "unexpected kevent() filter %d", 729 "unexpected kevent() filter %d",
654 event_list[i].filter); 730 event_list[i].filter);
655 continue; 731 continue;