Improved epoll failures handling.
epoll changes are committed to the kernel before epoll_wait() or on changes array overflow. In the latter case if there are errors epoll_wait() timeout was not set to zero. This commit is related to #173 issue on GitHub. Thanks to 洪志道 (Hong Zhi Dao).
This commit is contained in:
@@ -67,7 +67,7 @@ static void nxt_epoll_enable_accept(nxt_event_engine_t *engine,
|
|||||||
nxt_fd_event_t *ev);
|
nxt_fd_event_t *ev);
|
||||||
static void nxt_epoll_change(nxt_event_engine_t *engine, nxt_fd_event_t *ev,
|
static void nxt_epoll_change(nxt_event_engine_t *engine, nxt_fd_event_t *ev,
|
||||||
int op, uint32_t events);
|
int op, uint32_t events);
|
||||||
static nxt_int_t nxt_epoll_commit_changes(nxt_event_engine_t *engine);
|
static void nxt_epoll_commit_changes(nxt_event_engine_t *engine);
|
||||||
static void nxt_epoll_error_handler(nxt_task_t *task, void *obj, void *data);
|
static void nxt_epoll_error_handler(nxt_task_t *task, void *obj, void *data);
|
||||||
#if (NXT_HAVE_SIGNALFD)
|
#if (NXT_HAVE_SIGNALFD)
|
||||||
static nxt_int_t nxt_epoll_add_signal(nxt_event_engine_t *engine);
|
static nxt_int_t nxt_epoll_add_signal(nxt_event_engine_t *engine);
|
||||||
@@ -593,7 +593,7 @@ nxt_epoll_change(nxt_event_engine_t *engine, nxt_fd_event_t *ev, int op,
|
|||||||
engine->u.epoll.fd, ev->fd, op, events);
|
engine->u.epoll.fd, ev->fd, op, events);
|
||||||
|
|
||||||
if (engine->u.epoll.nchanges >= engine->u.epoll.mchanges) {
|
if (engine->u.epoll.nchanges >= engine->u.epoll.mchanges) {
|
||||||
(void) nxt_epoll_commit_changes(engine);
|
nxt_epoll_commit_changes(engine);
|
||||||
}
|
}
|
||||||
|
|
||||||
ev->changing = 1;
|
ev->changing = 1;
|
||||||
@@ -605,18 +605,16 @@ nxt_epoll_change(nxt_event_engine_t *engine, nxt_fd_event_t *ev, int op,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static nxt_int_t
|
static void
|
||||||
nxt_epoll_commit_changes(nxt_event_engine_t *engine)
|
nxt_epoll_commit_changes(nxt_event_engine_t *engine)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
nxt_int_t retval;
|
|
||||||
nxt_fd_event_t *ev;
|
nxt_fd_event_t *ev;
|
||||||
nxt_epoll_change_t *change, *end;
|
nxt_epoll_change_t *change, *end;
|
||||||
|
|
||||||
nxt_debug(&engine->task, "epoll %d changes:%ui",
|
nxt_debug(&engine->task, "epoll %d changes:%ui",
|
||||||
engine->u.epoll.fd, engine->u.epoll.nchanges);
|
engine->u.epoll.fd, engine->u.epoll.nchanges);
|
||||||
|
|
||||||
retval = NXT_OK;
|
|
||||||
change = engine->u.epoll.changes;
|
change = engine->u.epoll.changes;
|
||||||
end = change + engine->u.epoll.nchanges;
|
end = change + engine->u.epoll.nchanges;
|
||||||
|
|
||||||
@@ -637,7 +635,7 @@ nxt_epoll_commit_changes(nxt_event_engine_t *engine)
|
|||||||
nxt_work_queue_add(&engine->fast_work_queue,
|
nxt_work_queue_add(&engine->fast_work_queue,
|
||||||
nxt_epoll_error_handler, ev->task, ev, ev->data);
|
nxt_epoll_error_handler, ev->task, ev, ev->data);
|
||||||
|
|
||||||
retval = NXT_ERROR;
|
engine->u.epoll.error = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
change++;
|
change++;
|
||||||
@@ -645,8 +643,6 @@ nxt_epoll_commit_changes(nxt_event_engine_t *engine)
|
|||||||
} while (change < end);
|
} while (change < end);
|
||||||
|
|
||||||
engine->u.epoll.nchanges = 0;
|
engine->u.epoll.nchanges = 0;
|
||||||
|
|
||||||
return retval;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -884,10 +880,13 @@ nxt_epoll_poll(nxt_event_engine_t *engine, nxt_msec_t timeout)
|
|||||||
struct epoll_event *event;
|
struct epoll_event *event;
|
||||||
|
|
||||||
if (engine->u.epoll.nchanges != 0) {
|
if (engine->u.epoll.nchanges != 0) {
|
||||||
if (nxt_epoll_commit_changes(engine) != NXT_OK) {
|
nxt_epoll_commit_changes(engine);
|
||||||
/* Error handlers have been enqueued on failure. */
|
}
|
||||||
timeout = 0;
|
|
||||||
}
|
if (engine->u.epoll.error) {
|
||||||
|
engine->u.epoll.error = 0;
|
||||||
|
/* Error handlers have been enqueued on failure. */
|
||||||
|
timeout = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
nxt_debug(&engine->task, "epoll_wait(%d) timeout:%M",
|
nxt_debug(&engine->task, "epoll_wait(%d) timeout:%M",
|
||||||
|
|||||||
@@ -202,6 +202,8 @@ typedef struct {
|
|||||||
nxt_uint_t mchanges;
|
nxt_uint_t mchanges;
|
||||||
int mevents;
|
int mevents;
|
||||||
|
|
||||||
|
uint8_t error; /* 1 bit */
|
||||||
|
|
||||||
nxt_epoll_change_t *changes;
|
nxt_epoll_change_t *changes;
|
||||||
struct epoll_event *events;
|
struct epoll_event *events;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user