From c108f04e85a15f4e1cc700b41999a92ce09a889d Mon Sep 17 00:00:00 2001 From: Maxim Dounin Date: Fri, 26 Mar 2021 01:44:59 +0300 Subject: Events: fixed expiration of timers in the past. If, at the start of an event loop iteration, there are any timers in the past (including timers expiring now), the ngx_process_events() function is called with zero timeout, and returns immediately even if there are no events. But the following code only calls ngx_event_expire_timers() if time actually changed, so this results in nginx spinning in the event loop till current time changes. While such timers are not expected to appear under normal conditions, as all such timers should be removed on previous event loop iterations, they still can appear due to bugs, zero timeouts set in the configuration (if this is not explicitly handled by the code), or due to external time changes on systems without clock_gettime(CLOCK_MONOTONIC). Fix is to call ngx_event_expire_timers() unconditionally. Calling it on each event loop iteration is not expected to be significant from performance point of view, especially compared to a syscall in ngx_process_events(). --- src/event/ngx_event.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'src/event') diff --git a/src/event/ngx_event.c b/src/event/ngx_event.c index ed7b30bf3..7777d043e 100644 --- a/src/event/ngx_event.c +++ b/src/event/ngx_event.c @@ -257,9 +257,7 @@ ngx_process_events_and_timers(ngx_cycle_t *cycle) ngx_shmtx_unlock(&ngx_accept_mutex); } - if (delta) { - ngx_event_expire_timers(); - } + ngx_event_expire_timers(); ngx_event_process_posted(cycle, &ngx_posted_events); } -- cgit From fd0546aa33d2b28fc89753c15439f356485ad845 Mon Sep 17 00:00:00 2001 From: Maxim Dounin Date: Sun, 28 Mar 2021 17:45:29 +0300 Subject: Events: fixed "port_dissociate() failed" alerts with eventport. If an attempt is made to delete an event which was already reported, port_dissociate() returns an error. Fix is avoid doing anything if ev->active is not set. Possible alternative approach would be to avoid calling ngx_del_event() at all if ev->active is not set. This approach, however, will require something else to re-add the other event of the connection, since both read and write events are dissociated if an event is reported on a file descriptor. Currently ngx_eventport_del_event() re-associates write event if called to delete read event, and vice versa. --- src/event/modules/ngx_eventport_module.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/event') diff --git a/src/event/modules/ngx_eventport_module.c b/src/event/modules/ngx_eventport_module.c index f67c70457..d304e1c91 100644 --- a/src/event/modules/ngx_eventport_module.c +++ b/src/event/modules/ngx_eventport_module.c @@ -399,7 +399,7 @@ ngx_eventport_del_event(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags) return NGX_ERROR; } - } else { + } else if (ev->active) { ngx_log_debug1(NGX_LOG_DEBUG_EVENT, ev->log, 0, "eventport del event: fd:%d", c->fd); -- cgit