Mercurial > hg > nginx
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, ¬ify_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) ¬ify_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, ¬ify_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; |