[PATCH] Events: improve ngx_notify() interface
Piotr Sikora
piotrsikora at google.com
Thu Aug 18 00:29:40 UTC 2016
# HG changeset patch
# User Piotr Sikora <piotrsikora at google.com>
# Date 1471265536 25200
# Mon Aug 15 05:52:16 2016 -0700
# Node ID e4241e448bc94e6b598a2178d7378aef63741f3c
# Parent c131f20c9562387f94a268440594c288725d3ba8
Events: improve ngx_notify() interface.
Previous implementation had a race condition in which only the last
of the notified handlers was called, i.e.:
ngx_notify(ngx_ping_handler);
ngx_notify(ngx_pong_handler);
resulted in only ngx_pong_handler() being called.
This wasn't an issue in standalone NGINX (because there is only one
consumer of this interface), but it led to lost notifications when
used with 3rd-party modules that were also using this interface.
New implementation requires notification event to be initialized
in order to register the handler:
ngx_notify_init(&ngx_ping, ngx_ping_handler, cycle);
ngx_notify_init(&ngx_pong, ngx_pong_handler, cycle);
and notification is triggered on the event and not on a handler:
ngx_notify(&ngx_ping);
ngx_notify(&ngx_pong);
Tested on Linux, FreeBSD, OS X and SmartOS.
Found with ThreadSanitizer.
Reported by Feng Li.
Signed-off-by: Piotr Sikora <piotrsikora at google.com>
diff -r c131f20c9562 -r e4241e448bc9 src/core/ngx_thread_pool.c
--- a/src/core/ngx_thread_pool.c
+++ b/src/core/ngx_thread_pool.c
@@ -99,6 +99,7 @@ ngx_module_t ngx_thread_pool_module = {
static ngx_str_t ngx_thread_pool_default = ngx_string("default");
static ngx_uint_t ngx_thread_pool_task_id;
+static ngx_event_t ngx_thread_pool_notify;
static ngx_atomic_t ngx_thread_pool_done_lock;
static ngx_thread_pool_queue_t ngx_thread_pool_done;
@@ -111,12 +112,6 @@ ngx_thread_pool_init(ngx_thread_pool_t *
ngx_uint_t n;
pthread_attr_t attr;
- if (ngx_notify == NULL) {
- ngx_log_error(NGX_LOG_ALERT, log, 0,
- "the configured event method cannot be used with thread pools");
- return NGX_ERROR;
- }
-
ngx_thread_pool_queue_init(&tp->queue);
if (ngx_thread_mutex_create(&tp->mtx, log) != NGX_OK) {
@@ -349,7 +344,7 @@ ngx_thread_pool_cycle(void *data)
ngx_unlock(&ngx_thread_pool_done_lock);
- (void) ngx_notify(ngx_thread_pool_handler);
+ (void) ngx_notify(&ngx_thread_pool_notify);
}
}
@@ -588,10 +583,22 @@ ngx_thread_pool_init_worker(ngx_cycle_t
tcf = (ngx_thread_pool_conf_t *) ngx_get_conf(cycle->conf_ctx,
ngx_thread_pool_module);
- if (tcf == NULL) {
+ if (tcf == NULL || tcf->pools.nelts == 0) {
return NGX_OK;
}
+ if (ngx_notify_init == NULL || ngx_notify == NULL) {
+ ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
+ "the configured event method cannot be used with thread pools");
+ return NGX_ERROR;
+ }
+
+ if (ngx_notify_init(&ngx_thread_pool_notify, ngx_thread_pool_handler, cycle)
+ != NGX_OK)
+ {
+ return NGX_ERROR;
+ }
+
ngx_thread_pool_queue_init(&ngx_thread_pool_done);
tpp = tcf->pools.elts;
@@ -622,7 +629,7 @@ ngx_thread_pool_exit_worker(ngx_cycle_t
tcf = (ngx_thread_pool_conf_t *) ngx_get_conf(cycle->conf_ctx,
ngx_thread_pool_module);
- if (tcf == NULL) {
+ if (tcf == NULL || tcf->pools.nelts == 0) {
return;
}
@@ -631,4 +638,8 @@ ngx_thread_pool_exit_worker(ngx_cycle_t
for (i = 0; i < tcf->pools.nelts; i++) {
ngx_thread_pool_destroy(tpp[i]);
}
+
+ if (ngx_notify_close != NULL) {
+ ngx_notify_close(&ngx_thread_pool_notify);
+ }
}
diff -r c131f20c9562 -r e4241e448bc9 src/event/modules/ngx_devpoll_module.c
--- a/src/event/modules/ngx_devpoll_module.c
+++ b/src/event/modules/ngx_devpoll_module.c
@@ -90,7 +90,9 @@ ngx_event_module_t ngx_devpoll_module_c
ngx_devpoll_del_event, /* disable an event */
NULL, /* add an connection */
NULL, /* delete an connection */
+ NULL, /* init a notify */
NULL, /* trigger a notify */
+ NULL, /* close a notify */
ngx_devpoll_process_events, /* process the events */
ngx_devpoll_init, /* init the events */
ngx_devpoll_done, /* done the events */
diff -r c131f20c9562 -r e4241e448bc9 src/event/modules/ngx_epoll_module.c
--- a/src/event/modules/ngx_epoll_module.c
+++ b/src/event/modules/ngx_epoll_module.c
@@ -103,8 +103,10 @@ typedef struct {
static ngx_int_t ngx_epoll_init(ngx_cycle_t *cycle, ngx_msec_t timer);
#if (NGX_HAVE_EVENTFD)
-static ngx_int_t ngx_epoll_notify_init(ngx_log_t *log);
+static ngx_int_t ngx_epoll_notify_init(ngx_event_t *notify_event,
+ ngx_event_handler_pt handler, ngx_cycle_t *cycle);
static void ngx_epoll_notify_handler(ngx_event_t *ev);
+static void ngx_epoll_notify_close(ngx_event_t *notify_event);
#endif
#if (NGX_HAVE_EPOLLRDHUP)
static void ngx_epoll_test_rdhup(ngx_cycle_t *cycle);
@@ -118,7 +120,7 @@ static ngx_int_t ngx_epoll_add_connectio
static ngx_int_t ngx_epoll_del_connection(ngx_connection_t *c,
ngx_uint_t flags);
#if (NGX_HAVE_EVENTFD)
-static ngx_int_t ngx_epoll_notify(ngx_event_handler_pt handler);
+static ngx_int_t ngx_epoll_notify(ngx_event_t *notify_event);
#endif
static ngx_int_t ngx_epoll_process_events(ngx_cycle_t *cycle, ngx_msec_t timer,
ngx_uint_t flags);
@@ -134,12 +136,6 @@ static int ep = -1;
static struct epoll_event *event_list;
static ngx_uint_t nevents;
-#if (NGX_HAVE_EVENTFD)
-static int notify_fd = -1;
-static ngx_event_t notify_event;
-static ngx_connection_t notify_conn;
-#endif
-
#if (NGX_HAVE_FILE_AIO)
int ngx_eventfd = -1;
@@ -189,9 +185,13 @@ ngx_event_module_t ngx_epoll_module_ctx
ngx_epoll_add_connection, /* add an connection */
ngx_epoll_del_connection, /* delete an connection */
#if (NGX_HAVE_EVENTFD)
+ ngx_epoll_notify_init, /* init a notify */
ngx_epoll_notify, /* trigger a notify */
+ ngx_epoll_notify_close, /* close a notify */
#else
+ NULL, /* init a notify */
NULL, /* trigger a notify */
+ NULL, /* close a notify */
#endif
ngx_epoll_process_events, /* process the events */
ngx_epoll_init, /* init the events */
@@ -335,12 +335,6 @@ ngx_epoll_init(ngx_cycle_t *cycle, ngx_m
return NGX_ERROR;
}
-#if (NGX_HAVE_EVENTFD)
- if (ngx_epoll_notify_init(cycle->log) != NGX_OK) {
- ngx_epoll_module_ctx.actions.notify = NULL;
- }
-#endif
-
#if (NGX_HAVE_FILE_AIO)
ngx_epoll_aio_init(cycle, epcf);
#endif
@@ -383,9 +377,17 @@ ngx_epoll_init(ngx_cycle_t *cycle, ngx_m
#if (NGX_HAVE_EVENTFD)
static ngx_int_t
-ngx_epoll_notify_init(ngx_log_t *log)
+ngx_epoll_notify_init(ngx_event_t *notify_event, ngx_event_handler_pt handler,
+ ngx_cycle_t *cycle)
{
- struct epoll_event ee;
+ int notify_fd;
+ ngx_connection_t *notify_conn;
+ struct epoll_event ee;
+
+ notify_conn = ngx_pcalloc(cycle->pool, sizeof(ngx_connection_t));
+ if (notify_conn == NULL) {
+ return NGX_ERROR;
+ }
#if (NGX_HAVE_SYS_EVENTFD_H)
notify_fd = eventfd(0, 0);
@@ -394,31 +396,35 @@ ngx_epoll_notify_init(ngx_log_t *log)
#endif
if (notify_fd == -1) {
- ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "eventfd() failed");
+ ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno, "eventfd() failed");
return NGX_ERROR;
}
- ngx_log_debug1(NGX_LOG_DEBUG_EVENT, log, 0,
+ ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
"notify eventfd: %d", notify_fd);
- notify_event.handler = ngx_epoll_notify_handler;
- notify_event.log = log;
- notify_event.active = 1;
+ ngx_memzero(notify_event, sizeof(ngx_event_t));
- notify_conn.fd = notify_fd;
- notify_conn.read = ¬ify_event;
- notify_conn.log = log;
+ notify_event->data = notify_conn;
+ notify_event->handler = ngx_epoll_notify_handler;
+ notify_event->log = cycle->log;
+ notify_event->active = 1;
+
+ notify_conn->data = handler;
+ notify_conn->fd = notify_fd;
+ notify_conn->read = notify_event;
+ notify_conn->log = cycle->log;
ee.events = EPOLLIN|EPOLLET;
- ee.data.ptr = ¬ify_conn;
+ ee.data.ptr = notify_conn;
if (epoll_ctl(ep, EPOLL_CTL_ADD, notify_fd, &ee) == -1) {
- ngx_log_error(NGX_LOG_EMERG, log, ngx_errno,
+ ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
"epoll_ctl(EPOLL_CTL_ADD, eventfd) failed");
if (close(notify_fd) == -1) {
- ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
- "eventfd close() failed");
+ ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
+ "close() eventfd %d failed", notify_fd);
}
return NGX_ERROR;
@@ -431,31 +437,45 @@ ngx_epoll_notify_init(ngx_log_t *log)
static void
ngx_epoll_notify_handler(ngx_event_t *ev)
{
- ssize_t n;
- uint64_t count;
- ngx_err_t err;
- ngx_event_handler_pt handler;
+ ngx_connection_t *c = ev->data;
+
+ ssize_t n;
+ uint64_t count;
+ ngx_err_t err;
+ ngx_event_handler_pt handler;
if (++ev->index == NGX_MAX_UINT32_VALUE) {
ev->index = 0;
- n = read(notify_fd, &count, sizeof(uint64_t));
+ n = read(c->fd, &count, sizeof(uint64_t));
err = ngx_errno;
ngx_log_debug3(NGX_LOG_DEBUG_EVENT, ev->log, 0,
- "read() eventfd %d: %z count:%uL", notify_fd, n, count);
+ "read() eventfd %d: %z count:%uL", c->fd, n, count);
if ((size_t) n != sizeof(uint64_t)) {
ngx_log_error(NGX_LOG_ALERT, ev->log, err,
- "read() eventfd %d failed", notify_fd);
+ "read() eventfd %d failed", c->fd);
}
}
- handler = ev->data;
+ handler = c->data;
handler(ev);
}
+
+static void
+ngx_epoll_notify_close(ngx_event_t *notify_event)
+{
+ ngx_connection_t *c = notify_event->data;
+
+ if (close(c->fd) == -1) {
+ ngx_log_error(NGX_LOG_ALERT, notify_event->log, ngx_errno,
+ "close() eventfd %d failed", c->fd);
+ }
+}
+
#endif
@@ -536,17 +556,6 @@ ngx_epoll_done(ngx_cycle_t *cycle)
ep = -1;
-#if (NGX_HAVE_EVENTFD)
-
- if (close(notify_fd) == -1) {
- ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
- "eventfd close() failed");
- }
-
- notify_fd = -1;
-
-#endif
-
#if (NGX_HAVE_FILE_AIO)
if (ngx_eventfd != -1) {
@@ -762,15 +771,14 @@ ngx_epoll_del_connection(ngx_connection_
#if (NGX_HAVE_EVENTFD)
static ngx_int_t
-ngx_epoll_notify(ngx_event_handler_pt handler)
+ngx_epoll_notify(ngx_event_t *notify_event)
{
- static uint64_t inc = 1;
+ static uint64_t inc = 1;
+ ngx_connection_t *c = notify_event->data;
- notify_event.data = handler;
-
- if ((size_t) write(notify_fd, &inc, sizeof(uint64_t)) != sizeof(uint64_t)) {
- ngx_log_error(NGX_LOG_ALERT, notify_event.log, ngx_errno,
- "write() to eventfd %d failed", notify_fd);
+ if ((size_t) write(c->fd, &inc, sizeof(uint64_t)) != sizeof(uint64_t)) {
+ ngx_log_error(NGX_LOG_ALERT, notify_event->log, ngx_errno,
+ "write() to eventfd %d failed", c->fd);
return NGX_ERROR;
}
diff -r c131f20c9562 -r e4241e448bc9 src/event/modules/ngx_eventport_module.c
--- a/src/event/modules/ngx_eventport_module.c
+++ b/src/event/modules/ngx_eventport_module.c
@@ -140,7 +140,9 @@ static ngx_int_t ngx_eventport_add_event
ngx_uint_t flags);
static ngx_int_t ngx_eventport_del_event(ngx_event_t *ev, ngx_int_t event,
ngx_uint_t flags);
-static ngx_int_t ngx_eventport_notify(ngx_event_handler_pt handler);
+static ngx_int_t ngx_eventport_notify_init(ngx_event_t *notify_event,
+ ngx_event_handler_pt handler, ngx_cycle_t *cycle);
+static ngx_int_t ngx_eventport_notify(ngx_event_t *notify_event);
static ngx_int_t ngx_eventport_process_events(ngx_cycle_t *cycle,
ngx_msec_t timer, ngx_uint_t flags);
@@ -151,7 +153,6 @@ static int ep = -1;
static port_event_t *event_list;
static ngx_uint_t nevents;
static timer_t event_timer = (timer_t) -1;
-static ngx_event_t notify_event;
static ngx_str_t eventport_name = ngx_string("eventport");
@@ -181,7 +182,9 @@ ngx_event_module_t ngx_eventport_module
ngx_eventport_del_event, /* disable an event */
NULL, /* add an connection */
NULL, /* delete an connection */
+ ngx_eventport_notify_init, /* init a notify */
ngx_eventport_notify, /* trigger a notify */
+ NULL, /* close a notify */
ngx_eventport_process_events, /* process the events */
ngx_eventport_init, /* init the events */
ngx_eventport_done, /* done the events */
@@ -223,9 +226,6 @@ ngx_eventport_init(ngx_cycle_t *cycle, n
"port_create() failed");
return NGX_ERROR;
}
-
- notify_event.active = 1;
- notify_event.log = cycle->log;
}
if (nevents < epcf->events) {
@@ -418,12 +418,24 @@ ngx_eventport_del_event(ngx_event_t *ev,
static ngx_int_t
-ngx_eventport_notify(ngx_event_handler_pt handler)
+ngx_eventport_notify_init(ngx_event_t *notify_event,
+ ngx_event_handler_pt handler, ngx_cycle_t *cycle)
{
- notify_event.handler = handler;
+ ngx_memzero(notify_event, sizeof(ngx_event_t));
- if (port_send(ep, 0, ¬ify_event) != 0) {
- ngx_log_error(NGX_LOG_ALERT, notify_event.log, ngx_errno,
+ notify_event->handler = handler;
+ notify_event->active = 1;
+ notify_event->log = cycle->log;
+
+ return NGX_OK;
+}
+
+
+static ngx_int_t
+ngx_eventport_notify(ngx_event_t *notify_event)
+{
+ if (port_send(ep, 0, notify_event) != 0) {
+ ngx_log_error(NGX_LOG_ALERT, notify_event->log, ngx_errno,
"port_send() failed");
return NGX_ERROR;
}
diff -r c131f20c9562 -r e4241e448bc9 src/event/modules/ngx_iocp_module.c
--- a/src/event/modules/ngx_iocp_module.c
+++ b/src/event/modules/ngx_iocp_module.c
@@ -64,7 +64,9 @@ ngx_event_module_t ngx_iocp_module_ctx
NULL, /* disable an event */
NULL, /* add an connection */
ngx_iocp_del_connection, /* delete an connection */
+ NULL, /* init a notify */
NULL, /* trigger a notify */
+ NULL, /* close a notify */
ngx_iocp_process_events, /* process the events */
ngx_iocp_init, /* init the events */
ngx_iocp_done /* done the events */
diff -r c131f20c9562 -r e4241e448bc9 src/event/modules/ngx_kqueue_module.c
--- a/src/event/modules/ngx_kqueue_module.c
+++ b/src/event/modules/ngx_kqueue_module.c
@@ -18,7 +18,8 @@ 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);
+static ngx_int_t ngx_kqueue_notify_init(ngx_event_t *notify_event,
+ ngx_event_handler_pt handler, ngx_cycle_t *cycle);
#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,
@@ -28,7 +29,7 @@ static ngx_int_t ngx_kqueue_del_event(ng
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);
+static ngx_int_t ngx_kqueue_notify(ngx_event_t *notify_event);
#endif
static ngx_int_t ngx_kqueue_process_events(ngx_cycle_t *cycle, ngx_msec_t timer,
ngx_uint_t flags);
@@ -45,11 +46,6 @@ static struct kevent *change_list;
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
-
static ngx_str_t kqueue_name = ngx_string("kqueue");
@@ -86,9 +82,13 @@ ngx_event_module_t ngx_kqueue_module_ct
NULL, /* add an connection */
NULL, /* delete an connection */
#ifdef EVFILT_USER
+ ngx_kqueue_notify_init, /* init a notify */
ngx_kqueue_notify, /* trigger a notify */
+ NULL, /* close a notify */
#else
+ NULL, /* init a notify */
NULL, /* trigger a notify */
+ NULL, /* close a notify */
#endif
ngx_kqueue_process_events, /* process the events */
ngx_kqueue_init, /* init the events */
@@ -132,12 +132,6 @@ ngx_kqueue_init(ngx_cycle_t *cycle, ngx_
"kqueue() failed");
return NGX_ERROR;
}
-
-#ifdef EVFILT_USER
- if (ngx_kqueue_notify_init(cycle->log) != NGX_OK) {
- return NGX_ERROR;
- }
-#endif
}
if (max_changes < kcf->changes) {
@@ -230,27 +224,39 @@ ngx_kqueue_init(ngx_cycle_t *cycle, ngx_
#ifdef EVFILT_USER
static ngx_int_t
-ngx_kqueue_notify_init(ngx_log_t *log)
+ngx_kqueue_notify_init(ngx_event_t *notify_event, ngx_event_handler_pt handler,
+ ngx_cycle_t *cycle)
{
- 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;
+ struct kevent *notify_kev;
- if (kevent(ngx_kqueue, ¬ify_kev, 1, NULL, 0, NULL) == -1) {
- ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
+ notify_kev = ngx_pcalloc(cycle->pool, sizeof(struct kevent));
+ if (notify_kev == NULL) {
+ return NGX_ERROR;
+ }
+
+ notify_kev->ident = (uintptr_t) notify_event;
+ 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, cycle->log, ngx_errno,
"kevent(EVFILT_USER, EV_ADD) failed");
return NGX_ERROR;
}
- notify_event.active = 1;
- notify_event.log = log;
+ ngx_memzero(notify_event, sizeof(ngx_event_t));
- notify_kev.flags = 0;
- notify_kev.fflags = NOTE_TRIGGER;
- notify_kev.udata = NGX_KQUEUE_UDATA_T ((uintptr_t) ¬ify_event);
+ notify_event->data = notify_kev;
+ notify_event->handler = handler;
+ notify_event->active = 1;
+ notify_event->log = cycle->log;
+
+ notify_kev->flags = 0;
+ notify_kev->fflags = NOTE_TRIGGER;
+ notify_kev->udata = NGX_KQUEUE_UDATA_T ((uintptr_t) notify_event);
return NGX_OK;
}
@@ -478,12 +484,12 @@ ngx_kqueue_set_event(ngx_event_t *ev, ng
#ifdef EVFILT_USER
static ngx_int_t
-ngx_kqueue_notify(ngx_event_handler_pt handler)
+ngx_kqueue_notify(ngx_event_t *notify_event)
{
- notify_event.handler = handler;
+ struct kevent *notify_kev = notify_event->data;
- if (kevent(ngx_kqueue, ¬ify_kev, 1, NULL, 0, NULL) == -1) {
- ngx_log_error(NGX_LOG_ALERT, notify_event.log, ngx_errno,
+ 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;
}
diff -r c131f20c9562 -r e4241e448bc9 src/event/modules/ngx_poll_module.c
--- a/src/event/modules/ngx_poll_module.c
+++ b/src/event/modules/ngx_poll_module.c
@@ -39,7 +39,9 @@ ngx_event_module_t ngx_poll_module_ctx
ngx_poll_del_event, /* disable an event */
NULL, /* add an connection */
NULL, /* delete an connection */
+ NULL, /* init a notify */
NULL, /* trigger a notify */
+ NULL, /* close a notify */
ngx_poll_process_events, /* process the events */
ngx_poll_init, /* init the events */
ngx_poll_done /* done the events */
diff -r c131f20c9562 -r e4241e448bc9 src/event/modules/ngx_select_module.c
--- a/src/event/modules/ngx_select_module.c
+++ b/src/event/modules/ngx_select_module.c
@@ -47,7 +47,9 @@ ngx_event_module_t ngx_select_module_ct
ngx_select_del_event, /* disable an event */
NULL, /* add an connection */
NULL, /* delete an connection */
+ NULL, /* init a notify */
NULL, /* trigger a notify */
+ NULL, /* close a notify */
ngx_select_process_events, /* process the events */
ngx_select_init, /* init the events */
ngx_select_done /* done the events */
diff -r c131f20c9562 -r e4241e448bc9 src/event/modules/ngx_win32_select_module.c
--- a/src/event/modules/ngx_win32_select_module.c
+++ b/src/event/modules/ngx_win32_select_module.c
@@ -48,7 +48,9 @@ ngx_event_module_t ngx_select_module_ct
ngx_select_del_event, /* disable an event */
NULL, /* add an connection */
NULL, /* delete an connection */
+ NULL, /* init a notify */
NULL, /* trigger a notify */
+ NULL, /* close a notify */
ngx_select_process_events, /* process the events */
ngx_select_init, /* init the events */
ngx_select_done /* done the events */
diff -r c131f20c9562 -r e4241e448bc9 src/event/ngx_event.c
--- a/src/event/ngx_event.c
+++ b/src/event/ngx_event.c
@@ -170,7 +170,7 @@ ngx_event_module_t ngx_event_core_modul
ngx_event_core_create_conf, /* create configuration */
ngx_event_core_init_conf, /* init configuration */
- { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }
+ { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }
};
diff -r c131f20c9562 -r e4241e448bc9 src/event/ngx_event.h
--- a/src/event/ngx_event.h
+++ b/src/event/ngx_event.h
@@ -184,7 +184,10 @@ typedef struct {
ngx_int_t (*add_conn)(ngx_connection_t *c);
ngx_int_t (*del_conn)(ngx_connection_t *c, ngx_uint_t flags);
- ngx_int_t (*notify)(ngx_event_handler_pt handler);
+ ngx_int_t (*notify_init)(ngx_event_t *notify_event,
+ ngx_event_handler_pt handler, ngx_cycle_t *cycle);
+ ngx_int_t (*notify)(ngx_event_t *notify_event);
+ void (*notify_close)(ngx_event_t *notify_event);
ngx_int_t (*process_events)(ngx_cycle_t *cycle, ngx_msec_t timer,
ngx_uint_t flags);
@@ -416,7 +419,9 @@ extern ngx_uint_t ngx_use_epo
#define ngx_add_conn ngx_event_actions.add_conn
#define ngx_del_conn ngx_event_actions.del_conn
+#define ngx_notify_init ngx_event_actions.notify_init
#define ngx_notify ngx_event_actions.notify
+#define ngx_notify_close ngx_event_actions.notify_close
#define ngx_add_timer ngx_event_add_timer
#define ngx_del_timer ngx_event_del_timer
More information about the nginx-devel
mailing list