libuv: handle signals only if requested
authorDenis Osvald <denis.osvald@sartura.hr>
Tue, 22 Mar 2016 14:19:10 +0000 (15:19 +0100)
committerAndy Green <andy@warmcat.com>
Tue, 22 Mar 2016 23:44:06 +0000 (07:44 +0800)
Signed-off-by: Denis Osvald <denis.osvald@sartura.hr>
lib/libuv.c
lib/libwebsockets.h
test-server/test-server-libuv.c

index 3927d40..fbdf160 100644 (file)
@@ -66,9 +66,10 @@ lws_io_cb(uv_poll_t *watcher, int status, int revents)
 }
 
 LWS_VISIBLE void
-lws_uv_sigint_cb(uv_loop_t *loop, uv_signal_t *watcher, int revents)
+lws_uv_sigint_cb(uv_loop_t *loop, uv_signal_t *watcher, int signum)
 {
-       uv_stop(loop);
+       lwsl_info("internal signal handler caught signal %d\n", signum);
+       lws_libuv_stop(watcher->data);
 }
 
 LWS_VISIBLE int
@@ -97,6 +98,19 @@ lws_uv_timeout_cb(uv_timer_t *timer)
 
 static const int sigs[] = { SIGINT, SIGTERM, SIGSEGV, SIGFPE };
 
+struct lws_uv_sigint_ctx {
+       struct lws_context *context;
+       lws_uv_signal_cb_t *cb;
+};
+
+static void lws_uv_sigint_cb_wrapper(uv_signal_t *signal, int signum)
+{
+       struct lws_uv_sigint_ctx *p = signal->data;
+       uv_signal_t signal_fwd = *signal;
+       signal_fwd.data = p->context;
+       p->cb(signal->loop, &signal_fwd, signum);
+}
+
 LWS_VISIBLE int
 lws_uv_initloop(struct lws_context *context, uv_loop_t *loop, uv_signal_cb cb,
                int tsi)
@@ -114,10 +128,16 @@ lws_uv_initloop(struct lws_context *context, uv_loop_t *loop, uv_signal_cb cb,
 
        pt->io_loop_uv = loop;
 
-       assert(ARRAY_SIZE(sigs) <= ARRAY_SIZE(pt->signals));
-       for (n = 0; n < ARRAY_SIZE(sigs); n++) {
-               uv_signal_init(loop, &pt->signals[n]);
-               uv_signal_start(&pt->signals[n], cb, sigs[n]);
+       if (pt->context->use_ev_sigint) {
+               assert(ARRAY_SIZE(sigs) <= ARRAY_SIZE(pt->signals));
+               for (n = 0; n < ARRAY_SIZE(sigs); n++) {
+                       struct lws_uv_sigint_ctx *wrap_ctx = lws_malloc(sizeof(*wrap_ctx));
+                       wrap_ctx->context = pt->context;
+                       wrap_ctx->cb = context->lws_uv_sigint_cb;
+                       uv_signal_init(loop, &pt->signals[n]);
+                       pt->signals[n].data = wrap_ctx;
+                       uv_signal_start(&pt->signals[n], lws_uv_sigint_cb_wrapper, sigs[n]);
+               }
        }
 
        /*
@@ -165,8 +185,10 @@ 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]);
+               lws_free(pt->signals[m].data);
+       }
        if (!pt->ev_loop_foreign) {
                uv_stop(pt->io_loop_uv);
                uv_walk(pt->io_loop_uv, lws_uv_walk_cb, NULL);
@@ -269,6 +291,7 @@ lws_libuv_kill(const struct lws_context *context)
        for (n = 0; n < context->count_threads; n++)
                if (context->pt[n].io_loop_uv && LWS_LIBUV_ENABLED(context))
                        uv_stop(context->pt[n].io_loop_uv);
+       // TODO uv_stop check foreign loop? or not?
 }
 
 /*
index 91fadbc..31e0455 100644 (file)
@@ -1522,7 +1522,7 @@ lws_ev_sigint_cb(struct ev_loop *loop, struct ev_signal *watcher, int revents);
 #endif /* LWS_USE_LIBEV */
 
 #ifdef LWS_USE_LIBUV
-typedef void (lws_uv_signal_cb_t)(uv_loop_t *l, uv_signal_t *w, int revents);
+typedef void (lws_uv_signal_cb_t)(uv_loop_t *l, uv_signal_t *w, int signum);
 
 LWS_VISIBLE LWS_EXTERN int
 lws_uv_sigint_cfg(struct lws_context *context, int use_uv_sigint,
@@ -1541,7 +1541,7 @@ LWS_VISIBLE LWS_EXTERN uv_loop_t *
 lws_uv_getloop(struct lws_context *context, int tsi);
 
 LWS_VISIBLE void
-lws_uv_sigint_cb(uv_loop_t *loop, uv_signal_t *watcher, int revents);
+lws_uv_sigint_cb(uv_loop_t *loop, uv_signal_t *watcher, int signum);
 #endif /* LWS_USE_LIBUV */
 
 LWS_VISIBLE LWS_EXTERN int
index d7ce0dd..b6ef528 100644 (file)
@@ -112,7 +112,7 @@ static const struct lws_extension exts[] = {
        { NULL, NULL, NULL /* terminator */ }
 };
 
-void signal_cb(uv_signal_t *watcher, int revents)
+void signal_cb(uv_loop_t *loop, uv_signal_t *watcher, int signum)
 {
        lwsl_err("Signal %d caught, exiting...\n", watcher->signum);
        switch (watcher->signum) {
@@ -287,7 +287,9 @@ int main(int argc, char **argv)
                return -1;
        }
 
-       lws_uv_initloop(context, NULL, signal_cb, 0);
+       lws_uv_sigint_cfg(context, 1, signal_cb);
+
+       lws_uv_initloop(context, NULL, NULL, 0);
 
        uv_timer_init(lws_uv_getloop(context, 0), &timeout_watcher);
        uv_timer_start(&timeout_watcher, uv_timeout_cb_dumb_increment, 50, 50);