From: Andy Green Date: Wed, 6 Apr 2016 01:23:16 +0000 (+0800) Subject: libuv add idle processing to force service where needed X-Git-Tag: upstream/2.0.3~138 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=09998e3ad8e658674cb3db126ea785baa14ccdbb;p=platform%2Fupstream%2Flibwebsockets.git libuv add idle processing to force service where needed https://github.com/warmcat/libwebsockets/issues/485 Signed-off-by: Andy Green --- diff --git a/lib/libuv.c b/lib/libuv.c index 64090aa..14d3f18 100644 --- a/lib/libuv.c +++ b/lib/libuv.c @@ -31,10 +31,35 @@ lws_feature_status_libuv(struct lws_context_creation_info *info) } static void +lws_uv_idle(uv_idle_t *handle) +{ + struct lws_context_per_thread *pt = container_of(handle, + struct lws_context_per_thread, uv_idle); + + lwsl_debug("%s\n", __func__); + + /* + * is there anybody with pending stuff that needs service forcing? + */ + if (!lws_service_adjust_timeout(pt->context, 1, pt->tid)) { + /* -1 timeout means just do forced service */ + lws_plat_service_tsi(pt->context, -1, pt->tid); + /* still somebody left who wants forced service? */ + if (!lws_service_adjust_timeout(pt->context, 1, pt->tid)) + /* yes... come back again later */ + return; + } + + /* there is nobody who needs service forcing, shut down idle */ + uv_idle_stop(handle); +} + +static void 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 *wsi = container_of(lws_io, struct lws, w_read); struct lws_context *context = lws_io->context; struct lws_pollfd eventfd; @@ -67,6 +92,8 @@ lws_io_cb(uv_poll_t *watcher, int status, int revents) } } lws_service_fd(context, &eventfd); + + uv_idle_start(&context->pt[(int)wsi->tsi].uv_idle, lws_uv_idle); } LWS_VISIBLE void @@ -96,7 +123,7 @@ lws_uv_timeout_cb(uv_timer_t *timer) struct lws_context_per_thread, uv_timeout_watcher); lwsl_debug("%s\n", __func__); - /* do timeout check only */ + lws_service_fd_tsi(pt->context, NULL, pt->tid); } @@ -117,6 +144,7 @@ lws_uv_initloop(struct lws_context *context, uv_loop_t *loop, int tsi) pt->ev_loop_foreign = 1; pt->io_loop_uv = loop; + uv_idle_init(loop, &pt->uv_idle); if (pt->context->use_ev_sigint) { assert(ARRAY_SIZE(sigs) <= ARRAY_SIZE(pt->signals)); diff --git a/lib/lws-plat-unix.c b/lib/lws-plat-unix.c index a9e8c88..2b89e22 100644 --- a/lib/lws-plat-unix.c +++ b/lib/lws-plat-unix.c @@ -122,7 +122,7 @@ LWS_VISIBLE int lws_plat_service_tsi(struct lws_context *context, int timeout_ms, int tsi) { struct lws_context_per_thread *pt = &context->pt[tsi]; - int n, m, c; + int n = -1, m, c; char buf; /* stay dead once we are dead */ @@ -130,6 +130,9 @@ lws_plat_service_tsi(struct lws_context *context, int timeout_ms, int tsi) if (!context || !context->vhost_list) return 1; + if (timeout_ms < 0) + goto faked_service; + lws_libev_run(context, tsi); lws_libuv_run(context, tsi); @@ -139,7 +142,8 @@ lws_plat_service_tsi(struct lws_context *context, int timeout_ms, int tsi) memset(&_lws, 0, sizeof(_lws)); _lws.context = context; - context->service_tid_detected = context->vhost_list->protocols[0].callback( + context->service_tid_detected = + context->vhost_list->protocols[0].callback( &_lws, LWS_CALLBACK_GET_THREAD_ID, NULL, NULL, 0); } context->service_tid = context->service_tid_detected; @@ -158,6 +162,7 @@ lws_plat_service_tsi(struct lws_context *context, int timeout_ms, int tsi) return 0; } +faked_service: m = lws_service_flag_pending(context, tsi); if (m) c = -1; /* unknown limit */ diff --git a/lib/lws-plat-win.c b/lib/lws-plat-win.c index 751771c..67c3c12 100644 --- a/lib/lws-plat-win.c +++ b/lib/lws-plat-win.c @@ -177,6 +177,9 @@ lws_plat_service_tsi(struct lws_context *context, int timeout_ms, int tsi) } context->service_tid = context->service_tid_detected; + if (timeout_ms < 0) + goto faked_service; + for (i = 0; i < pt->fds_count; ++i) { pfd = &pt->fds[i]; @@ -236,6 +239,8 @@ lws_plat_service_tsi(struct lws_context *context, int timeout_ms, int tsi) wsi->sock_send_blocking = 0; } +faked_service: + /* if someone faked their LWS_POLLIN, then go through all active fds */ if (lws_service_flag_pending(context, tsi)) { @@ -254,6 +259,9 @@ lws_plat_service_tsi(struct lws_context *context, int timeout_ms, int tsi) return 0; } + if (timeout_ms < 0) + return 0; + /* otherwise just do the one... must be a way to improve that... */ return lws_service_fd_tsi(context, pfd, tsi); diff --git a/lib/private-libwebsockets.h b/lib/private-libwebsockets.h index 04d1a89..5ebb974 100644 --- a/lib/private-libwebsockets.h +++ b/lib/private-libwebsockets.h @@ -598,6 +598,7 @@ struct lws_context_per_thread { uv_loop_t *io_loop_uv; uv_signal_t signals[8]; uv_timer_t uv_timeout_watcher; + uv_idle_t uv_idle; #endif #if defined(LWS_USE_LIBEV) struct lws_io_watcher w_accept;