diff options
author | Igor Sysoev <igor@sysoev.ru> | 2018-10-23 16:31:42 +0300 |
---|---|---|
committer | Igor Sysoev <igor@sysoev.ru> | 2018-10-23 16:31:42 +0300 |
commit | d4a99aad84e1ab432733650e9753814311e04a01 (patch) | |
tree | ab56e8454cc80952e975b94107a19deba758e648 /src | |
parent | 780181412623c0dc9232fc7f56055b6e3312a319 (diff) | |
download | unit-d4a99aad84e1ab432733650e9753814311e04a01.tar.gz unit-d4a99aad84e1ab432733650e9753814311e04a01.tar.bz2 |
Backout of ba94959b1dec and improving epoll error handling.
Diffstat (limited to 'src')
-rw-r--r-- | src/nxt_epoll_engine.c | 32 |
1 files changed, 28 insertions, 4 deletions
diff --git a/src/nxt_epoll_engine.c b/src/nxt_epoll_engine.c index d87b92cf..9f9c8f62 100644 --- a/src/nxt_epoll_engine.c +++ b/src/nxt_epoll_engine.c @@ -920,8 +920,8 @@ nxt_epoll_poll(nxt_event_engine_t *engine, nxt_msec_t timeout) ev->fd, events, ev, ev->read, ev->write); /* - * On error epoll may set EPOLLERR and EPOLLHUP only without EPOLLIN or - * EPOLLOUT, so the "error" variable enqueues only one active handler. + * On error epoll may set EPOLLERR and EPOLLHUP only without EPOLLIN + * or EPOLLOUT, so the "error" variable enqueues only error handler. */ error = ((events & (EPOLLERR | EPOLLHUP)) != 0); ev->epoll_error = error; @@ -932,7 +932,7 @@ nxt_epoll_poll(nxt_event_engine_t *engine, nxt_msec_t timeout) #endif - if ((events & EPOLLIN) || error) { + if ((events & EPOLLIN) != 0) { ev->read_ready = 1; if (ev->read != NXT_EVENT_BLOCKED) { @@ -948,9 +948,11 @@ nxt_epoll_poll(nxt_event_engine_t *engine, nxt_msec_t timeout) /* Level-triggered mode. */ nxt_epoll_disable_read(engine, ev); } + + error = 0; } - if ((events & EPOLLOUT) || error) { + if ((events & EPOLLOUT) != 0) { ev->write_ready = 1; if (ev->write != NXT_EVENT_BLOCKED) { @@ -966,7 +968,29 @@ nxt_epoll_poll(nxt_event_engine_t *engine, nxt_msec_t timeout) /* Level-triggered mode. */ nxt_epoll_disable_write(engine, ev); } + + error = 0; + } + + if (!error) { + continue; + } + + ev->read_ready = 1; + ev->write_ready = 1; + + if (ev->read == NXT_EVENT_BLOCKED && ev->write == NXT_EVENT_BLOCKED) { + + if (engine->u.epoll.mode == 0) { + /* Level-triggered mode. */ + nxt_epoll_disable(engine, ev); + } + + continue; } + + nxt_work_queue_add(&engine->fast_work_queue, nxt_epoll_error_handler, + ev->task, ev, ev->data); } } |