# HG changeset patch # User Valentin Bartenev # Date 1426343836 -10800 # Node ID e5f1d83360ef7273a4e734caad302f74de5cd312 # Parent 40e244e042a7e30b7c7abc828f0564d280f4b468 Events: implemented kqueue notification mechanism. diff --git a/src/event/modules/ngx_kqueue_module.c b/src/event/modules/ngx_kqueue_module.c --- a/src/event/modules/ngx_kqueue_module.c +++ b/src/event/modules/ngx_kqueue_module.c @@ -17,6 +17,9 @@ typedef struct { static ngx_int_t ngx_kqueue_init(ngx_cycle_t *cycle, ngx_msec_t timer); +#ifdef EVFILT_USER +static ngx_int_t ngx_kqueue_notify_init(ngx_log_t *log); +#endif static void ngx_kqueue_done(ngx_cycle_t *cycle); static ngx_int_t ngx_kqueue_add_event(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags); @@ -24,6 +27,9 @@ static ngx_int_t ngx_kqueue_del_event(ng ngx_uint_t flags); static ngx_int_t ngx_kqueue_set_event(ngx_event_t *ev, ngx_int_t filter, ngx_uint_t flags); +#ifdef EVFILT_USER +static ngx_int_t ngx_kqueue_notify(ngx_event_handler_pt handler); +#endif static ngx_int_t ngx_kqueue_process_changes(ngx_cycle_t *cycle, ngx_uint_t try); static ngx_int_t ngx_kqueue_process_events(ngx_cycle_t *cycle, ngx_msec_t timer, ngx_uint_t flags); @@ -48,6 +54,11 @@ static struct kevent *change_list, *cha static struct kevent *event_list; static ngx_uint_t max_changes, nchanges, nevents; +#ifdef EVFILT_USER +static ngx_event_t notify_event; +static struct kevent notify_kev; +#endif + #if (NGX_OLD_THREADS) static ngx_mutex_t *list_mutex; static ngx_mutex_t *kevent_mutex; @@ -89,7 +100,11 @@ ngx_event_module_t ngx_kqueue_module_ct ngx_kqueue_del_event, /* disable an event */ NULL, /* add an connection */ NULL, /* delete an connection */ +#ifdef EVFILT_USER + ngx_kqueue_notify, /* trigger a notify */ +#else NULL, /* trigger a notify */ +#endif ngx_kqueue_process_changes, /* process the changes */ ngx_kqueue_process_events, /* process the events */ ngx_kqueue_init, /* init the events */ @@ -134,6 +149,12 @@ ngx_kqueue_init(ngx_cycle_t *cycle, ngx_ return NGX_ERROR; } +#ifdef EVFILT_USER + if (ngx_kqueue_notify_init(cycle->log) != NGX_OK) { + return NGX_ERROR; + } +#endif + #if (NGX_OLD_THREADS) list_mutex = ngx_mutex_init(cycle->log, 0); @@ -248,6 +269,37 @@ ngx_kqueue_init(ngx_cycle_t *cycle, ngx_ } +#ifdef EVFILT_USER + +static ngx_int_t +ngx_kqueue_notify_init(ngx_log_t *log) +{ + notify_kev.ident = 0; + notify_kev.filter = EVFILT_USER; + notify_kev.data = 0; + notify_kev.flags = EV_ADD|EV_CLEAR; + notify_kev.fflags = 0; + notify_kev.udata = 0; + + if (kevent(ngx_kqueue, ¬ify_kev, 1, NULL, 0, NULL) == -1) { + ngx_log_error(NGX_LOG_ALERT, log, ngx_errno, + "kevent(EVFILT_USER, EV_ADD) failed"); + return NGX_ERROR; + } + + notify_event.active = 1; + notify_event.log = log; + + notify_kev.flags = 0; + notify_kev.fflags = NOTE_TRIGGER; + notify_kev.udata = NGX_KQUEUE_UDATA_T ((uintptr_t) ¬ify_event); + + return NGX_OK; +} + +#endif + + static void ngx_kqueue_done(ngx_cycle_t *cycle) { @@ -488,6 +540,25 @@ ngx_kqueue_set_event(ngx_event_t *ev, ng } +#ifdef EVFILT_USER + +static ngx_int_t +ngx_kqueue_notify(ngx_event_handler_pt handler) +{ + notify_event.handler = handler; + + if (kevent(ngx_kqueue, ¬ify_kev, 1, NULL, 0, NULL) == -1) { + ngx_log_error(NGX_LOG_ALERT, notify_event.log, ngx_errno, + "kevent(EVFILT_USER, NOTE_TRIGGER) failed"); + return NGX_ERROR; + } + + return NGX_OK; +} + +#endif + + static ngx_int_t ngx_kqueue_process_events(ngx_cycle_t *cycle, ngx_msec_t timer, ngx_uint_t flags) @@ -648,6 +719,11 @@ ngx_kqueue_process_events(ngx_cycle_t *c break; +#ifdef EVFILT_USER + case EVFILT_USER: + break; +#endif + default: ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, "unexpected kevent() filter %d",