diff options
author | Andy Green <andy@warmcat.com> | 2016-04-06 09:25:46 +0800 |
---|---|---|
committer | Andy Green <andy@warmcat.com> | 2016-04-07 18:56:40 +0800 |
commit | 3564e3d5e93a41d2e5bc10478394d10c36a80e1b (patch) | |
tree | 52ba4559e046f2a419bd759e3ab6e22b51531d2a | |
parent | 101bd4272a251e095cf681401f6a1fb79cf724a9 (diff) | |
download | libwebsockets-3564e3d5e93a41d2e5bc10478394d10c36a80e1b.tar.gz libwebsockets-3564e3d5e93a41d2e5bc10478394d10c36a80e1b.tar.bz2 libwebsockets-3564e3d5e93a41d2e5bc10478394d10c36a80e1b.zip |
libuv add idle processing to force service where needed
https://github.com/warmcat/libwebsockets/issues/485
Signed-off-by: Andy Green <andy@warmcat.com>
-rw-r--r-- | lib/libuv.c | 31 | ||||
-rw-r--r-- | lib/lws-plat-unix.c | 6 | ||||
-rw-r--r-- | lib/lws-plat-win.c | 8 | ||||
-rw-r--r-- | lib/private-libwebsockets.h | 1 |
4 files changed, 43 insertions, 3 deletions
diff --git a/lib/libuv.c b/lib/libuv.c index 6e7038ba..28703161 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 @@ -95,8 +122,7 @@ lws_uv_timeout_cb(uv_timer_t *timer) struct lws_context_per_thread *pt = container_of(timer, struct lws_context_per_thread, uv_timeout_watcher); - lwsl_info("%s\n", __func__); - /* do timeout check only */ + lwsl_debug("%s\n", __func__); lws_service_fd_tsi(pt->context, NULL, pt->tid); } @@ -131,6 +157,7 @@ lws_uv_initloop(struct lws_context *context, uv_loop_t *loop, uv_signal_cb cb, 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 48a89703..2e51513d 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) return 1; + if (timeout_ms < 0) + goto faked_service; + lws_libev_run(context, tsi); lws_libuv_run(context, tsi); @@ -158,6 +161,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 428ae7cd..2c0213a9 100644 --- a/lib/lws-plat-win.c +++ b/lib/lws-plat-win.c @@ -176,6 +176,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]; if (pfd->fd == pt->lserv_fd) @@ -234,6 +237,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)) { @@ -252,6 +257,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 ca5be466..4cabdd92 100644 --- a/lib/private-libwebsockets.h +++ b/lib/private-libwebsockets.h @@ -561,6 +561,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; |