diff --git a/lib/core-net/pollfd.c b/lib/core-net/pollfd.c index 12986f406..69ba5daf6 100644 --- a/lib/core-net/pollfd.c +++ b/lib/core-net/pollfd.c @@ -313,7 +313,7 @@ __remove_wsi_socket_from_fds(struct lws *wsi) } #endif - if (wsi->vhost && + if (wsi->vhost && wsi->vhost->protocols && wsi->vhost->protocols[0].callback(wsi, LWS_CALLBACK_LOCK_POLL, wsi->user_space, (void *)&pa, 1)) return -1; @@ -332,9 +332,9 @@ __remove_wsi_socket_from_fds(struct lws *wsi) LWS_EV_STOP | LWS_EV_READ | LWS_EV_WRITE | LWS_EV_PREPARE_DELETION); - lwsl_debug("%s: wsi=%p, skt=%d, fds pos=%d, end guy pos=%d, endfd=%d\n", - __func__, wsi, wsi->desc.sockfd, wsi->position_in_fds_table, - pt->fds_count, pt->fds[pt->fds_count].fd); +// lwsl_debug("%s: wsi=%p, skt=%d, fds pos=%d, end guy pos=%d, endfd=%d\n", +// __func__, wsi, wsi->desc.sockfd, wsi->position_in_fds_table, +// pt->fds_count, pt->fds[pt->fds_count].fd); if (m != LWS_NO_FDS_POS) { @@ -500,7 +500,7 @@ __lws_same_vh_protocol_remove(struct lws *wsi) { struct lws_dll *head; - if (!wsi->vhost) + if (!wsi->vhost || !wsi->vhost->same_vh_protocol_heads) return; head = &wsi->vhost->same_vh_protocol_heads[(int)wsi->bound_vhost_index]; diff --git a/lib/core/context.c b/lib/core/context.c index b2f6164df..5991ea7fc 100644 --- a/lib/core/context.c +++ b/lib/core/context.c @@ -510,6 +510,8 @@ lws_context_destroy3(struct lws_context *context) #if defined(LWS_WITH_NETWORK) int n; + lwsl_debug("%s\n", __func__); + for (n = 0; n < context->count_threads; n++) { #if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2) struct lws_context_per_thread *pt = &context->pt[n]; @@ -567,6 +569,8 @@ lws_context_destroy2(struct lws_context *context) vh = vh1; } + lwsl_debug("%p: post vh listl\n", __func__); + /* remove ourselves from the pending destruction list */ while (context->vhost_pending_destruction_list) @@ -574,6 +578,8 @@ lws_context_destroy2(struct lws_context *context) __lws_vhost_destroy2(context->vhost_pending_destruction_list); #endif + lwsl_debug("%p: post pdl\n", __func__); + lws_stats_log_dump(context); #if defined(LWS_WITH_NETWORK) lws_ssl_context_destroy(context); @@ -593,6 +599,8 @@ lws_context_destroy2(struct lws_context *context) lws_free(context->pl_hash_table); #endif + lwsl_debug("%p: baggage\n", __func__); + if (context->external_baggage_free_on_destroy) free(context->external_baggage_free_on_destroy); @@ -611,10 +619,13 @@ lws_context_destroy2(struct lws_context *context) return; } + lwsl_debug("%p: post dc2\n", __func__); + if (!context->pt[0].event_loop_foreign) { int n; for (n = 0; n < context->count_threads; n++) if (context->pt[n].inside_service) { + lwsl_debug("%p: bailing as inside service\n", __func__); lws_context_unlock(context); /* } context --- */ return; } diff --git a/lib/event-libs/libevent/libevent.c b/lib/event-libs/libevent/libevent.c index 9e3c8037d..e1f48a489 100644 --- a/lib/event-libs/libevent/libevent.c +++ b/lib/event-libs/libevent/libevent.c @@ -114,6 +114,9 @@ lws_event_cb(evutil_socket_t sock_fd, short revents, void *ctx) } wsi = wsi_from_fd(context, sock_fd); + if (!wsi) { + return; + } pt = &context->pt[(int)wsi->tsi]; lws_service_fd_tsi(context, &eventfd, wsi->tsi); @@ -362,7 +365,7 @@ elops_destroy_context2_event(struct lws_context *context) struct lws_context_per_thread *pt; int n, m; - lwsl_debug("%s\n", __func__); + lwsl_debug("%s: in\n", __func__); for (n = 0; n < context->count_threads; n++) { int budget = 1000; @@ -393,6 +396,8 @@ elops_destroy_context2_event(struct lws_context *context) } + lwsl_debug("%s: out\n", __func__); + return 0; } diff --git a/lib/event-libs/libuv/libuv.c b/lib/event-libs/libuv/libuv.c index 7ea7eb846..88c3d3f2e 100644 --- a/lib/event-libs/libuv/libuv.c +++ b/lib/event-libs/libuv/libuv.c @@ -563,7 +563,8 @@ elops_wsi_logical_close_uv(struct lws *wsi) if (wsi->listener || wsi->event_pipe) { lwsl_debug("%s: %p: %d %d stop listener / pipe poll\n", __func__, wsi, wsi->listener, wsi->event_pipe); - uv_poll_stop(wsi->w_read.uv.pwatcher); + if (wsi->w_read.uv.pwatcher) + uv_poll_stop(wsi->w_read.uv.pwatcher); } lwsl_debug("%s: lws_libuv_closehandle: wsi %p\n", __func__, wsi); /* diff --git a/lib/plat/unix/unix-init.c b/lib/plat/unix/unix-init.c index d209b885e..135058c90 100644 --- a/lib/plat/unix/unix-init.c +++ b/lib/plat/unix/unix-init.c @@ -89,7 +89,7 @@ lws_plat_context_late_destroy(struct lws_context *context) #endif #if defined(LWS_WITH_NETWORK) if (context->lws_lookup) - lws_free(context->lws_lookup); + lws_free_set_NULL(context->lws_lookup); #endif if (!context->fd_random) lwsl_err("ZERO RANDOM FD\n"); diff --git a/lib/roles/listen/ops-listen.c b/lib/roles/listen/ops-listen.c index 662434509..67234f807 100644 --- a/lib/roles/listen/ops-listen.c +++ b/lib/roles/listen/ops-listen.c @@ -92,6 +92,9 @@ rops_handle_POLLIN_listen(struct lws_context_per_thread *pt, struct lws *wsi, return LWS_HPI_RET_HANDLED; } + if (context->being_destroyed) + return LWS_HPI_RET_PLEASE_CLOSE_ME; + lws_plat_set_socket_options(wsi->vhost, accept_fd, 0); #if defined(LWS_WITH_IPV6) @@ -117,8 +120,7 @@ rops_handle_POLLIN_listen(struct lws_context_per_thread *pt, struct lws *wsi, NULL, (void *)(lws_intptr_t)accept_fd, 0)) { lwsl_debug("Callback denied net connection\n"); - compatible_close(accept_fd); - break; + return LWS_HPI_RET_PLEASE_CLOSE_ME; } if (!(wsi->vhost->options & diff --git a/minimal-examples/http-server/minimal-http-server-eventlib-smp/CMakeLists.txt b/minimal-examples/http-server/minimal-http-server-eventlib-smp/CMakeLists.txt new file mode 100644 index 000000000..a60b3d60a --- /dev/null +++ b/minimal-examples/http-server/minimal-http-server-eventlib-smp/CMakeLists.txt @@ -0,0 +1,91 @@ +cmake_minimum_required(VERSION 2.8) +include(CheckIncludeFile) +include(CheckCSourceCompiles) + +set(SAMP lws-minimal-http-server-eventlib-smp) +set(SRCS minimal-http-server-eventlib-smp.c) + +MACRO(require_pthreads result) + CHECK_INCLUDE_FILE(pthread.h LWS_HAVE_PTHREAD_H) + if (NOT LWS_HAVE_PTHREAD_H) + if (LWS_WITH_MINIMAL_EXAMPLES) + set(result 0) + else() + message(FATAL_ERROR "threading support requires pthreads") + endif() + endif() +ENDMACRO() + +# If we are being built as part of lws, confirm current build config supports +# reqconfig, else skip building ourselves. +# +# If we are being built externally, confirm installed lws was configured to +# support reqconfig, else error out with a helpful message about the problem. +# +MACRO(require_lws_config reqconfig _val result) + + if (DEFINED ${reqconfig}) + if (${reqconfig}) + set (rq 1) + else() + set (rq 0) + endif() + else() + set(rq 0) + endif() + + if (${_val} EQUAL ${rq}) + set(SAME 1) + else() + set(SAME 0) + endif() + + if (LWS_WITH_MINIMAL_EXAMPLES AND NOT ${SAME}) + if (${_val}) + message("${SAMP}: skipping as lws being built without ${reqconfig}") + else() + message("${SAMP}: skipping as lws built with ${reqconfig}") + endif() + set(${result} 0) + else() + if (LWS_WITH_MINIMAL_EXAMPLES) + set(MET ${SAME}) + else() + CHECK_C_SOURCE_COMPILES("#include \nint main(void) {\n#if defined(${reqconfig})\n return 0;\n#else\n fail;\n#endif\n return 0;\n}\n" HAS_${reqconfig}) + if (NOT DEFINED HAS_${reqconfig} OR NOT HAS_${reqconfig}) + set(HAS_${reqconfig} 0) + else() + set(HAS_${reqconfig} 1) + endif() + if ((HAS_${reqconfig} AND ${_val}) OR (NOT HAS_${reqconfig} AND NOT ${_val})) + set(MET 1) + else() + set(MET 0) + endif() + endif() + if (NOT MET) + if (${_val}) + message(FATAL_ERROR "This project requires lws must have been configured with ${reqconfig}") + else() + message(FATAL_ERROR "Lws configuration of ${reqconfig} is incompatible with this project") + endif() + endif() + + endif() +ENDMACRO() + +set(requirements 1) +require_pthreads(requirements) +require_lws_config(LWS_ROLE_H1 1 requirements) +require_lws_config(LWS_WITHOUT_SERVER 0 requirements) + +if (requirements) + add_executable(${SAMP} ${SRCS}) + + if (websockets_shared) + target_link_libraries(${SAMP} websockets_shared pthread) + add_dependencies(${SAMP} websockets_shared pthread) + else() + target_link_libraries(${SAMP} websockets pthread) + endif() +endif() diff --git a/minimal-examples/http-server/minimal-http-server-eventlib-smp/README.md b/minimal-examples/http-server/minimal-http-server-eventlib-smp/README.md new file mode 100644 index 000000000..56dfcc45d --- /dev/null +++ b/minimal-examples/http-server/minimal-http-server-eventlib-smp/README.md @@ -0,0 +1,33 @@ +# lws minimal http server eventlib + +WARNING: this is under development, it's not stable. + +This demonstrates a minimal http server that can use any of the event libraries + +Commandline option|Meaning +---|--- +-d |Debug verbosity in decimal, eg, -d15 +-t |Number of threads to use. +--uv|Use the libuv event library (lws must have been configured with `-DLWS_WITH_LIBUV=1`) +--event|Use the libevent library (lws must have been configured with `-DLWS_WITH_LIBEVENT=1`) +--ev|Use the libev event library (lws must have been configured with `-DLWS_WITH_LIBEV=1`) + +## build + +lilbwebsockets must have been built with `LWS_MAX_SMP` greater than 1 to use +multiple threads. + +``` + $ cmake . && make +``` + +## usage + +``` + $ ./lws-minimal-http-server-eventlib-smp +[2018/03/04 09:30:02:7986] USER: LWS minimal http server-eventlib | visit http://localhost:7681 +[2018/03/04 09:30:02:7986] NOTICE: Creating Vhost 'default' port 7681, 1 protocols, IPv6 on +``` + +Visit http://localhost:7681 + diff --git a/minimal-examples/http-server/minimal-http-server-eventlib-smp/localhost-100y.cert b/minimal-examples/http-server/minimal-http-server-eventlib-smp/localhost-100y.cert new file mode 100644 index 000000000..6f372db40 --- /dev/null +++ b/minimal-examples/http-server/minimal-http-server-eventlib-smp/localhost-100y.cert @@ -0,0 +1,34 @@ +-----BEGIN CERTIFICATE----- +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 +e2Hl/7M0c/lbZ4FvXgARlex2rkgS0Ka06HE= +-----END CERTIFICATE----- diff --git a/minimal-examples/http-server/minimal-http-server-eventlib-smp/localhost-100y.key b/minimal-examples/http-server/minimal-http-server-eventlib-smp/localhost-100y.key new file mode 100644 index 000000000..148f8598e --- /dev/null +++ b/minimal-examples/http-server/minimal-http-server-eventlib-smp/localhost-100y.key @@ -0,0 +1,52 @@ +-----BEGIN PRIVATE KEY----- +MIIJQwIBADANBgkqhkiG9w0BAQEFAASCCS0wggkpAgEAAoICAQCjYtuWaICCY0tJ +PubxpIgIL+WWmz/fmK8IQr11Wtee6/IUyUlo5I602mq1qcLhT/kmpoR8Di3DAmHK +nSWdPWtn1BtXLErLlUiHgZDrZWInmEBjKM1DZf+CvNGZ+EzPgBv5nTekLWcfI5ZZ +toGuIP1Dl/IkNDw8zFz4cpiMe/BFGemyxdHhLrKHSm8Eo+nT734tItnHKT/m6DSU +0xlZ13d6ehLRm7/+Nx47M3XMTRH5qKP/7TTE2s0U6+M0tsGI2zpRi+m6jzhNyMBT +J1u58qAe3ZW5/+YAiuZYAB6n5bhUp4oFuB5wYbcBywVR8ujInpF8buWQUjy5N8pS +Np7szdYsnLJpvAd0sibrNPjC0FQCNrpNjgJmIK3+mKk4kXX7ZTwefoAzTK4l2pHN +uC53QVc/EF++GBLAxmvCDq9ZpMIYi7OmzkkAKKC9Ue6Ef217LFQCFIBKIzv9cgi9 +fwPMLhrKleoVRNsecBsCP569WgJXhUnwf2lon4fEZr3+vRuc9shfqnV0nPN1IMSn +zXCast7I2fiuRXdIz96KjlGQpP4XfNVA+RGL7aMnWOFIaVrKWLzAtgzoGMTvP/Au +ehKXncBJhYtW0ltTioVx+5yTYSAZWl+IssmXjefxJqYi2/7QWmv1QC9psNcjTMaB +QLN03T1Qelbs7Y27sxdEnNUth4kI+wIDAQABAoICAFWe8MQZb37k2gdAV3Y6aq8f +qokKQqbCNLd3giGFwYkezHXoJfg6Di7oZxNcKyw35LFEghkgtQqErQqo35VPIoH+ +vXUpWOjnCmM4muFA9/cX6mYMc8TmJsg0ewLdBCOZVw+wPABlaqz+0UOiSMMftpk9 +fz9JwGd8ERyBsT+tk3Qi6D0vPZVsC1KqxxL/cwIFd3Hf2ZBtJXe0KBn1pktWht5A +Kqx9mld2Ovl7NjgiC1Fx9r+fZw/iOabFFwQA4dr+R8mEMK/7bd4VXfQ1o/QGGbMT +G+ulFrsiDyP+rBIAaGC0i7gDjLAIBQeDhP409ZhswIEc/GBtODU372a2CQK/u4Q/ +HBQvuBtKFNkGUooLgCCbFxzgNUGc83GB/6IwbEM7R5uXqsFiE71LpmroDyjKTlQ8 +YZkpIcLNVLw0usoGYHFm2rvCyEVlfsE3Ub8cFyTFk50SeOcF2QL2xzKmmbZEpXgl +xBHR0hjgon0IKJDGfor4bHO7Nt+1Ece8u2oTEKvpz5aIn44OeC5mApRGy83/0bvs +esnWjDE/bGpoT8qFuy+0urDEPNId44XcJm1IRIlG56ErxC3l0s11wrIpTmXXckqw +zFR9s2z7f0zjeyxqZg4NTPI7wkM3M8BXlvp2GTBIeoxrWB4V3YArwu8QF80QBgVz +mgHl24nTg00UH1OjZsABAoIBAQDOxftSDbSqGytcWqPYP3SZHAWDA0O4ACEM+eCw +au9ASutl0IDlNDMJ8nC2ph25BMe5hHDWp2cGQJog7pZ/3qQogQho2gUniKDifN77 +40QdykllTzTVROqmP8+efreIvqlzHmuqaGfGs5oTkZaWj5su+B+bT+9rIwZcwfs5 +YRINhQRx17qa++xh5mfE25c+M9fiIBTiNSo4lTxWMBShnK8xrGaMEmN7W0qTMbFH +PgQz5FcxRjCCqwHilwNBeLDTp/ZECEB7y34khVh531mBE2mNzSVIQcGZP1I/DvXj +W7UUNdgFwii/GW+6M0uUDy23UVQpbFzcV8o1C2nZc4Fb4zwBAoIBAQDKSJkFwwuR +naVJS6WxOKjX8MCu9/cKPnwBv2mmI2jgGxHTw5sr3ahmF5eTb8Zo19BowytN+tr6 +2ZFoIBA9Ubc9esEAU8l3fggdfM82cuR9sGcfQVoCh8tMg6BP8IBLOmbSUhN3PG2m +39I802u0fFNVQCJKhx1m1MFFLOu7lVcDS9JN+oYVPb6MDfBLm5jOiPuYkFZ4gH79 +J7gXI0/YKhaJ7yXthYVkdrSF6Eooer4RZgma62Dd1VNzSq3JBo6rYjF7Lvd+RwDC +R1thHrmf/IXplxpNVkoMVxtzbrrbgnC25QmvRYc0rlS/kvM4yQhMH3eA7IycDZMp +Y+0xm7I7jTT7AoIBAGKzKIMDXdCxBWKhNYJ8z7hiItNl1IZZMW2TPUiY0rl6yaCh +BVXjM9W0r07QPnHZsUiByqb743adkbTUjmxdJzjaVtxN7ZXwZvOVrY7I7fPWYnCE +fXCr4+IVpZI/ZHZWpGX6CGSgT6EOjCZ5IUufIvEpqVSmtF8MqfXO9o9uIYLokrWQ +x1dBl5UnuTLDqw8bChq7O5y6yfuWaOWvL7nxI8NvSsfj4y635gIa/0dFeBYZEfHI +UlGdNVomwXwYEzgE/c19ruIowX7HU/NgxMWTMZhpazlxgesXybel+YNcfDQ4e3RM +OMz3ZFiaMaJsGGNf4++d9TmMgk4Ns6oDs6Tb9AECggEBAJYzd+SOYo26iBu3nw3L +65uEeh6xou8pXH0Tu4gQrPQTRZZ/nT3iNgOwqu1gRuxcq7TOjt41UdqIKO8vN7/A +aJavCpaKoIMowy/aGCbvAvjNPpU3unU8jdl/t08EXs79S5IKPcgAx87sTTi7KDN5 +SYt4tr2uPEe53NTXuSatilG5QCyExIELOuzWAMKzg7CAiIlNS9foWeLyVkBgCQ6S +me/L8ta+mUDy37K6vC34jh9vK9yrwF6X44ItRoOJafCaVfGI+175q/eWcqTX4q+I +G4tKls4sL4mgOJLq+ra50aYMxbcuommctPMXU6CrrYyQpPTHMNVDQy2ttFdsq9iK +TncCggEBAMmt/8yvPflS+xv3kg/ZBvR9JB1In2n3rUCYYD47ReKFqJ03Vmq5C9nY +56s9w7OUO8perBXlJYmKZQhO4293lvxZD2Iq4NcZbVSCMoHAUzhzY3brdgtSIxa2 +gGveGAezZ38qKIU26dkz7deECY4vrsRkwhpTW0LGVCpjcQoaKvymAoCmAs8V2oMr +Ziw1YQ9uOUoWwOqm1wZqmVcOXvPIS2gWAs3fQlWjH9hkcQTMsUaXQDOD0aqkSY3E +NqOvbCV1/oUpRi3076khCoAXI1bKSn/AvR3KDP14B5toHI/F5OTSEiGhhHesgRrs +fBrpEY1IATtPq1taBZZogRqI3rOkkPk= +-----END PRIVATE KEY----- diff --git a/minimal-examples/http-server/minimal-http-server-eventlib-smp/minimal-http-server-eventlib-smp.c b/minimal-examples/http-server/minimal-http-server-eventlib-smp/minimal-http-server-eventlib-smp.c new file mode 100644 index 000000000..b13091d9d --- /dev/null +++ b/minimal-examples/http-server/minimal-http-server-eventlib-smp/minimal-http-server-eventlib-smp.c @@ -0,0 +1,159 @@ +/* + * lws-minimal-http-server-eventlib-smp + * + * Copyright (C) 2018 - 2019 Andy Green + * + * This file is made available under the Creative Commons CC0 1.0 + * Universal Public Domain Dedication. + * + * This demonstrates a minimal http[s] server that can work with any of the + * supported event loop backends, or the default poll() one. + * + * To keep it simple, it serves stuff from the subdirectory + * "./mount-origin" of the directory it was started in. + * You can change that by changing mount.origin below. + */ + +#include +#include +#include + +#include + +#define COUNT_THREADS 8 + +static struct lws_context *context; +static volatile int interrupted; + +static const struct lws_http_mount mount = { + /* .mount_next */ NULL, /* linked-list "next" */ + /* .mountpoint */ "/", /* mountpoint URL */ + /* .origin */ "./mount-origin", /* serve from dir */ + /* .def */ "index.html", /* default filename */ + /* .protocol */ NULL, + /* .cgienv */ NULL, + /* .extra_mimetypes */ NULL, + /* .interpret */ NULL, + /* .cgi_timeout */ 0, + /* .cache_max_age */ 0, + /* .auth_mask */ 0, + /* .cache_reusable */ 0, + /* .cache_revalidate */ 0, + /* .cache_intermediaries */ 0, + /* .origin_protocol */ LWSMPRO_FILE, /* files in a dir */ + /* .mountpoint_len */ 1, /* char count */ + /* .basic_auth_login_file */ NULL, +}; + +void *thread_service(void *threadid) +{ + while (lws_service_tsi(context, 10000, + (int)(lws_intptr_t)threadid) >= 0 && + !interrupted) + ; + + pthread_exit(NULL); + + return NULL; +} + +void signal_cb(void *handle, int signum) +{ + interrupted = 1; + + switch (signum) { + case SIGTERM: + case SIGINT: + break; + default: + lwsl_err("%s: signal %d\n", __func__, signum); + break; + } + lws_context_destroy(context); +} + +void sigint_handler(int sig) +{ + signal_cb(NULL, sig); +} + +int main(int argc, const char **argv) +{ + pthread_t pthread_service[COUNT_THREADS]; + struct lws_context_creation_info info; + const char *p; + void *retval; + int n, logs = LLL_USER | LLL_ERR | LLL_WARN | LLL_NOTICE + /* for LLL_ verbosity above NOTICE to be built into lws, + * lws must have been configured and built with + * -DCMAKE_BUILD_TYPE=DEBUG instead of =RELEASE */ + /* | LLL_INFO */ /* | LLL_PARSER */ /* | LLL_HEADER */ + /* | LLL_EXT */ /* | LLL_CLIENT */ /* | LLL_LATENCY */ + /* | LLL_DEBUG */; + + if ((p = lws_cmdline_option(argc, argv, "-d"))) + logs = atoi(p); + + lws_set_log_level(logs, NULL); + lwsl_user("LWS minimal http server eventlib SMP | visit http://localhost:7681\n"); + lwsl_user(" [-s (ssl)] [--uv (libuv)] [--ev (libev)] [--event (libevent)]\n"); + lwsl_user("WARNING: Not stable, under development!\n"); + + memset(&info, 0, sizeof info); /* otherwise uninitialized garbage */ + info.port = 7681; + info.mounts = &mount; + info.error_document_404 = "/404.html"; + info.pcontext = &context; + info.signal_cb = signal_cb; + info.options = + LWS_SERVER_OPTION_HTTP_HEADERS_SECURITY_BEST_PRACTICES_ENFORCE; + + if ((p = lws_cmdline_option(argc, argv, "-t"))) { + info.count_threads = atoi(p); + if (info.count_threads < 1 || info.count_threads > LWS_MAX_SMP) + return 1; + } else + info.count_threads = COUNT_THREADS; + + if (lws_cmdline_option(argc, argv, "-s")) { + info.options |= LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT; + info.ssl_cert_filepath = "localhost-100y.cert"; + info.ssl_private_key_filepath = "localhost-100y.key"; + } + + if (lws_cmdline_option(argc, argv, "--uv")) + info.options |= LWS_SERVER_OPTION_LIBUV; + else + if (lws_cmdline_option(argc, argv, "--event")) + info.options |= LWS_SERVER_OPTION_LIBEVENT; + else + if (lws_cmdline_option(argc, argv, "--ev")) + info.options |= LWS_SERVER_OPTION_LIBEV; + else + signal(SIGINT, sigint_handler); + + context = lws_create_context(&info); + if (!context) { + lwsl_err("lws init failed\n"); + return 1; + } + + lwsl_notice(" Service threads: %d\n", lws_get_count_threads(context)); + + /* start all the service threads */ + + for (n = 0; n < lws_get_count_threads(context); n++) + if (pthread_create(&pthread_service[n], NULL, thread_service, + (void *)(lws_intptr_t)n)) + lwsl_err("Failed to start service thread\n"); + + /* wait for all the service threads to exit */ + + while ((--n) >= 0) + pthread_join(pthread_service[n], &retval); + + lwsl_notice("%s: calling external context destroy\n", __func__); + lws_context_destroy(context); + + return 0; +} diff --git a/minimal-examples/http-server/minimal-http-server-eventlib-smp/mount-origin/404.html b/minimal-examples/http-server/minimal-http-server-eventlib-smp/mount-origin/404.html new file mode 100644 index 000000000..3e5a14b9f --- /dev/null +++ b/minimal-examples/http-server/minimal-http-server-eventlib-smp/mount-origin/404.html @@ -0,0 +1,9 @@ + + + +
+

404

+ Sorry, that file doesn't exist. + + + diff --git a/minimal-examples/http-server/minimal-http-server-eventlib-smp/mount-origin/favicon.ico b/minimal-examples/http-server/minimal-http-server-eventlib-smp/mount-origin/favicon.ico new file mode 100644 index 000000000..c0cc2e3df Binary files /dev/null and b/minimal-examples/http-server/minimal-http-server-eventlib-smp/mount-origin/favicon.ico differ diff --git a/minimal-examples/http-server/minimal-http-server-eventlib-smp/mount-origin/index.html b/minimal-examples/http-server/minimal-http-server-eventlib-smp/mount-origin/index.html new file mode 100644 index 000000000..8da5b6619 --- /dev/null +++ b/minimal-examples/http-server/minimal-http-server-eventlib-smp/mount-origin/index.html @@ -0,0 +1,15 @@ + + + + + + +
+ + Hello from the minimal http server event loop example. +
+ You can confirm the 404 page handler by going to this + nonexistant page. + + + diff --git a/minimal-examples/http-server/minimal-http-server-eventlib-smp/mount-origin/libwebsockets.org-logo.svg b/minimal-examples/http-server/minimal-http-server-eventlib-smp/mount-origin/libwebsockets.org-logo.svg new file mode 100644 index 000000000..7baea649f --- /dev/null +++ b/minimal-examples/http-server/minimal-http-server-eventlib-smp/mount-origin/libwebsockets.org-logo.svg @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/minimal-examples/http-server/minimal-http-server-eventlib-smp/mount-origin/strict-csp.svg b/minimal-examples/http-server/minimal-http-server-eventlib-smp/mount-origin/strict-csp.svg new file mode 100644 index 000000000..cd128f1d2 --- /dev/null +++ b/minimal-examples/http-server/minimal-http-server-eventlib-smp/mount-origin/strict-csp.svg @@ -0,0 +1,53 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +