From 3d033984f541510809b5424f4d1d6c81b33b78ad Mon Sep 17 00:00:00 2001 From: Denis Osvald Date: Tue, 22 Mar 2016 15:19:10 +0100 Subject: [PATCH] libuv: handle signals only if requested Signed-off-by: Denis Osvald --- lib/libuv.c | 37 ++++++++++++++++++++++++++++++------- lib/libwebsockets.h | 4 ++-- test-server/test-server-libuv.c | 6 ++++-- 3 files changed, 36 insertions(+), 11 deletions(-) diff --git a/lib/libuv.c b/lib/libuv.c index ddfd2af..9b1e515 100644 --- a/lib/libuv.c +++ b/lib/libuv.c @@ -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? } /* diff --git a/lib/libwebsockets.h b/lib/libwebsockets.h index fe15298..8f05b34 100644 --- a/lib/libwebsockets.h +++ b/lib/libwebsockets.h @@ -1492,7 +1492,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, @@ -1511,7 +1511,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 diff --git a/test-server/test-server-libuv.c b/test-server/test-server-libuv.c index d7ce0dd..b6ef528 100644 --- a/test-server/test-server-libuv.c +++ b/test-server/test-server-libuv.c @@ -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); -- 2.7.4