libuv fixes for foreign loop test
authorAndy Green <andy@warmcat.com>
Wed, 4 May 2016 00:27:56 +0000 (08:27 +0800)
committerAndy Green <andy@warmcat.com>
Wed, 4 May 2016 00:40:46 +0000 (08:40 +0800)
Signed-off-by: Andy Green <andy@warmcat.com>
lib/libuv.c
lib/lws-plat-unix.c
test-server/test-server-libuv.c

index a230b57fb8062ab9088df7587cb3eed68af8b4f3..3e22c501b3ac5711bf72ba73ca25b769fc983de5 100644 (file)
@@ -106,7 +106,7 @@ lws_io_cb(uv_poll_t *watcher, int status, int revents)
 LWS_VISIBLE void
 lws_uv_sigint_cb(uv_signal_t *watcher, int signum)
 {
-       lwsl_info("internal signal handler caught signal %d\n", signum);
+       lwsl_err("internal signal handler caught signal %d\n", signum);
        lws_libuv_stop(watcher->data);
 }
 
@@ -156,8 +156,10 @@ lws_uv_initloop(struct lws_context *context, uv_loop_t *loop, int tsi)
                return 1;
 #endif
                pt->ev_loop_foreign = 0;
-       } else
+       } else {
+               lwsl_notice(" Using foreign event loop...\n");
                pt->ev_loop_foreign = 1;
+       }
 
        pt->io_loop_uv = loop;
        uv_idle_init(loop, &pt->uv_idle);
@@ -183,16 +185,15 @@ lws_uv_initloop(struct lws_context *context, uv_loop_t *loop, int tsi)
                if (vh->lserv_wsi) {
                        vh->lserv_wsi->w_read.context = context;
                        n = uv_poll_init_socket(pt->io_loop_uv,
-                                    &vh->lserv_wsi->w_read.uv_watcher,
-                                    vh->lserv_wsi->sock);
+                                               &vh->lserv_wsi->w_read.uv_watcher,
+                                               vh->lserv_wsi->sock);
                        if (n) {
                                lwsl_err("uv_poll_init failed %d, sockfd=%p\n",
                                        n, (void *)(long)vh->lserv_wsi->sock);
 
                                return -1;
                        }
-                       uv_poll_start(&vh->lserv_wsi->w_read.uv_watcher,
-                                     UV_READABLE, lws_io_cb);
+                       lws_libuv_io(vh->lserv_wsi, LWS_EV_START | LWS_EV_READ);
                }
                vh = vh->vhost_next;
        }
@@ -203,12 +204,12 @@ lws_uv_initloop(struct lws_context *context, uv_loop_t *loop, int tsi)
        return status;
 }
 
-void lws_uv_close_cb(uv_handle_t *handle)
+static void lws_uv_close_cb(uv_handle_t *handle)
 {
-
+       //lwsl_err("%s\n", __func__);
 }
 
-void lws_uv_walk_cb(uv_handle_t *handle, void *arg)
+static void lws_uv_walk_cb(uv_handle_t *handle, void *arg)
 {
        uv_close(handle, lws_uv_close_cb);
 }
@@ -217,7 +218,7 @@ void
 lws_libuv_destroyloop(struct lws_context *context, int tsi)
 {
        struct lws_context_per_thread *pt = &context->pt[tsi];
-       int m;
+       int m, budget = 100;
 
        if (!lws_check_opt(context->options, LWS_SERVER_OPTION_LIBUV))
                return;
@@ -227,19 +228,39 @@ lws_libuv_destroyloop(struct lws_context *context, int tsi)
 
        if (context->use_ev_sigint)
                uv_signal_stop(&pt->w_sigint.uv_watcher);
-       for (m = 0; m < ARRAY_SIZE(sigs); m++)
+
+       for (m = 0; m < ARRAY_SIZE(sigs); m++) {
                uv_signal_stop(&pt->signals[m]);
-       if (!pt->ev_loop_foreign) {
+               uv_close((uv_handle_t *)&pt->signals[m], lws_uv_close_cb);
+       }
+
+       uv_timer_stop(&pt->uv_timeout_watcher);
+       uv_close((uv_handle_t *)&pt->uv_timeout_watcher, lws_uv_close_cb);
+
+       uv_idle_stop(&pt->uv_idle);
+       uv_close((uv_handle_t *)&pt->uv_idle, lws_uv_close_cb);
+
+       while (budget-- && uv_run(pt->io_loop_uv, UV_RUN_NOWAIT))
+               ;
+
+       if (!pt->ev_loop_foreign)
                uv_stop(pt->io_loop_uv);
-               uv_walk(pt->io_loop_uv, lws_uv_walk_cb, NULL);
-               while (uv_run(pt->io_loop_uv, UV_RUN_NOWAIT));
+
+       if (pt->ev_loop_foreign)
+               return;
+
+       uv_walk(pt->io_loop_uv, lws_uv_walk_cb, NULL);
+       if (pt->ev_loop_foreign)
+               return;
+
+       while (uv_run(pt->io_loop_uv, UV_RUN_NOWAIT))
+               ;
 #if UV_VERSION_MAJOR > 0
-               m = uv_loop_close(pt->io_loop_uv);
-               if (m == UV_EBUSY)
-                       lwsl_debug("%s: uv_loop_close: UV_EBUSY\n", __func__);
+       m = uv_loop_close(pt->io_loop_uv);
+       if (m == UV_EBUSY)
+               lwsl_err("%s: uv_loop_close: UV_EBUSY\n", __func__);
 #endif
-               lws_free(pt->io_loop_uv);
-       }
+       lws_free(pt->io_loop_uv);
 }
 
 void
@@ -335,9 +356,10 @@ lws_libuv_kill(const struct lws_context *context)
        int n;
 
        for (n = 0; n < context->count_threads; n++)
-               if (context->pt[n].io_loop_uv && LWS_LIBUV_ENABLED(context))
+               if (context->pt[n].io_loop_uv &&
+                   LWS_LIBUV_ENABLED(context) &&
+                   !context->pt[n].ev_loop_foreign)
                        uv_stop(context->pt[n].io_loop_uv);
-       // TODO uv_stop check foreign loop? or not?
 }
 
 /*
index 98b6c588fc10995eaed878771472ff2a7f5d69c9..e26b041fa5ae97e6680848c32b8513df25cab7a7 100644 (file)
@@ -567,6 +567,10 @@ lws_plat_delete_socket_from_fds(struct lws_context *context,
                                                struct lws *wsi, int m)
 {
        struct lws_context_per_thread *pt = &context->pt[(int)wsi->tsi];
+
+       lws_libev_io(wsi, LWS_EV_STOP | LWS_EV_READ | LWS_EV_WRITE);
+       lws_libuv_io(wsi, LWS_EV_STOP | LWS_EV_READ | LWS_EV_WRITE);
+
        pt->fds_count--;
 }
 
index f3cdffa82787d3f8d3dc2cf8e66002a6f2d24839..986a3d85a68b94b076f18a6939d2705b46d6fd74 100644 (file)
@@ -20,6 +20,7 @@
  */
 
 #include "test-server.h"
+#include <uv.h>
 
 int close_testing;
 int max_poll_elements;
@@ -165,6 +166,7 @@ static struct option options[] = {
        { NULL, 0, 0, 0 }
 };
 
+#if UV_VERSION_MAJOR > 0
 /* ----- this code is only needed for foreign / external libuv tests -----*/
 struct counter
 {
@@ -211,11 +213,13 @@ static void lws_uv_walk_cb(uv_handle_t *handle, void *arg)
 }
 
 /* --- end of foreign test code ---- */
+#endif
 
 int main(int argc, char **argv)
 {
        struct lws_context_creation_info info;
        char interface_name[128] = "";
+#if UV_VERSION_MAJOR > 0
 /* --- only needed for foreign loop test ---> */
        uv_loop_t loop;
        uv_signal_t signal_outer;
@@ -223,6 +227,7 @@ int main(int argc, char **argv)
        struct counter ctr;
        int foreign_libuv_loop = 0;
 /* <--- only needed for foreign loop test --- */
+#endif
        uv_timer_t timeout_watcher;
        const char *iface = NULL;
        char cert_path[1024];
@@ -250,7 +255,9 @@ int main(int argc, char **argv)
                        continue;
                switch (n) {
                case 'f':
+#if UV_VERSION_MAJOR > 0
                        foreign_libuv_loop = 1;
+#endif
                        break;
                case 'e':
                        opts |= LWS_SERVER_OPTION_LIBEV;
@@ -356,6 +363,7 @@ int main(int argc, char **argv)
        info.timeout_secs = 5;
        info.options = opts | LWS_SERVER_OPTION_LIBUV;
 
+#if UV_VERSION_MAJOR > 0
        if (foreign_libuv_loop) {
                /* create the foreign loop */
                uv_loop_init(&loop);
@@ -377,6 +385,7 @@ int main(int argc, char **argv)
 
                /* timer will stop loop and we will get here */
        }
+#endif
 
        context = lws_create_context(&info);
        if (context == NULL) {
@@ -386,10 +395,13 @@ int main(int argc, char **argv)
 
        lws_uv_sigint_cfg(context, 1, signal_cb);
 
+#if UV_VERSION_MAJOR > 0
        if (foreign_libuv_loop)
                /* we have our own uv loop outside of lws */
                lws_uv_initloop(context, &loop, 0);
-       else {
+       else
+#endif
+       {
                /*
                 * lws will create his own libuv loop in the context
                 */
@@ -403,7 +415,7 @@ int main(int argc, char **argv)
        uv_timer_init(lws_uv_getloop(context, 0), &timeout_watcher);
        uv_timer_start(&timeout_watcher, uv_timeout_cb_dumb_increment, 50, 50);
 
-
+#if UV_VERSION_MAJOR > 0
        if (foreign_libuv_loop) {
                /*
                 * prepare inner timer on loop, to run along with lws.
@@ -474,7 +486,9 @@ int main(int argc, char **argv)
                lwsl_notice("uv loop close rc %s\n",
                            e ? uv_strerror(e) : "ok");
 
-       } else {
+       } else
+#endif
+       {
                lws_libuv_run(context, 0);
 
 bail: