summaryrefslogtreecommitdiffhomepage
path: root/src/nxt_epoll_engine.c
diff options
context:
space:
mode:
authorIgor Sysoev <igor@sysoev.ru>2018-10-23 16:31:42 +0300
committerIgor Sysoev <igor@sysoev.ru>2018-10-23 16:31:42 +0300
commitd4a99aad84e1ab432733650e9753814311e04a01 (patch)
treeab56e8454cc80952e975b94107a19deba758e648 /src/nxt_epoll_engine.c
parent780181412623c0dc9232fc7f56055b6e3312a319 (diff)
downloadunit-d4a99aad84e1ab432733650e9753814311e04a01.tar.gz
unit-d4a99aad84e1ab432733650e9753814311e04a01.tar.bz2
Backout of ba94959b1dec and improving epoll error handling.
Diffstat (limited to '')
-rw-r--r--src/nxt_epoll_engine.c32
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);
}
}