From ed9f87c90119832c3c96fb9c352e53db61943fe4 Mon Sep 17 00:00:00 2001 From: Valentin Bartenev Date: Fri, 12 Apr 2013 15:02:33 +0000 Subject: [PATCH] Events: protection from stale events in eventport and devpoll. Stale write event may happen if read and write events was reported both, and processing of the read event closed descriptor. In practice this might result in "sendfilev() failed (134: ..." or "writev() failed (134: ..." errors when switching to next upstream server. See report here: http://mailman.nginx.org/pipermail/nginx/2013-April/038421.html --- src/event/modules/ngx_devpoll_module.c | 8 +++++++- src/event/modules/ngx_eventport_module.c | 2 +- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/event/modules/ngx_devpoll_module.c b/src/event/modules/ngx_devpoll_module.c index d09b5bc07..5f78cd7d3 100644 --- a/src/event/modules/ngx_devpoll_module.c +++ b/src/event/modules/ngx_devpoll_module.c @@ -343,7 +343,7 @@ ngx_devpoll_process_events(ngx_cycle_t *cycle, ngx_msec_t timer, ngx_fd_t fd; ngx_err_t err; ngx_int_t i; - ngx_uint_t level; + ngx_uint_t level, instance; ngx_event_t *rev, *wev, **queue; ngx_connection_t *c; struct pollfd pfd; @@ -510,7 +510,13 @@ ngx_devpoll_process_events(ngx_cycle_t *cycle, ngx_msec_t timer, ngx_locked_post_event(rev, queue); } else { + instance = rev->instance; + rev->handler(rev); + + if (c->fd == -1 || wev->instance != instance) { + continue; + } } } diff --git a/src/event/modules/ngx_eventport_module.c b/src/event/modules/ngx_eventport_module.c index d6dcb0bed..5f9cf4e35 100644 --- a/src/event/modules/ngx_eventport_module.c +++ b/src/event/modules/ngx_eventport_module.c @@ -551,7 +551,7 @@ ngx_eventport_process_events(ngx_cycle_t *cycle, ngx_msec_t timer, } else { rev->handler(rev); - if (ev->closed) { + if (ev->closed || ev->instance != instance) { continue; } }