[nginx] Events: implemented kqueue notification mechanism.

Valentin Bartenev vbart at nginx.com
Wed Mar 18 15:58:00 UTC 2015


details:   http://hg.nginx.org/nginx/rev/e5f1d83360ef
branches:  
changeset: 6020:e5f1d83360ef
user:      Valentin Bartenev <vbart at nginx.com>
date:      Sat Mar 14 17:37:16 2015 +0300
description:
Events: implemented kqueue notification mechanism.

diffstat:

 src/event/modules/ngx_kqueue_module.c |  76 +++++++++++++++++++++++++++++++++++
 1 files changed, 76 insertions(+), 0 deletions(-)

diffs (136 lines):

diff -r 40e244e042a7 -r e5f1d83360ef src/event/modules/ngx_kqueue_module.c
--- a/src/event/modules/ngx_kqueue_module.c	Sat Mar 14 17:37:13 2015 +0300
+++ b/src/event/modules/ngx_kqueue_module.c	Sat Mar 14 17:37:16 2015 +0300
@@ -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, &notify_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) &notify_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, &notify_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",



More information about the nginx-devel mailing list