1
0
Fork 0
mirror of https://github.com/warmcat/libwebsockets.git synced 2025-03-09 00:00:04 +01:00

minimal: smp + foreign: libuv foreign loops

AG: various fixes and adaptation of test protocol to use ring lock
to protect global wsi list against modifications from other threads
while in use
This commit is contained in:
Mykola Stryebkov 2020-09-30 19:11:50 +03:00 committed by Andy Green
parent 26a0d500a1
commit 89f4b739e1
10 changed files with 792 additions and 1 deletions

View file

@ -145,7 +145,6 @@ lws_client_connect_2_dnsreq(struct lws *wsi)
}
solo:
wsi->addrinfo_idx = 0;
/*
* clients who will create their own fresh connection keep a copy of

View file

@ -0,0 +1,44 @@
project(lws-minimal-ws-server-threads-foreign-smp C)
cmake_minimum_required(VERSION 2.8)
find_package(libwebsockets CONFIG REQUIRED)
list(APPEND CMAKE_MODULE_PATH ${LWS_CMAKE_DIR})
include(CheckIncludeFile)
include(CheckCSourceCompiles)
include(LwsCheckRequirements)
set(SAMP lws-minimal-ws-server-threads-foreign-smp)
set(SRCS minimal-ws-server.c)
set(requirements 1)
require_pthreads(requirements)
require_lws_config(LWS_ROLE_WS 1 requirements)
require_lws_config(LWS_WITH_SERVER 1 requirements)
require_lws_config(LWS_WITH_TLS 1 requirements)
require_lws_config(LWS_WITH_LIBUV 1 requirements)
CHECK_C_SOURCE_COMPILES("#include <libwebsockets.h>\nint main(void) {\n#if defined(LWS_WITH_LIBUV)\n return 0;\n#else\n fail;\n#endif\n return 0;\n}\n" LWS_WITH_LIBUV)
if (NOT LWS_WITH_LIBUV)
set(requirements 0)
endif()
if (requirements)
add_executable(${SAMP} ${SRCS})
find_path(LIBUV_INCLUDE_DIRS NAMES uv.h)
find_library(LIBUV_LIBRARIES NAMES uv)
message("libuv include dir: ${LIBUV_INCLUDE_DIRS}")
message("libuv libraries: ${LIBUV_LIBRARIES}")
include_directories("${LIBUV_INCLUDE_DIRS}")
set(extralibs ${extralibs} ${LIBUV_LIBRARIES})
message("Extra libs: ${extralibs}")
if (websockets_shared)
target_link_libraries(${SAMP} websockets_shared ${extralibs} ${PTHREAD_LIB} ${LIBWEBSOCKETS_DEP_LIBS})
add_dependencies(${SAMP} websockets_shared)
else()
target_link_libraries(${SAMP} websockets ${extralibs} ${PTHREAD_LIB} ${LIBWEBSOCKETS_DEP_LIBS})
endif()
endif()

View file

@ -0,0 +1,39 @@
# lws minimal ws server (threads) + SMP
This demonstrates both independent threads creating content as in the
-threads example, multiple service threads as in the http-server-smp
example (but with ws), and using the foreign libuv loop.
## build
You must first build libwebsockets itself with cmake `-DLWS_MAX_SMP=8`
or some other number greater than one, as well as `-DLWS_WITH_LIBUV=1`
```
$ cmake . && make
```
Pthreads is required on your system.
## usage
```
$ ./lws-minimal-ws-server-threads-smp
[2019/01/28 06:59:17:4217] USER: LWS minimal ws server + threads + smp | visit http://localhost:7681
[2019/01/28 06:59:17:4219] NOTICE: Service threads: 2
[2019/01/28 06:59:17:4220] NOTICE: LWS_CALLBACK_EVENT_WAIT_CANCELLED in svc tid 0x7fec48af8700
[2019/01/28 06:59:17:4220] NOTICE: LWS_CALLBACK_EVENT_WAIT_CANCELLED in svc tid 0x7fec48af8700
...
```
Visit http://localhost:7681 on multiple browser windows. You may need to open
4 before the second service thread is used (check "svc tid" in the browser output).
Two lws service threads are started.
Two separate asynchronous threads generate strings and add them to a ringbuffer,
signalling all lws service threads to send new entries to all the browser windows.
This demonstrates how to safely manage asynchronously generated content
and hook it up to the lws service threads.

View file

@ -0,0 +1,182 @@
/*
* lws-minimal-ws-server
*
* Written in 2010-2020 by Andy Green <andy@warmcat.com>
*
* This file is made available under the Creative Commons CC0 1.0
* Universal Public Domain Dedication.
*
* This demonstrates a minimal ws server that can cooperate with
* other threads cleanly. Two other threads are started, which fill
* a ringbuffer with strings at 10Hz.
*
* The actual work and thread spawning etc are done in the protocol
* implementation in protocol_lws_minimal.c.
*
* To keep it simple, it serves stuff in the subdirectory "./mount-origin" of
* the directory it was started in.
* You can change that by changing mount.origin.
*/
#include <libwebsockets.h>
#include <string.h>
#include <signal.h>
#if defined(WIN32)
#define HAVE_STRUCT_TIMESPEC
#if defined(pid_t)
#undef pid_t
#endif
#endif
#include <pthread.h>
#include <uv.h>
#define COUNT_THREADS 5
#define LWS_PLUGIN_STATIC
#include "protocol_lws_minimal.c"
static struct lws_protocols protocols[] = {
{ "http", lws_callback_http_dummy, 0, 0 },
LWS_PLUGIN_PROTOCOL_MINIMAL,
{ NULL, NULL, 0, 0 } /* terminator */
};
static struct lws_context *context;
static int interrupted;
static uv_loop_t loop[COUNT_THREADS];
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,
};
/*
* This demonstrates how to pass a pointer into a specific protocol handler
* running on a specific vhost. In this case, it's our default vhost and
* we pass the pvo named "config" with the value a const char * "myconfig".
*
* This is the preferred way to pass configuration into a specific vhost +
* protocol instance.
*/
static const struct lws_protocol_vhost_options pvo_ops = {
NULL,
NULL,
"config", /* pvo name */
(void *)"myconfig" /* pvo value */
};
static const struct lws_protocol_vhost_options pvo = {
NULL, /* "next" pvo linked-list */
&pvo_ops, /* "child" pvo linked-list */
"lws-minimal", /* protocol name we belong to on this vhost */
"" /* ignored */
};
void *thread_service(void *threadid)
{
while (lws_service_tsi(context, 0,
(int)(lws_intptr_t)threadid) >= 0 &&
!interrupted)
lwsl_notice("%s\n", __func__);
pthread_exit(NULL);
return NULL;
}
void signal_cb(uv_signal_t *watcher, int signum)
{
int n;
if (interrupted)
return;
lwsl_notice("signal_cb: signal %d caught\n", watcher->signum);
interrupted = 1;
uv_signal_stop(watcher);
lws_context_destroy(context);
for (n = 0; n < COUNT_THREADS; n++)
uv_stop(&loop[n]);
}
int main(int argc, const char **argv)
{
int n, logs = LLL_USER | LLL_ERR | LLL_WARN | LLL_NOTICE;
uv_signal_t *s, signal_outer[3 * COUNT_THREADS];
pthread_t pthread_service[COUNT_THREADS];
struct lws_context_creation_info info;
void *foreign_loops[COUNT_THREADS];
const char *p;
void *retval;
if ((p = lws_cmdline_option(argc, argv, "-d")))
logs = atoi(p);
lws_set_log_level(logs, NULL);
lwsl_user("LWS minimal ws server + threads + smp | visit http://localhost:7681\n");
for (n = 0; n < COUNT_THREADS; n++) {
int m;
uv_loop_init(&loop[n]);
for (m = 0; m < 3; m++) {
s = &signal_outer[n * 3 + m];
uv_signal_init(&loop[n], s);
uv_signal_start(s, signal_cb, SIGINT);
}
foreign_loops[n] = &loop[n];
}
memset(&info, 0, sizeof info); /* otherwise uninitialized garbage */
info.port = 7681;
info.mounts = &mount;
info.pcontext = &context;
info.protocols = protocols;
info.pvo = &pvo; /* per-vhost options */
info.foreign_loops = foreign_loops;
info.count_threads = COUNT_THREADS;
info.options = LWS_SERVER_OPTION_LIBUV |
LWS_SERVER_OPTION_HTTP_HEADERS_SECURITY_BEST_PRACTICES_ENFORCE;
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);
lws_context_destroy(context);
return 0;
}

View file

@ -0,0 +1,68 @@
var head = 0, tail = 0, ring = new Array();
function get_appropriate_ws_url(extra_url)
{
var pcol;
var u = document.URL;
/*
* We open the websocket encrypted if this page came on an
* https:// url itself, otherwise unencrypted
*/
if (u.substring(0, 5) === "https") {
pcol = "wss://";
u = u.substr(8);
} else {
pcol = "ws://";
if (u.substring(0, 4) === "http")
u = u.substr(7);
}
u = u.split("/");
/* + "/xxx" bit is for IE10 workaround */
return pcol + u[0] + "/" + extra_url;
}
function new_ws(urlpath, protocol)
{
return new WebSocket(urlpath, protocol);
}
document.addEventListener("DOMContentLoaded", function() {
var ws = new_ws(get_appropriate_ws_url(""), "lws-minimal");
try {
ws.onopen = function() {
document.getElementById("r").disabled = 0;
};
ws.onmessage =function got_packet(msg) {
var n, s = "";
ring[head] = msg.data + "\n";
head = (head + 1) % 50;
if (tail === head)
tail = (tail + 1) % 50;
n = tail;
do {
s = s + ring[n];
n = (n + 1) % 50;
} while (n !== head);
document.getElementById("r").value = s;
document.getElementById("r").scrollTop =
document.getElementById("r").scrollHeight;
};
ws.onclose = function(){
document.getElementById("r").disabled = 1;
};
} catch(exception) {
alert("<p>Error " + exception);
}
}, false);

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

View file

@ -0,0 +1,19 @@
<html>
<head>
<meta charset=utf-8 http-equiv="Content-Language" content="en"/>
<script src="/example.js"></script>
</head>
<body>
<img src="libwebsockets.org-logo.svg">
<img src="strict-csp.svg"><br>
<b>Minimal ws server threads SMP example</b>.<br>
Strings generated by server threads are sent to
all browsers open on this page.<br>
The textarea show the last 50 lines received.
<br>
<br>
<textarea id=r readonly cols=80 rows=50></textarea><br>
</body>
</html>

View file

@ -0,0 +1,66 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="117.26mm" height="19.676mm" version="1.1" viewBox="0 0 117.26 19.677" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
<metadata>
<rdf:RDF>
<cc:Work rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
<dc:title/>
</cc:Work>
</rdf:RDF>
</metadata>
<path d="m0-2.6715e-4h117.26v19.677h-117.26z" fill="none"/>
<g transform="matrix(.63895 0 0 .63895 2.5477 3.6562)">
<g transform="matrix(.9517 0 0 .9517 3.2398 -93.904)">
<path d="m9.5909 107.4h2.5567v2.649h-2.5567z"/>
<path d="m12.12 107.36a1.2625 1.2625 0 0 1-1.2625 1.262 1.2625 1.2625 0 0 1-1.2625-1.262 1.2625 1.2625 0 0 1 1.2625-1.262 1.2625 1.2625 0 0 1 1.2625 1.262" stroke-linecap="round" stroke-width="1.0365"/>
<path d="m12.127 110.05a1.2625 1.2625 0 0 1-1.2625 1.262 1.2625 1.2625 0 0 1-1.2625-1.262 1.2625 1.2625 0 0 1 1.2625-1.262 1.2625 1.2625 0 0 1 1.2625 1.262" stroke-linecap="round" stroke-width="1.0365"/>
</g>
<path d="m12.174 13.987a1.2015 1.2015 0 0 1-1.2024 1.2024 1.2015 1.2015 0 0 1-1.2006-1.2024 1.2015 1.2015 0 0 1 1.2006-1.2005 1.2015 1.2015 0 0 1 1.2024 1.2005" stroke-linecap="round" stroke-width=".98647"/>
<path d="m8.2754 5.0474h2.468v5.6755h-2.468z"/>
<path d="m16.25 13.965a1.2015 1.2015 0 0 1-1.2027 1.2005 1.2015 1.2015 0 0 1-1.2004-1.2005 1.2015 1.2015 0 0 1 1.2004-1.2025 1.2015 1.2015 0 0 1 1.2027 1.2025" stroke-linecap="round" stroke-width=".98647"/>
<path d="m19.545 13.928a1.2015 1.2015 0 0 1-1.2025 1.2026 1.2015 1.2015 0 0 1-1.2003-1.2026 1.2015 1.2015 0 0 1 1.2003-1.2005 1.2015 1.2015 0 0 1 1.2025 1.2005" stroke-linecap="round" stroke-width=".98647"/>
<path d="m23.75 13.902a1.2015 1.2015 0 0 1-1.2005 1.2024 1.2015 1.2015 0 0 1-1.2025-1.2024 1.2015 1.2015 0 0 1 1.2025-1.2005 1.2015 1.2015 0 0 1 1.2005 1.2005" stroke-linecap="round" stroke-width=".98647"/>
<path d="m26.249 5.0292a1.2015 1.2015 0 0 1-1.2027 1.2004 1.2015 1.2015 0 0 1-1.2004-1.2004 1.2015 1.2015 0 0 1 1.2004-1.2026 1.2015 1.2015 0 0 1 1.2027 1.2026" stroke-linecap="round" stroke-width=".98647"/>
<g transform="matrix(.9517 0 0 .9517 6.3252 -93.961)">
<path d="m9.5909 107.4h2.5567v2.649h-2.5567z"/>
<path d="m12.12 107.36a1.2625 1.2625 0 0 1-1.2625 1.262 1.2625 1.2625 0 0 1-1.2625-1.262 1.2625 1.2625 0 0 1 1.2625-1.262 1.2625 1.2625 0 0 1 1.2625 1.262" stroke-linecap="round" stroke-width="1.0365"/>
<path d="m12.127 110.05a1.2625 1.2625 0 0 1-1.2625 1.262 1.2625 1.2625 0 0 1-1.2625-1.262 1.2625 1.2625 0 0 1 1.2625-1.262 1.2625 1.2625 0 0 1 1.2625 1.262" stroke-linecap="round" stroke-width="1.0365"/>
</g>
<g transform="matrix(.9517 0 0 .9517 9.3806 -93.988)">
<path d="m9.5909 107.4h2.5567v2.649h-2.5567z"/>
<path d="m12.12 107.36a1.2625 1.2625 0 0 1-1.2625 1.262 1.2625 1.2625 0 0 1-1.2625-1.262 1.2625 1.2625 0 0 1 1.2625-1.262 1.2625 1.2625 0 0 1 1.2625 1.262" stroke-linecap="round" stroke-width="1.0365"/>
<path d="m12.127 110.05a1.2625 1.2625 0 0 1-1.2625 1.262 1.2625 1.2625 0 0 1-1.2625-1.262 1.2625 1.2625 0 0 1 1.2625-1.262 1.2625 1.2625 0 0 1 1.2625 1.262" stroke-linecap="round" stroke-width="1.0365"/>
</g>
<g transform="matrix(.9517 0 0 .9517 13.506 -94.006)">
<path d="m9.5909 107.4h2.5567v2.649h-2.5567z"/>
<path d="m12.12 107.36a1.2625 1.2625 0 0 1-1.2625 1.262 1.2625 1.2625 0 0 1-1.2625-1.262 1.2625 1.2625 0 0 1 1.2625-1.262 1.2625 1.2625 0 0 1 1.2625 1.262" stroke-linecap="round" stroke-width="1.0365"/>
<path d="m12.127 110.05a1.2625 1.2625 0 0 1-1.2625 1.262 1.2625 1.2625 0 0 1-1.2625-1.262 1.2625 1.2625 0 0 1 1.2625-1.262 1.2625 1.2625 0 0 1 1.2625 1.262" stroke-linecap="round" stroke-width="1.0365"/>
</g>
<g transform="matrix(.9517 0 0 .9517 -.82062 -93.74)">
<path d="m9.5909 107.4h2.5567v2.649h-2.5567z"/>
<path d="m12.12 107.36a1.2625 1.2625 0 0 1-1.2625 1.262 1.2625 1.2625 0 0 1-1.2625-1.262 1.2625 1.2625 0 0 1 1.2625-1.262 1.2625 1.2625 0 0 1 1.2625 1.262" stroke-linecap="round" stroke-width="1.0365"/>
<path d="m12.127 110.05a1.2625 1.2625 0 0 1-1.2625 1.262 1.2625 1.2625 0 0 1-1.2625-1.262 1.2625 1.2625 0 0 1 1.2625-1.262 1.2625 1.2625 0 0 1 1.2625 1.262" stroke-linecap="round" stroke-width="1.0365"/>
</g>
<path d="m10.703 5.0413a1.2015 1.2015 0 0 1-1.2006 1.2025 1.2015 1.2015 0 0 1-1.2025-1.2025 1.2015 1.2015 0 0 1 1.2025-1.2004 1.2015 1.2015 0 0 1 1.2006 1.2004" stroke-linecap="round" stroke-width=".98647"/>
</g>
<g transform="matrix(2.6825 0 0 2.6825 -289.72 -275.57)" dominant-baseline="auto" stroke-width=".29098" style="font-feature-settings:normal;font-variant-alternates:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;font-variant-position:normal;shape-padding:0;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-orientation:mixed;text-transform:none;white-space:normal" aria-label="libwebsockets.org">
<path d="m117.05 105.01v2.752h0.224v-2.752z"/>
<path d="m117.95 105.71v2.057h0.223v-2.057zm-0.04-0.695v0.318h0.297v-0.318z"/>
<path d="m118.8 105.01v2.752h0.203l0.02-0.251c0.101 0.157 0.244 0.279 0.649 0.279 0.601 0 0.81-0.307 0.81-1.083 0-0.541-0.09-1.03-0.81-1.03-0.468 0-0.594 0.196-0.649 0.283v-0.95zm0.845 0.87c0.552 0 0.618 0.339 0.618 0.855 0 0.486-0.05 0.852-0.611 0.852-0.426 0-0.632-0.181-0.632-0.852 0-0.597 0.15-0.855 0.625-0.855z"/>
<path d="m120.79 105.71 0.555 2.057h0.314l0.479-1.858 0.482 1.858h0.314l0.551-2.057h-0.23l-0.482 1.879-0.482-1.879h-0.303l-0.486 1.879-0.478-1.879z"/>
<path d="m125.54 106.8v-0.157c0-0.433-0.06-0.964-0.869-0.964-0.824 0-0.891 0.566-0.891 1.079 0 0.688 0.196 1.034 0.926 1.034 0.495 0 0.792-0.178 0.831-0.663h-0.224c-0.01 0.377-0.262 0.464-0.628 0.464-0.611 0-0.688-0.314-0.685-0.793zm-1.54-0.195c0.02-0.374 0.08-0.727 0.667-0.727 0.493 0 0.653 0.21 0.65 0.727z"/>
<path d="m126.04 105.01v2.752h0.203l0.02-0.251c0.101 0.157 0.244 0.279 0.649 0.279 0.601 0 0.81-0.307 0.81-1.083 0-0.541-0.09-1.03-0.81-1.03-0.468 0-0.593 0.196-0.649 0.283v-0.95zm0.845 0.87c0.552 0 0.618 0.339 0.618 0.855 0 0.486-0.05 0.852-0.611 0.852-0.426 0-0.632-0.181-0.632-0.852 0-0.597 0.151-0.855 0.625-0.855z"/>
<path d="m129.86 106.28c0-0.24-0.06-0.604-0.799-0.604-0.426 0-0.814 0.109-0.814 0.601 0 0.381 0.241 0.471 0.489 0.503l0.576 0.08c0.273 0.04 0.381 0.08 0.381 0.338 0 0.315-0.224 0.391-0.618 0.391-0.646 0-0.646-0.223-0.646-0.481h-0.224c0 0.279 0.04 0.684 0.852 0.684 0.37 0 0.856-0.05 0.856-0.608 0-0.415-0.294-0.492-0.486-0.516l-0.607-0.08c-0.234-0.03-0.356-0.07-0.356-0.297 0-0.192 0.06-0.408 0.593-0.408 0.583 0 0.58 0.237 0.58 0.401z"/>
<path d="m130.35 106.74c0 0.594 0.06 1.058 0.908 1.058 0.883 0 0.904-0.51 0.904-1.103 0-0.601-0.108-1.01-0.904-1.01-0.852 0-0.908 0.475-0.908 1.055zm0.908-0.852c0.569 0 0.684 0.213 0.684 0.803 0 0.636-0.05 0.904-0.684 0.904-0.584 0-0.688-0.223-0.688-0.824 0-0.6 0.04-0.883 0.688-0.883z"/>
<path d="m134.12 107.03c0 0.471-0.22 0.565-0.656 0.565-0.496 0-0.667-0.181-0.667-0.838 0-0.782 0.272-0.869 0.677-0.869 0.283 0 0.625 0.06 0.625 0.531h0.22c0.01-0.734-0.639-0.734-0.845-0.734-0.632 0-0.897 0.245-0.897 1.058 0 0.793 0.248 1.055 0.908 1.055 0.468 0 0.834-0.115 0.859-0.768z"/>
<path d="m135.05 106.64v-1.624h-0.22v2.752h0.22v-1.072l1.076 1.072h0.321l-1.149-1.1 1.041-0.957h-0.318z"/>
<path d="m138.48 106.8v-0.157c0-0.433-0.06-0.964-0.87-0.964-0.824 0-0.89 0.566-0.89 1.079 0 0.688 0.195 1.034 0.925 1.034 0.496 0 0.793-0.178 0.831-0.663h-0.223c-0.01 0.377-0.262 0.464-0.629 0.464-0.611 0-0.688-0.314-0.684-0.793zm-1.54-0.195c0.02-0.374 0.08-0.727 0.667-0.727 0.492 0 0.653 0.21 0.649 0.727z"/>
<path d="m139.29 105.71h-0.457v0.206h0.457v1.348c0 0.335 0.07 0.531 0.664 0.531 0.09 0 0.139 0 0.181-0.01v-0.209c-0.06 0-0.136 0.01-0.251 0.01-0.374 0-0.374-0.129-0.374-0.381v-1.292h0.541v-0.206h-0.541v-0.488h-0.22z"/>
<path d="m142.15 106.28c0-0.24-0.06-0.604-0.799-0.604-0.426 0-0.814 0.109-0.814 0.601 0 0.381 0.241 0.471 0.489 0.503l0.576 0.08c0.272 0.04 0.381 0.08 0.381 0.338 0 0.315-0.224 0.391-0.618 0.391-0.646 0-0.646-0.223-0.646-0.481h-0.224c0 0.279 0.04 0.684 0.852 0.684 0.37 0 0.856-0.05 0.856-0.608 0-0.415-0.294-0.492-0.486-0.516l-0.607-0.08c-0.234-0.03-0.356-0.07-0.356-0.297 0-0.192 0.06-0.408 0.593-0.408 0.583 0 0.58 0.237 0.58 0.401z"/>
<path d="m142.76 107.44v0.321h0.293v-0.321z"/>
<path d="m143.54 106.74c0 0.594 0.06 1.058 0.908 1.058 0.883 0 0.904-0.51 0.904-1.103 0-0.601-0.108-1.01-0.904-1.01-0.852 0-0.908 0.475-0.908 1.055zm0.908-0.852c0.569 0 0.684 0.213 0.684 0.803 0 0.636-0.05 0.904-0.684 0.904-0.583 0-0.688-0.223-0.688-0.824 0-0.6 0.04-0.883 0.688-0.883z"/>
<path d="m145.81 105.71v2.057h0.22v-1.337c0-0.542 0.419-0.542 0.569-0.542h0.206v-0.213c-0.37 0-0.576 0-0.775 0.259l-0.01-0.231z"/>
<path d="m149.11 105.62c-0.331 0.01-0.391 0.136-0.429 0.217-0.143-0.14-0.44-0.158-0.646-0.158-0.503 0-0.821 0.14-0.821 0.601 0 0.119 0.02 0.272 0.126 0.398-0.175 0.02-0.265 0.157-0.265 0.325 0 0.1 0.04 0.258 0.22 0.311-0.07 0.03-0.245 0.132-0.245 0.408 0 0.412 0.374 0.51 1.006 0.51 0.593 0 0.971-0.09 0.971-0.541 0-0.297-0.175-0.465-0.601-0.489l-0.922-0.06c-0.105 0-0.223-0.05-0.223-0.182 0-0.08 0.04-0.132 0.153-0.195 0.123 0.09 0.322 0.126 0.629 0.126 0.384 0 0.82-0.05 0.82-0.625 0-0.172-0.04-0.227-0.08-0.297 0.06-0.112 0.108-0.133 0.307-0.143zm-1.065 0.258c0.535 0 0.622 0.182 0.622 0.388 0 0.339-0.178 0.426-0.611 0.426-0.423 0-0.622-0.07-0.622-0.384 0-0.356 0.192-0.43 0.611-0.43zm0.206 1.512c0.36 0.02 0.556 0.06 0.556 0.308 0 0.216-0.147 0.331-0.751 0.331-0.674 0-0.8-0.1-0.8-0.345 0-0.304 0.318-0.336 0.328-0.336z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 9.4 KiB

View file

@ -0,0 +1,53 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="24.78mm" height="24.78mm" version="1.1" viewBox="0 0 24.780247 24.780247" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<linearGradient id="linearGradient955" x1="66.618" x2="82.588" y1="81.176" y2="64.828" gradientTransform="matrix(.82538 0 0 .82538 -392 -92.399)" gradientUnits="userSpaceOnUse">
<stop stop-color="#0aa70b" offset="0"/>
<stop stop-color="#3bff39" offset="1"/>
</linearGradient>
<filter id="filter945" x="-.0516" y="-.0516" width="1.1032" height="1.1032" color-interpolation-filters="sRGB">
<feGaussianBlur stdDeviation="0.58510713"/>
</filter>
</defs>
<g transform="translate(342.15 43.638)">
<circle transform="matrix(.82538 0 0 .82538 -392 -92.399)" cx="75.406" cy="74.089" r="13.607" filter="url(#filter945)" stroke="#000" stroke-linecap="round" stroke-width="1.565"/>
<circle cx="-330.23" cy="-31.716" r="11.231" fill="url(#linearGradient955)" stroke="#000" stroke-linecap="round" stroke-width="1.2917"/>
<g transform="matrix(.70929 0 0 .70929 -99.465 -12.686)" stroke-width=".51676px" style="font-feature-settings:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal" aria-label="Strict">
<path d="m-330.78-33.775q0 0.73996-0.53676 1.154-0.53676 0.41407-1.4569 0.41407-0.99684 0-1.5336-0.25688v-0.62878q0.34506 0.14569 0.75147 0.23004 0.4064 0.08435 0.80514 0.08435 0.65177 0 0.9815-0.24538 0.32972-0.24921 0.32972-0.69012 0-0.29138-0.11885-0.47542-0.11502-0.18787-0.39107-0.34506-0.27221-0.15719-0.83198-0.35656-0.78213-0.27988-1.1195-0.66328-0.33356-0.3834-0.33356-1.0007 0-0.64794 0.48692-1.0313 0.48691-0.3834 1.2882-0.3834 0.83581 0 1.5374 0.30672l-0.2032 0.56743q-0.69395-0.29138-1.3496-0.29138-0.51759 0-0.80897 0.22237t-0.29138 0.61727q0 0.29138 0.10735 0.47925 0.10735 0.18403 0.36039 0.34123 0.25688 0.15336 0.78214 0.34122 0.88182 0.31439 1.2115 0.67478 0.33356 0.3604 0.33356 0.93549z"/>
<path d="m-328.37-32.732q0.16869 0 0.32589-0.023 0.15719-0.02684 0.24921-0.05368v0.48692q-0.10352 0.04984-0.30672 0.08051-0.19937 0.03451-0.3604 0.03451-1.2192 0-1.2192-1.2844v-2.4998h-0.60194v-0.30672l0.60194-0.26455 0.26838-0.89716h0.36807v0.97384h1.2192v0.49458h-1.2192v2.4729q0 0.37957 0.18019 0.58277 0.1802 0.2032 0.49459 0.2032z"/>
<path d="m-325.04-36.562q0.27989 0 0.50226 0.04601l-0.0882 0.59044q-0.26072-0.05751-0.46008-0.05751-0.50993 0-0.87415 0.41407-0.3604 0.41407-0.3604 1.0313v2.2544h-0.63644v-4.2021h0.52525l0.0729 0.7783h0.0307q0.23388-0.41024 0.5636-0.63261 0.32972-0.22237 0.72462-0.22237z"/>
<path d="m-323.11-32.284h-0.63644v-4.2021h0.63644zm-0.69012-5.3408q0-0.21854 0.10735-0.31822 0.10735-0.10352 0.26838-0.10352 0.15336 0 0.26455 0.10352 0.11118 0.10352 0.11118 0.31822 0 0.2147-0.11118 0.32206-0.11119 0.10352-0.26455 0.10352-0.16103 0-0.26838-0.10352-0.10735-0.10735-0.10735-0.32206z"/>
<path d="m-320.07-32.207q-0.91249 0-1.4147-0.55976-0.49842-0.5636-0.49842-1.5911 0-1.0543 0.50609-1.6294 0.50992-0.5751 1.4492-0.5751 0.30288 0 0.60577 0.06518 0.30288 0.06518 0.47541 0.15336l-0.19553 0.54059q-0.21087-0.08435-0.46008-0.13802-0.24921-0.05751-0.44091-0.05751-1.2806 0-1.2806 1.6333 0 0.77447 0.31055 1.1885 0.31439 0.41407 0.92783 0.41407 0.52526 0 1.0774-0.22621v0.5636q-0.42174 0.21854-1.062 0.21854z"/>
<path d="m-316.65-32.732q0.16869 0 0.32589-0.023 0.15719-0.02684 0.24921-0.05368v0.48692q-0.10352 0.04984-0.30672 0.08051-0.19937 0.03451-0.3604 0.03451-1.2192 0-1.2192-1.2844v-2.4998h-0.60194v-0.30672l0.60194-0.26455 0.26838-0.89716h0.36806v0.97384h1.2192v0.49458h-1.2192v2.4729q0 0.37957 0.1802 0.58277 0.1802 0.2032 0.49459 0.2032z"/>
</g>
<g fill="#fff">
<g transform="matrix(.70929 0 0 .70929 -99.465 -12.686)" stroke-width=".3317px" style="font-feature-settings:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal" aria-label="Content">
<path d="m-332.67-30.173q-0.5931 0-0.93764 0.39622-0.34208 0.39376-0.34208 1.0804 0 0.70631 0.32977 1.0927 0.33224 0.38392 0.94503 0.38392 0.37653 0 0.85889-0.13536v0.36669q-0.37407 0.14028-0.92288 0.14028-0.7949 0-1.228-0.48236-0.43067-0.48236-0.43067-1.3708 0-0.55619 0.20672-0.97456 0.20919-0.41837 0.60049-0.64478 0.39376-0.22641 0.92533-0.22641 0.56603 0 0.98933 0.20672l-0.1772 0.35931q-0.40852-0.19196-0.81705-0.19196z"/>
<path d="m-328.77-28.248q0 0.65955-0.33224 1.0312-0.33223 0.36915-0.91795 0.36915-0.36177 0-0.64233-0.16981-0.28055-0.16981-0.43313-0.48728-0.15259-0.31747-0.15259-0.74322 0-0.65955 0.32978-1.0262 0.32977-0.36915 0.91549-0.36915 0.56603 0 0.89827 0.37653 0.3347 0.37653 0.3347 1.0189zm-2.0549 0q0 0.51681 0.20672 0.78752 0.20673 0.27071 0.60787 0.27071t0.60787-0.26825q0.20918-0.27071 0.20918-0.78998 0-0.51435-0.20918-0.78014-0.20673-0.26825-0.61279-0.26825-0.40115 0-0.60541 0.26333-0.20426 0.26333-0.20426 0.78506z"/>
<path d="m-326.21-26.897v-1.7449q0-0.32978-0.15012-0.4922-0.15012-0.16243-0.47005-0.16243-0.42329 0-0.62017 0.22887-0.19688 0.22887-0.19688 0.75553v1.4151h-0.40853v-2.6973h0.33223l0.0664 0.36915h0.0197q0.12551-0.19934 0.35192-0.30762 0.22642-0.11075 0.50451-0.11075 0.48728 0 0.73338 0.23626 0.2461 0.2338 0.2461 0.75061v1.7596z"/>
<path d="m-324.09-27.185q0.10828 0 0.20918-0.01477 0.1009-0.01723 0.15997-0.03445v0.31255q-0.0665 0.03199-0.19688 0.05168-0.12797 0.02215-0.23134 0.02215-0.7826 0-0.7826-0.82444v-1.6046h-0.38637v-0.19688l0.38637-0.16981 0.17227-0.57588h0.23626v0.6251h0.7826v0.31747h-0.7826v1.5873q0 0.24364 0.11567 0.37407 0.11566 0.13043 0.31747 0.13043z"/>
<path d="m-322.04-26.848q-0.59802 0-0.94502-0.36423-0.34454-0.36423-0.34454-1.0115 0-0.65217 0.31993-1.0361 0.32239-0.38392 0.86381-0.38392 0.50697 0 0.80229 0.3347 0.29532 0.33224 0.29532 0.87858v0.25841h-1.8581q0.0123 0.47497 0.23872 0.72107 0.22887 0.2461 0.64232 0.2461 0.4356 0 0.86135-0.18212v0.36423q-0.21657 0.09352-0.41099 0.13289-0.19195 0.04184-0.46513 0.04184zm-0.11074-2.4536q-0.32485 0-0.51927 0.21165-0.19196 0.21165-0.22642 0.58572h1.4102q0-0.38638-0.17227-0.59064-0.17227-0.20672-0.4922-0.20672z"/>
<path d="m-318.51-26.897v-1.7449q0-0.32978-0.15012-0.4922-0.15013-0.16243-0.47006-0.16243-0.42329 0-0.62017 0.22887-0.19688 0.22887-0.19688 0.75553v1.4151h-0.40853v-2.6973h0.33224l0.0664 0.36915h0.0197q0.12552-0.19934 0.35193-0.30762 0.22641-0.11075 0.5045-0.11075 0.48728 0 0.73338 0.23626 0.2461 0.2338 0.2461 0.75061v1.7596z"/>
<path d="m-316.4-27.185q0.10829 0 0.20919-0.01477 0.1009-0.01723 0.15996-0.03445v0.31255q-0.0664 0.03199-0.19688 0.05168-0.12797 0.02215-0.23133 0.02215-0.7826 0-0.7826-0.82444v-1.6046h-0.38638v-0.19688l0.38638-0.16981 0.17227-0.57588h0.23625v0.6251h0.7826v0.31747h-0.7826v1.5873q0 0.24364 0.11567 0.37407 0.11567 0.13043 0.31747 0.13043z"/>
</g>
<g transform="matrix(.70929 0 0 .70929 -99.465 -12.686)" stroke-width=".32428px" style="font-feature-settings:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal" aria-label="Security">
<path d="m-332.03-22.859q0 0.46434-0.33683 0.72417-0.33682 0.25984-0.91423 0.25984-0.62553 0-0.96236-0.1612v-0.39456q0.21653 0.09142 0.47155 0.14435 0.25503 0.05293 0.50524 0.05293 0.409 0 0.61591-0.15398 0.20691-0.15638 0.20691-0.43306 0-0.18285-0.0746-0.29833-0.0722-0.11789-0.2454-0.21653-0.17082-0.09864-0.52208-0.22375-0.4908-0.17563-0.70252-0.41622-0.20931-0.24059-0.20931-0.62794 0-0.4066 0.30555-0.64718t0.80838-0.24059q0.52448 0 0.96476 0.19247l-0.12751 0.35607q-0.43547-0.18285-0.84687-0.18285-0.3248 0-0.50765 0.13954-0.18284 0.13954-0.18284 0.38735 0 0.18285 0.0674 0.30074 0.0674 0.11548 0.22615 0.21412 0.1612 0.09624 0.4908 0.21412 0.55336 0.19728 0.76027 0.42344 0.20931 0.22615 0.20931 0.58704z"/>
<path d="m-330.26-21.875q-0.58463 0-0.92386-0.35607-0.33683-0.35607-0.33683-0.98882 0-0.63756 0.31277-1.0129 0.31517-0.37532 0.84446-0.37532 0.49562 0 0.78432 0.3272 0.28871 0.3248 0.28871 0.8589v0.25262h-1.8164q0.012 0.46434 0.23338 0.70492 0.22374 0.24059 0.62793 0.24059 0.42584 0 0.84206-0.17804v0.35607q-0.21171 0.09142-0.40178 0.12992-0.18766 0.0409-0.45471 0.0409zm-0.10827-2.3987q-0.31757 0-0.50764 0.20691-0.18766 0.20691-0.22134 0.5726h1.3786q0-0.37772-0.16841-0.57741-0.16841-0.2021-0.48118-0.2021z"/>
<path d="m-327.56-21.875q-0.5726 0-0.88777-0.35126-0.31277-0.35366-0.31277-0.99844 0-0.66162 0.31758-1.0225 0.31998-0.36088 0.90942-0.36088 0.19007 0 0.38013 0.0409 0.19007 0.0409 0.29833 0.09624l-0.1227 0.33923q-0.13232-0.05293-0.2887-0.08661-0.15639-0.03609-0.27668-0.03609-0.80357 0-0.80357 1.0249 0 0.48599 0.19488 0.74582 0.19728 0.25984 0.58223 0.25984 0.3296 0 0.67605-0.14195v0.35366q-0.26465 0.13714-0.66643 0.13714z"/>
<path d="m-325.89-24.56v1.7106q0 0.32239 0.14676 0.48118 0.14675 0.15879 0.45952 0.15879 0.41381 0 0.60388-0.22615 0.19247-0.22615 0.19247-0.73861v-1.3858h0.39938v2.6369h-0.32961l-0.0577-0.35367h-0.0217q-0.1227 0.19488-0.34163 0.29833-0.21653 0.10345-0.49561 0.10345-0.48118 0-0.72177-0.22856-0.23818-0.22856-0.23818-0.73139v-1.725z"/>
<path d="m-322.04-24.608q0.17563 0 0.31517 0.02887l-0.0553 0.37051q-0.1636-0.03609-0.2887-0.03609-0.31999 0-0.54855 0.25984-0.22615 0.25984-0.22615 0.64718v1.4147h-0.39938v-2.6369h0.32961l0.0457 0.4884h0.0192q0.14676-0.25743 0.35366-0.39697 0.20691-0.13954 0.45472-0.13954z"/>
<path d="m-320.83-21.923h-0.39938v-2.6369h0.39938zm-0.43306-3.3514q0-0.13714 0.0674-0.19969 0.0674-0.06496 0.16841-0.06496 0.0962 0 0.16601 0.06496 0.0698 0.06496 0.0698 0.19969 0 0.13473-0.0698 0.2021-0.0698 0.06496-0.16601 0.06496-0.10105 0-0.16841-0.06496-0.0674-0.06736-0.0674-0.2021z"/>
<path d="m-319.13-22.205q0.10586 0 0.2045-0.01443 0.0986-0.01684 0.15638-0.03368v0.30555q-0.065 0.03128-0.19247 0.05052-0.1251 0.02165-0.22615 0.02165-0.76507 0-0.76507-0.80597v-1.5686h-0.37773v-0.19247l0.37773-0.16601 0.16841-0.56298h0.23096v0.6111h0.76508v0.31036h-0.76508v1.5518q0 0.23818 0.11308 0.3657t0.31036 0.12751z"/>
<path d="m-318.66-24.56h0.42825l0.57742 1.5037q0.19006 0.51486 0.23577 0.74342h0.0192q0.0313-0.1227 0.12992-0.41862 0.10105-0.29833 0.6544-1.8285h0.42825l-1.1332 3.0025q-0.16841 0.44509-0.39456 0.63034-0.22375 0.18766-0.55095 0.18766-0.18285 0-0.36088-0.0409v-0.31998q0.13232 0.02887 0.29592 0.02887 0.41141 0 0.58704-0.46193l0.14676-0.37532z"/>
</g>
<g transform="matrix(.70929 0 0 .70929 -99.465 -12.686)" stroke-width=".32334px" style="font-feature-settings:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal" aria-label="Policy">
<path d="m-329.37-19.254q0 0.53256-0.36464 0.82043-0.36224 0.28547-1.0387 0.28547h-0.41261v1.3794h-0.40782v-3.5072h0.90919q1.3146 0 1.3146 1.0219zm-1.816 0.75566h0.36703q0.54215 0 0.78445-0.17512 0.24229-0.17512 0.24229-0.56135 0-0.34784-0.2279-0.51817t-0.71008-0.17032h-0.45579z"/>
<path d="m-326.43-18.086q0 0.64291-0.32386 1.0051-0.32385 0.35984-0.89479 0.35984-0.35264 0-0.62612-0.16552t-0.42221-0.47498q-0.14873-0.30946-0.14873-0.72447 0-0.64291 0.32145-1.0003 0.32146-0.35984 0.8924-0.35984 0.55175 0 0.8756 0.36703 0.32626 0.36704 0.32626 0.99315zm-2.0031 0q0 0.50377 0.20151 0.76765t0.59253 0.26388q0.39103 0 0.59254-0.26148 0.2039-0.26388 0.2039-0.77005 0-0.50137-0.2039-0.76046-0.20151-0.26148-0.59733-0.26148-0.39103 0-0.59014 0.25668-0.19911 0.25668-0.19911 0.76525z"/>
<path d="m-325.33-16.769h-0.39822v-3.7327h0.39822z"/>
<path d="m-324.09-16.769h-0.39822v-2.6292h0.39822zm-0.43181-3.3417q0-0.13674 0.0672-0.19911 0.0672-0.06477 0.16793-0.06477 0.0959 0 0.16552 0.06477 0.0696 0.06477 0.0696 0.19911t-0.0696 0.20151q-0.0696 0.06477-0.16552 0.06477-0.10076 0-0.16793-0.06477-0.0672-0.06717-0.0672-0.20151z"/>
<path d="m-322.19-16.721q-0.57094 0-0.8852-0.35024-0.31186-0.35264-0.31186-0.99555 0-0.6597 0.31666-1.0195 0.31906-0.35984 0.90679-0.35984 0.18951 0 0.37903 0.04078 0.18951 0.04078 0.29746 0.09596l-0.12234 0.33825q-0.13194-0.05278-0.28787-0.08636-0.15593-0.03598-0.27588-0.03598-0.80123 0-0.80123 1.0219 0 0.48458 0.19431 0.74366 0.19671 0.25908 0.58054 0.25908 0.32865 0 0.67409-0.14154v0.35264q-0.26388 0.13674-0.6645 0.13674z"/>
<path d="m-321.31-19.398h0.427l0.57574 1.4993q0.18952 0.51337 0.2351 0.74127h0.0192q0.0312-0.12234 0.12954-0.41741 0.10076-0.29747 0.65251-1.8232h0.427l-1.1299 2.9938q-0.16792 0.4438-0.39342 0.62852-0.2231 0.18712-0.54935 0.18712-0.18232 0-0.35984-0.04078v-0.31906q0.13194 0.02879 0.29507 0.02879 0.41021 0 0.58533-0.46059l0.14634-0.37423z"/>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 12 KiB

View file

@ -0,0 +1,321 @@
/*
* ws protocol handler plugin for "lws-minimal" demonstrating multithread
*
* Written in 2010-2019 by Andy Green <andy@warmcat.com>
*
* This file is made available under the Creative Commons CC0 1.0
* Universal Public Domain Dedication.
*/
#if !defined (LWS_PLUGIN_STATIC)
#define LWS_DLL
#define LWS_INTERNAL
#include <libwebsockets.h>
#endif
#include <string.h>
#include <assert.h>
/* one of these created for each message in the ringbuffer */
struct msg {
void *payload; /* is malloc'd */
size_t len;
};
/*
* One of these is created for each client connecting to us.
*
* It is ONLY read or written from the lws service thread context.
*/
struct per_session_data__minimal {
struct per_session_data__minimal *pss_list;
struct lws *wsi;
uint32_t tail;
};
/*
* One of these is created for each vhost our protocol is used with, that
* means it is a shared resource between the SMP threads and must be locked.
*/
struct per_vhost_data__minimal {
struct lws_context *context;
struct lws_vhost *vhost;
const struct lws_protocols *protocol;
struct per_session_data__minimal *pss_list; /* linked-list of live pss*/
pthread_t pthread_spam[2];
pthread_mutex_t lock_ring; /* serialize access to the ring buffer */
struct lws_ring *ring; /* {lock_ring} ringbuffer holding unsent content */
const char *config;
char finished;
};
#if defined(WIN32)
static void usleep(unsigned long l) { Sleep(l / 1000); }
#endif
/*
* This runs under both lws service and "spam threads" contexts.
* Access is serialized by vhd->lock_ring.
*/
static void
__minimal_destroy_message(void *_msg)
{
struct msg *msg = _msg;
free(msg->payload);
msg->payload = NULL;
msg->len = 0;
}
/*
* This runs under the "spam thread" thread context only.
*
* We spawn two threads that generate messages with this.
*
*/
static void *
thread_spam(void *d)
{
struct per_vhost_data__minimal *vhd =
(struct per_vhost_data__minimal *)d;
struct msg amsg;
int len = 128, index = 1, n, whoami = 0;
for (n = 0; n < (int)LWS_ARRAY_SIZE(vhd->pthread_spam); n++)
if (pthread_equal(pthread_self(), vhd->pthread_spam[n]))
whoami = n + 1;
do {
pthread_mutex_lock(&vhd->lock_ring); /* --------- ring lock { */
/* don't generate output if nobody connected */
if (!vhd->pss_list)
goto wait_unlock;
/* only create if space in ringbuffer */
n = (int)lws_ring_get_count_free_elements(vhd->ring);
if (!n) {
// lwsl_user("dropping!\n");
goto wait_unlock;
}
amsg.payload = malloc(LWS_PRE + len);
if (!amsg.payload) {
lwsl_user("OOM: dropping\n");
goto wait_unlock;
}
n = lws_snprintf((char *)amsg.payload + LWS_PRE, len,
"%s: spam tid: %d, msg: %d", vhd->config,
whoami, index++);
amsg.len = n;
n = (int)lws_ring_insert(vhd->ring, &amsg, 1);
if (n != 1) {
__minimal_destroy_message(&amsg);
// lwsl_user("dropping!\n");
} else
/*
* This will cause a LWS_CALLBACK_EVENT_WAIT_CANCELLED
* in the lws service thread context.
*/
lws_cancel_service(vhd->context);
wait_unlock:
pthread_mutex_unlock(&vhd->lock_ring); /* } ring lock ------- */
usleep(100000);
} while (!vhd->finished);
lwsl_notice("thread_spam %d exiting\n", whoami);
pthread_exit(NULL);
return NULL;
}
/* this runs under the lws service thread context only */
static int
callback_minimal(struct lws *wsi, enum lws_callback_reasons reason,
void *user, void *in, size_t len)
{
struct per_session_data__minimal *pss =
(struct per_session_data__minimal *)user;
struct per_vhost_data__minimal *vhd =
(struct per_vhost_data__minimal *)
lws_protocol_vh_priv_get(lws_get_vhost(wsi),
lws_get_protocol(wsi));
const struct lws_protocol_vhost_options *pvo;
const struct msg *pmsg;
char temp[LWS_PRE + 256];
void *retval;
int n, m, r = 0;
switch (reason) {
case LWS_CALLBACK_PROTOCOL_INIT:
/* create our per-vhost struct */
vhd = lws_protocol_vh_priv_zalloc(lws_get_vhost(wsi),
lws_get_protocol(wsi),
sizeof(struct per_vhost_data__minimal));
if (!vhd)
return 1;
pthread_mutex_init(&vhd->lock_ring, NULL);
/* recover the pointer to the globals struct */
pvo = lws_pvo_search(
(const struct lws_protocol_vhost_options *)in,
"config");
if (!pvo || !pvo->value) {
lwsl_err("%s: Can't find \"config\" pvo\n", __func__);
return 1;
}
vhd->config = pvo->value;
vhd->context = lws_get_context(wsi);
vhd->protocol = lws_get_protocol(wsi);
vhd->vhost = lws_get_vhost(wsi);
vhd->ring = lws_ring_create(sizeof(struct msg), 8,
__minimal_destroy_message);
if (!vhd->ring) {
lwsl_err("%s: failed to create ring\n", __func__);
return 1;
}
/* start the content-creating threads */
for (n = 0; n < (int)LWS_ARRAY_SIZE(vhd->pthread_spam); n++)
if (pthread_create(&vhd->pthread_spam[n], NULL,
thread_spam, vhd)) {
lwsl_err("thread creation failed\n");
r = 1;
goto init_fail;
}
break;
case LWS_CALLBACK_PROTOCOL_DESTROY:
init_fail:
vhd->finished = 1;
for (n = 0; n < (int)LWS_ARRAY_SIZE(vhd->pthread_spam); n++)
pthread_join(vhd->pthread_spam[n], &retval);
if (vhd->ring)
lws_ring_destroy(vhd->ring);
pthread_mutex_destroy(&vhd->lock_ring);
break;
case LWS_CALLBACK_ESTABLISHED:
/* add ourselves to the list of live pss held in the vhd */
pthread_mutex_lock(&vhd->lock_ring);
lws_ll_fwd_insert(pss, pss_list, vhd->pss_list);
pss->tail = lws_ring_get_oldest_tail(vhd->ring);
pss->wsi = wsi;
pthread_mutex_unlock(&vhd->lock_ring);
break;
case LWS_CALLBACK_CLOSED:
/* doesn't reference ring */
pthread_mutex_lock(&vhd->lock_ring);
/* remove our closing pss from the list of live pss */
lws_ll_fwd_remove(struct per_session_data__minimal, pss_list,
pss, vhd->pss_list);
pthread_mutex_unlock(&vhd->lock_ring);
break;
case LWS_CALLBACK_SERVER_WRITEABLE:
pthread_mutex_lock(&vhd->lock_ring); /* --------- ring lock { */
pmsg = lws_ring_get_element(vhd->ring, &pss->tail);
if (!pmsg) {
pthread_mutex_unlock(&vhd->lock_ring); /* } ring lock ------- */
break;
}
assert(pmsg->payload);
n = lws_snprintf(temp + LWS_PRE, sizeof(temp) - LWS_PRE,
"svc, %s",
(char *)pmsg->payload + LWS_PRE);
/* notice we allowed for LWS_PRE in the payload already */
m = lws_write(wsi, (unsigned char *)temp + LWS_PRE, n,
LWS_WRITE_TEXT);
if (m < n) {
pthread_mutex_unlock(&vhd->lock_ring); /* } ring lock ------- */
lwsl_err("ERROR %d writing to ws socket\n", m);
return -1;
}
lws_ring_consume_and_update_oldest_tail(
vhd->ring, /* lws_ring object */
struct per_session_data__minimal, /* type of objects with tails */
&pss->tail, /* tail of guy doing the consuming */
1, /* number of payload objects being consumed */
vhd->pss_list, /* head of list of objects with tails */
tail, /* member name of tail in objects with tails */
pss_list /* member name of next object in objects with tails */
);
/* more to do? */
if (lws_ring_get_element(vhd->ring, &pss->tail))
/* come back as soon as we can write more */
lws_callback_on_writable(pss->wsi);
pthread_mutex_unlock(&vhd->lock_ring); /* } ring lock ------- */
break;
case LWS_CALLBACK_RECEIVE:
break;
case LWS_CALLBACK_EVENT_WAIT_CANCELLED:
// lwsl_notice("EVENT_WAIT_CANCELLED tsi %d\n", lws_wsi_tsi(wsi));
if (!vhd)
break;
/*
* When the "spam" threads add a message to the ringbuffer,
* they create this event in the lws service thread context
* using lws_cancel_service().
*
* We respond by scheduling a writable callback for all
* connected clients.
*/
pthread_mutex_lock(&vhd->lock_ring); /* --------- ring lock { */
lws_start_foreach_llp(struct per_session_data__minimal **,
ppss, vhd->pss_list) {
if (lws_wsi_tsi((*ppss)->wsi) == lws_wsi_tsi(wsi))
lws_callback_on_writable((*ppss)->wsi);
} lws_end_foreach_llp(ppss, pss_list);
pthread_mutex_unlock(&vhd->lock_ring); /* } ring lock ------- */
break;
default:
break;
}
return r;
}
#define LWS_PLUGIN_PROTOCOL_MINIMAL \
{ \
"lws-minimal", \
callback_minimal, \
sizeof(struct per_session_data__minimal), \
128, \
0, NULL, 0 \
}