From 93db6fe3aaff421d61a15993ba6827b742ab00d1 Mon Sep 17 00:00:00 2001 From: Garrett D'Amore Date: Mon, 27 Nov 2017 14:21:20 -0800 Subject: fixes #2 Websocket transport This is a rather large changeset -- it fundamentally adds websocket transport, but as part of this changeset we added a generic framework for both HTTP and websocket. We also made some supporting changes to the core, such as changing the way timeouts work for AIOs and adding additional state keeping for AIOs, and adding a common framework for deferred finalization (to avoid certain kinds of circular deadlocks during resource cleanup). We also invented a new initialization framework so that we can avoid wiring in knowledge about them into the master initialization framework. The HTTP framework is not yet complete, but it is good enough for simple static serving and building additional services on top of -- including websocket. We expect both websocket and HTTP support to evolve considerably, and so these are not part of the public API yet. Property support for the websocket transport (in particular address properties) is still missing, as is support for TLS. The websocket transport here is a bit more robust than the original nanomsg implementation, as it supports multiple sockets listening at the same port sharing the same HTTP server instance, discriminating between them based on URI (and possibly the virtual host). Websocket is enabled by default at present, and work to conditionalize HTTP and websocket further (to minimize bloat) is still pending. --- src/core/init.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) (limited to 'src/core/init.c') diff --git a/src/core/init.c b/src/core/init.c index 4a7fd974..cb6dbeee 100644 --- a/src/core/init.c +++ b/src/core/init.c @@ -1,6 +1,7 @@ // // Copyright 2017 Garrett D'Amore // Copyright 2017 Capitar IT Group BV +// Copyright 2017 Staysail Systems, Inc. // // This software is supplied under the terms of the MIT License, a // copy of which should be located in the distribution where this @@ -10,15 +11,25 @@ #include "core/nng_impl.h" +#include #include #include +static nni_mtx nni_init_mtx; +static nni_list nni_init_list; +static bool nni_inited = false; + static int nni_init_helper(void) { int rv; + nni_mtx_init(&nni_init_mtx); + NNI_LIST_INIT(&nni_init_list, nni_initializer, i_node); + nni_inited = true; + if (((rv = nni_taskq_sys_init()) != 0) || + ((rv = nni_reap_sys_init()) != 0) || ((rv = nni_timer_sys_init()) != 0) || ((rv = nni_aio_sys_init()) != 0) || ((rv = nni_random_sys_init()) != 0) || @@ -29,6 +40,7 @@ nni_init_helper(void) ((rv = nni_tran_sys_init()) != 0)) { nni_fini(); } + return (rv); } @@ -41,14 +53,54 @@ nni_init(void) void nni_fini(void) { + if (!nni_inited) { + return; + } + if (!nni_list_empty(&nni_init_list)) { + nni_initializer *init; + + nni_mtx_lock(&nni_init_mtx); + while ((init = nni_list_first(&nni_init_list)) != NULL) { + if (init->i_fini != NULL) { + init->i_fini(); + } + init->i_once = 0; + nni_list_remove(&nni_init_list, init); + } + nni_mtx_unlock(&nni_init_mtx); + } nni_tran_sys_fini(); nni_proto_sys_fini(); nni_pipe_sys_fini(); nni_ep_sys_fini(); nni_sock_sys_fini(); nni_random_sys_fini(); + nni_reap_sys_fini(); // must be before timer and aio (expire) nni_aio_sys_fini(); nni_timer_sys_fini(); nni_taskq_sys_fini(); + + nni_mtx_fini(&nni_init_mtx); nni_plat_fini(); + nni_inited = false; +} + +int +nni_initialize(nni_initializer *init) +{ + int rv; + if (init->i_once) { + return (0); + } + nni_mtx_lock(&nni_init_mtx); + if (init->i_once) { + nni_mtx_unlock(&nni_init_mtx); + return (0); + } + if ((rv = init->i_init()) == 0) { + init->i_once = 1; + nni_list_append(&nni_init_list, init); + } + nni_mtx_unlock(&nni_init_mtx); + return (rv); } -- cgit v1.2.3-70-g09d2