summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndy Green <andy@warmcat.com>2016-04-06 09:25:46 +0800
committerAndy Green <andy@warmcat.com>2016-04-07 18:56:40 +0800
commit3564e3d5e93a41d2e5bc10478394d10c36a80e1b (patch)
tree52ba4559e046f2a419bd759e3ab6e22b51531d2a
parent101bd4272a251e095cf681401f6a1fb79cf724a9 (diff)
downloadlibwebsockets-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.c31
-rw-r--r--lib/lws-plat-unix.c6
-rw-r--r--lib/lws-plat-win.c8
-rw-r--r--lib/private-libwebsockets.h1
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;