Follow-up to 2f9cce9, handle I/O watchers similar to timer+signal

This patch is a follow-up to 2f9cce9, and a complete refactor of
fe8f3f1 which first introduced the EPOLLERR and EPOLLHUP handling.
Then mainly for managing errors and hangups on stream sockets.

Now, instead of trying to reopen the epoll() fd, and breaking out
hard from the event loop on catastrophic error,  we now delegate
I/O watcher EPOLLERR and EPOLLHUP to the watcher callback, just
like other watchers.

Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This commit is contained in:
Joachim Nilsson
2017-11-14 12:16:23 +01:00
parent 966f29c207
commit 35a54ef75e
2 changed files with 7 additions and 34 deletions
-1
View File
@@ -44,7 +44,6 @@ typedef enum {
typedef struct {
int running;
int fd; /* For epoll() */
uint32_t errors;
LIST_HEAD(,uev) watchers;
uint32_t workaround; /* For workarounds, e.g. redirected stdin */
} uev_ctx_t;
+7 -33
View File
@@ -330,39 +330,6 @@ int uev_run(uev_ctx_t *ctx, int flags)
w = (uev_t *)ee[i].data.ptr;
events = ee[i].events;
if (events & (EPOLLHUP | EPOLLERR)) {
ctx->errors++;
if (ctx->errors >= 42) {
uev_t *tmp, *retry = w;
/* If not valid anymore, try to remove, ignore any errors. */
if (!is_valid_fd(w->fd))
_uev_watcher_stop(w);
/* Must recreate epoll fd now ... */
if (_init(ctx, 1)) {
/* Catastrophic error, no way to recover. */
uev_exit(ctx);
return -3;
}
/* Restart watchers in new efd */
LIST_FOREACH_SAFE(w, &ctx->watchers, link, tmp) {
if (_uev_watcher_active(w)) {
w->active = 0;
LIST_REMOVE(w, link);
_uev_watcher_start(w);
}
}
_uev_watcher_start(retry);
/* New efd, restart everything! */
ctx->errors = 0;
continue;
}
}
switch (w->type) {
case UEV_CRON_TYPE:
if (read(w->fd, &exp, sizeof(exp)) != sizeof(exp)) {
@@ -397,6 +364,13 @@ int uev_run(uev_ctx_t *ctx, int flags)
}
}
break;
case UEV_IO_TYPE:
if (events & (EPOLLHUP | EPOLLERR)) {
if (!is_valid_fd(w->fd))
uev_io_stop(w);
}
break;
}
if (w->cb)