diff options
Diffstat (limited to 'src/pevent.c')
-rw-r--r-- | src/pevent.c | 54 |
1 files changed, 41 insertions, 13 deletions
diff --git a/src/pevent.c b/src/pevent.c index 7ed9b55..ea29825 100644 --- a/src/pevent.c +++ b/src/pevent.c @@ -9,6 +9,23 @@ #include "pevent.h" #include "log.h" +static int epoll_event_string(uint32_t event, char *buf, size_t siz); + + +static int epoll_event_string(uint32_t event, char *buf, size_t siz) +{ + if (event & EPOLLERR) { + snprintf(buf, siz, "%s", "EPOLLERR"); + } else if (event & EPOLLHUP) { + snprintf(buf, siz, "%s", "EPOLLHUP"); + } else if (event & EPOLLRDHUP) { + snprintf(buf, siz, "%s", "EPOLLRDHUP"); + } else if (event & EPOLLIN) { + snprintf(buf, siz, "%s", "EPOLLIN"); + } else return 1; + + return 0; +} void event_init(event_ctx **ctx) { @@ -75,20 +92,23 @@ int event_add_fd(event_ctx *ctx, int fd) int event_loop(event_ctx *ctx, on_event_cb on_event, void *user_data) { - int n, i; + int n, i, saved_errno; + char ev_err[16]; sigset_t eset; assert(ctx && on_event); sigemptyset(&eset); ctx->active = 1; + ctx->has_error = 0; - while (ctx->active) { + while (ctx->active && !ctx->has_error) { errno = 0; n = epoll_pwait(ctx->epoll_fd, ctx->events, POTD_MAXEVENTS, -1, &eset); + saved_errno = errno; if (errno == EINTR) continue; if (n < 0) { - ctx->active = 0; + ctx->has_error = 1; break; } @@ -100,21 +120,29 @@ int event_loop(event_ctx *ctx, on_event_cb on_event, void *user_data) (ctx->events[i].events & EPOLLRDHUP) || (!(ctx->events[i].events & EPOLLIN))) { - E_STRERR("Event epoll for descriptor %d", - ctx->events[i].data.fd); - ctx->active = 0; + if (epoll_event_string(ctx->events[i].events, ev_err, sizeof ev_err)) { + errno = saved_errno; + E_STRERR("Event for descriptor %d", + ctx->events[i].data.fd); + } else { + errno = saved_errno; + E_STRERR("Event [%s] for descriptor %d", + ev_err, ctx->events[i].data.fd); + } + + ctx->has_error = 1; } else { - if (!on_event(ctx, ctx->events[i].data.fd, user_data)) + if (!on_event(ctx, ctx->events[i].data.fd, user_data) && !ctx->has_error) W2("Event callback failed: [fd: %d , npoll: %d]", ctx->events[i].data.fd, n); } - if (!ctx->active) + if (!ctx->active || ctx->has_error) break; } } - return ctx->active == 0; + return ctx->has_error != 0; } forward_state @@ -150,6 +178,7 @@ event_forward_connection(event_ctx *ctx, int dest_fd, on_data_cb on_data, switch (siz) { case -1: E_STRERR("Client read from fd %d", ev->data.fd); + ctx->has_error = 1; rc = CON_IN_ERROR; break; case 0: @@ -177,6 +206,7 @@ event_forward_connection(event_ctx *ctx, int dest_fd, on_data_cb on_data, switch (siz) { case -1: + ctx->has_error = 1; rc = CON_OUT_ERROR; break; case 0: @@ -195,10 +225,8 @@ event_forward_connection(event_ctx *ctx, int dest_fd, on_data_cb on_data, D2("Connection state: %d", rc); if (rc != CON_OK) { - if (shutdown(ev->data.fd, SHUT_RDWR)) - E_STRERR("Shutdown source socket fd %d", ev->data.fd); - if (shutdown(dest_fd, SHUT_RDWR)) - E_STRERR("Shutdown dest socket fd %d", dest_fd); + shutdown(ev->data.fd, SHUT_RDWR); + shutdown(dest_fd, SHUT_RDWR); } return rc; } |