From 3eb59c90bf0ea12ef753d60741a2e66819cc2e99 Mon Sep 17 00:00:00 2001 From: Alex Hultman Date: Wed, 2 Mar 2016 11:39:37 +0100 Subject: [PATCH] libuv.c: Service fd with LWS_POLLHUP on poll errors --- lib/libuv.c | 42 +++++++++++++++++++++++++++--------------- 1 file changed, 27 insertions(+), 15 deletions(-) diff --git a/lib/libuv.c b/lib/libuv.c index ac1ab6d..ddfd2af 100644 --- a/lib/libuv.c +++ b/lib/libuv.c @@ -31,26 +31,36 @@ lws_feature_status_libuv(struct lws_context_creation_info *info) } static void -lws_accept_cb(uv_poll_t *watcher, int status, int revents) +lws_io_cb(uv_poll_t *watcher, int status, int revents) { struct lws_io_watcher *lws_io = container_of(watcher, struct lws_io_watcher, uv_watcher); struct lws_context *context = lws_io->context; struct lws_pollfd eventfd; - if (status < 0) - return; - eventfd.fd = watcher->io_watcher.fd; eventfd.events = 0; eventfd.revents = 0; - if (revents & UV_READABLE) { - eventfd.events |= LWS_POLLIN; - eventfd.revents |= LWS_POLLIN; - } - if (revents & UV_WRITABLE) { - eventfd.events |= LWS_POLLOUT; - eventfd.revents |= LWS_POLLOUT; + + if (status < 0) { + /* at this point status will be an UV error, like UV_EBADF, + we treat all errors as LWS_POLLHUP */ + + /* you might want to return; instead of servicing the fd in some cases */ + if (status == UV_EAGAIN) + return; + + eventfd.events |= LWS_POLLHUP; + eventfd.revents |= LWS_POLLHUP; + } else { + if (revents & UV_READABLE) { + eventfd.events |= LWS_POLLIN; + eventfd.revents |= LWS_POLLIN; + } + if (revents & UV_WRITABLE) { + eventfd.events |= LWS_POLLOUT; + eventfd.revents |= LWS_POLLOUT; + } } lws_service_fd(context, &eventfd); } @@ -119,8 +129,10 @@ lws_uv_initloop(struct lws_context *context, uv_loop_t *loop, uv_signal_cb cb, */ if (wsi) { wsi->w_read.context = context; - uv_poll_init(pt->io_loop_uv, &wsi->w_read.uv_watcher, pt->lserv_fd); - uv_poll_start(&wsi->w_read.uv_watcher, UV_READABLE, lws_accept_cb); + uv_poll_init(pt->io_loop_uv, &wsi->w_read.uv_watcher, + pt->lserv_fd); + uv_poll_start(&wsi->w_read.uv_watcher, UV_READABLE, + lws_io_cb); } uv_timer_init(pt->io_loop_uv, &pt->uv_timeout_watcher); @@ -211,7 +223,7 @@ lws_libuv_io(struct lws *wsi, int flags) if (flags & LWS_EV_READ) current_events |= UV_READABLE; - uv_poll_start(&w->uv_watcher, current_events, lws_accept_cb); + uv_poll_start(&w->uv_watcher, current_events, lws_io_cb); } else { if (flags & LWS_EV_WRITE) current_events &= ~UV_WRITABLE; @@ -223,7 +235,7 @@ lws_libuv_io(struct lws *wsi, int flags) uv_poll_stop(&w->uv_watcher); else uv_poll_start(&w->uv_watcher, current_events, - lws_accept_cb); + lws_io_cb); } } -- 2.7.4