mirror of
https://github.com/warmcat/libwebsockets.git
synced 2025-03-09 00:00:04 +01:00
smp: minimal client with several active connections
This commit is contained in:
parent
2bcae2b3b6
commit
a03181301d
12 changed files with 367 additions and 20 deletions
|
@ -0,0 +1,25 @@
|
|||
project(lws-minimal-ws-client-spam-tx-rx 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-client-spam-tx-rx)
|
||||
set(SRCS minimal-ws-client.c)
|
||||
|
||||
set(requirements 1)
|
||||
require_lws_config(LWS_ROLE_WS 1 requirements)
|
||||
require_lws_config(LWS_WITH_CLIENT 1 requirements)
|
||||
|
||||
if (requirements)
|
||||
add_executable(${SAMP} ${SRCS})
|
||||
|
||||
if (websockets_shared)
|
||||
target_link_libraries(${SAMP} websockets_shared ${LIBWEBSOCKETS_DEP_LIBS})
|
||||
add_dependencies(${SAMP} websockets_shared)
|
||||
else()
|
||||
target_link_libraries(${SAMP} websockets ${LIBWEBSOCKETS_DEP_LIBS})
|
||||
endif()
|
||||
endif()
|
|
@ -0,0 +1,79 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIFWjCCBEKgAwIBAgISA9x0/oj5PLdW46hsmR82/7ytMA0GCSqGSIb3DQEBCwUA
|
||||
MEoxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MSMwIQYDVQQD
|
||||
ExpMZXQncyBFbmNyeXB0IEF1dGhvcml0eSBYMzAeFw0xOTA5MDcwNzA5NDBaFw0x
|
||||
OTEyMDYwNzA5NDBaMBwxGjAYBgNVBAMTEWxpYndlYnNvY2tldHMub3JnMIIBIjAN
|
||||
BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxPinIkleLmvEcA/YuBss6ASXVi7g
|
||||
yr6Sss7cB3vTy7Fp8OB2c1N25prHZxVpORAUo0UreiaY2Ws4NFvDaYp08ZffevuC
|
||||
UhThsEJlbkD0uvt7dPapJt9PNJtlxjNFWyvHEy6PijzIaMYDROiStcCJQn7kAew/
|
||||
Za2+5kNVgKqT+7OXukJEFdSdVZI6QC/npeQlkIrFSq1WVthCGBNJehxxES0hSWzk
|
||||
0gNVKlkD3/SbkupsfUpe73XiawMtrtsSE7cdnul7VZmiP8I/3sJr1+4/3xZ+DEYg
|
||||
mVB82B0vd08VJYzU7Nf0pz0PWusAmzRoRn81IXkOfBg9ohlSSEoZhHYS7QIDAQAB
|
||||
o4ICZjCCAmIwDgYDVR0PAQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggr
|
||||
BgEFBQcDAjAMBgNVHRMBAf8EAjAAMB0GA1UdDgQWBBRmKKyGjufWgp7pR2x0tWxG
|
||||
D9G+WTAfBgNVHSMEGDAWgBSoSmpjBH3duubRObemRWXv86jsoTBvBggrBgEFBQcB
|
||||
AQRjMGEwLgYIKwYBBQUHMAGGImh0dHA6Ly9vY3NwLmludC14My5sZXRzZW5jcnlw
|
||||
dC5vcmcwLwYIKwYBBQUHMAKGI2h0dHA6Ly9jZXJ0LmludC14My5sZXRzZW5jcnlw
|
||||
dC5vcmcvMBwGA1UdEQQVMBOCEWxpYndlYnNvY2tldHMub3JnMEwGA1UdIARFMEMw
|
||||
CAYGZ4EMAQIBMDcGCysGAQQBgt8TAQEBMCgwJgYIKwYBBQUHAgEWGmh0dHA6Ly9j
|
||||
cHMubGV0c2VuY3J5cHQub3JnMIIBBAYKKwYBBAHWeQIEAgSB9QSB8gDwAHcAdH7a
|
||||
gzGtMxCRIZzOJU9CcMK//V5CIAjGNzV55hB7zFYAAAFtCsWIfgAABAMASDBGAiEA
|
||||
0H55VqSKV3otHK7uHNbcR0QwoUYtCmeObhsqxzCnmDwCIQD3mtuSKrxTD3oA+Yde
|
||||
nmTgWfFyS4TNgLNEPCJYo2s75gB1ACk8UZZUyDlluqpQ/FgH1Ldvv1h6KXLcpMMM
|
||||
9OVFR/R4AAABbQrFil4AAAQDAEYwRAIgNSpvz/1JA2aP6fh6ujGNuYfrAvWjlxXo
|
||||
CJtVGe4XaDYCIGmK1/9tl1uQbVD46P5NswnULq06KQmuOrlI3HO4r86HMA0GCSqG
|
||||
SIb3DQEBCwUAA4IBAQBiAlV7wkCsWE99VmZHBmcbZChWyWUHG3LM1hnaQRQjTSYk
|
||||
CIlauCpWzlUd6weuvra85KqBbCYo+1hxbwITI796uAdgtHmBE8nj0VltHwKeSq2s
|
||||
KKiGXBRT7Z7t0VHYSLOlGOVn1auuQFaWBArc0cQ/m1ZsoHvOiHTlKQvVsA4HnIxA
|
||||
CjGY9OOQoh0c36ecbJZ44XKnU9J/OXtDx00aW6QodaZmgMp/OOCghFQUvufkgTUL
|
||||
LZid873/8dJVWjAaj1VdadO1nSbdAfBbeWXy93+vg1aAoig80RoscrzYCaNlwmR7
|
||||
EO5zWxL3l+xUZogQSJuICgUgNzVB3wjn8HeHGsqt
|
||||
-----END CERTIFICATE-----
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIEkjCCA3qgAwIBAgIQCgFBQgAAAVOFc2oLheynCDANBgkqhkiG9w0BAQsFADA/
|
||||
MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT
|
||||
DkRTVCBSb290IENBIFgzMB4XDTE2MDMxNzE2NDA0NloXDTIxMDMxNzE2NDA0Nlow
|
||||
SjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUxldCdzIEVuY3J5cHQxIzAhBgNVBAMT
|
||||
GkxldCdzIEVuY3J5cHQgQXV0aG9yaXR5IFgzMIIBIjANBgkqhkiG9w0BAQEFAAOC
|
||||
AQ8AMIIBCgKCAQEAnNMM8FrlLke3cl03g7NoYzDq1zUmGSXhvb418XCSL7e4S0EF
|
||||
q6meNQhY7LEqxGiHC6PjdeTm86dicbp5gWAf15Gan/PQeGdxyGkOlZHP/uaZ6WA8
|
||||
SMx+yk13EiSdRxta67nsHjcAHJyse6cF6s5K671B5TaYucv9bTyWaN8jKkKQDIZ0
|
||||
Z8h/pZq4UmEUEz9l6YKHy9v6Dlb2honzhT+Xhq+w3Brvaw2VFn3EK6BlspkENnWA
|
||||
a6xK8xuQSXgvopZPKiAlKQTGdMDQMc2PMTiVFrqoM7hD8bEfwzB/onkxEz0tNvjj
|
||||
/PIzark5McWvxI0NHWQWM6r6hCm21AvA2H3DkwIDAQABo4IBfTCCAXkwEgYDVR0T
|
||||
AQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAYYwfwYIKwYBBQUHAQEEczBxMDIG
|
||||
CCsGAQUFBzABhiZodHRwOi8vaXNyZy50cnVzdGlkLm9jc3AuaWRlbnRydXN0LmNv
|
||||
bTA7BggrBgEFBQcwAoYvaHR0cDovL2FwcHMuaWRlbnRydXN0LmNvbS9yb290cy9k
|
||||
c3Ryb290Y2F4My5wN2MwHwYDVR0jBBgwFoAUxKexpHsscfrb4UuQdf/EFWCFiRAw
|
||||
VAYDVR0gBE0wSzAIBgZngQwBAgEwPwYLKwYBBAGC3xMBAQEwMDAuBggrBgEFBQcC
|
||||
ARYiaHR0cDovL2Nwcy5yb290LXgxLmxldHNlbmNyeXB0Lm9yZzA8BgNVHR8ENTAz
|
||||
MDGgL6AthitodHRwOi8vY3JsLmlkZW50cnVzdC5jb20vRFNUUk9PVENBWDNDUkwu
|
||||
Y3JsMB0GA1UdDgQWBBSoSmpjBH3duubRObemRWXv86jsoTANBgkqhkiG9w0BAQsF
|
||||
AAOCAQEA3TPXEfNjWDjdGBX7CVW+dla5cEilaUcne8IkCJLxWh9KEik3JHRRHGJo
|
||||
uM2VcGfl96S8TihRzZvoroed6ti6WqEBmtzw3Wodatg+VyOeph4EYpr/1wXKtx8/
|
||||
wApIvJSwtmVi4MFU5aMqrSDE6ea73Mj2tcMyo5jMd6jmeWUHK8so/joWUoHOUgwu
|
||||
X4Po1QYz+3dszkDqMp4fklxBwXRsW10KXzPMTZ+sOPAveyxindmjkW8lGy+QsRlG
|
||||
PfZ+G6Z6h7mjem0Y+iWlkYcV4PIWL1iwBi8saCbGS5jN2p8M+X+Q7UNKEkROb3N6
|
||||
KOqkqm57TH2H3eDJAkSnh6/DNFu0Qg==
|
||||
-----END CERTIFICATE-----
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDSjCCAjKgAwIBAgIQRK+wgNajJ7qJMDmGLvhAazANBgkqhkiG9w0BAQUFADA/
|
||||
MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT
|
||||
DkRTVCBSb290IENBIFgzMB4XDTAwMDkzMDIxMTIxOVoXDTIxMDkzMDE0MDExNVow
|
||||
PzEkMCIGA1UEChMbRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QgQ28uMRcwFQYDVQQD
|
||||
Ew5EU1QgUm9vdCBDQSBYMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
|
||||
AN+v6ZdQCINXtMxiZfaQguzH0yxrMMpb7NnDfcdAwRgUi+DoM3ZJKuM/IUmTrE4O
|
||||
rz5Iy2Xu/NMhD2XSKtkyj4zl93ewEnu1lcCJo6m67XMuegwGMoOifooUMM0RoOEq
|
||||
OLl5CjH9UL2AZd+3UWODyOKIYepLYYHsUmu5ouJLGiifSKOeDNoJjj4XLh7dIN9b
|
||||
xiqKqy69cK3FCxolkHRyxXtqqzTWMIn/5WgTe1QLyNau7Fqckh49ZLOMxt+/yUFw
|
||||
7BZy1SbsOFU5Q9D8/RhcQPGX69Wam40dutolucbY38EVAjqr2m7xPi71XAicPNaD
|
||||
aeQQmxkqtilX4+U9m5/wAl0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNV
|
||||
HQ8BAf8EBAMCAQYwHQYDVR0OBBYEFMSnsaR7LHH62+FLkHX/xBVghYkQMA0GCSqG
|
||||
SIb3DQEBBQUAA4IBAQCjGiybFwBcqR7uKGY3Or+Dxz9LwwmglSBd49lZRNI+DT69
|
||||
ikugdB/OEIKcdBodfpga3csTS7MgROSR6cz8faXbauX+5v3gTt23ADq1cEmv8uXr
|
||||
AvHRAosZy5Q6XkjEGB5YGV8eAlrwDPGxrancWYaLbumR9YbK+rlmM6pZW87ipxZz
|
||||
R8srzJmwN0jP41ZL9c8PDHIyh8bwRLtTcm1D9SZImlJnt1ir/md2cXjbDaJWFBM5
|
||||
JDGFoqgCWjBH4d1QB7wCCZAA62RjYJsWvIjJEubSfZGL+T0yjWW06XyxV3bqxbYo
|
||||
Ob8VZRzI9neWagqNdwvYkQsEjgfbKbYK7p2CNTUQ
|
||||
-----END CERTIFICATE-----
|
||||
|
|
@ -0,0 +1,221 @@
|
|||
#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
|
||||
|
||||
static int nclients = 11;
|
||||
unsigned char msg[LWS_PRE+128];
|
||||
static int message_delay = 500000; // microseconds
|
||||
static int connection_delay = 100000; // microseconds
|
||||
static struct lws_context *context;
|
||||
static const char *server_address = "localhost", *pro = "lws-minimal";
|
||||
static int interrupted = 0, port = 7681, ssl_connection = 0;
|
||||
|
||||
static int connect_client()
|
||||
{
|
||||
struct lws_client_connect_info i;
|
||||
|
||||
memset(&i, 0, sizeof(i));
|
||||
|
||||
i.context = context;
|
||||
i.port = port;
|
||||
i.address = server_address;
|
||||
i.path = "/";
|
||||
i.host = i.address;
|
||||
i.origin = i.address;
|
||||
i.ssl_connection = ssl_connection;
|
||||
i.protocol = pro;
|
||||
i.local_protocol_name = pro;
|
||||
|
||||
//usleep(connection_delay);
|
||||
lwsl_notice("%s: connection %s:%d\n", __func__, i.address, i.port);
|
||||
if (!lws_client_connect_via_info(&i)) return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
callback(struct lws *wsi, enum lws_callback_reasons reason,
|
||||
void *user, void *in, size_t len)
|
||||
{
|
||||
int m= 0, n = 0;
|
||||
short r;
|
||||
#if defined(_DEBUG)
|
||||
size_t remain;
|
||||
int first = 0, final = 0;
|
||||
#endif
|
||||
|
||||
//lwsl_notice("callback called with reason %d\n", reason);
|
||||
switch (reason) {
|
||||
|
||||
case LWS_CALLBACK_PROTOCOL_INIT:
|
||||
for (n = 0; n < nclients; n++)
|
||||
connect_client();
|
||||
break;
|
||||
|
||||
case LWS_CALLBACK_CLIENT_CONNECTION_ERROR:
|
||||
lwsl_err("CLIENT_CONNECTION_ERROR: %s\n", in ? (char *)in :
|
||||
"(null)");
|
||||
if(--nclients == 0) interrupted = 1;
|
||||
break;
|
||||
|
||||
/* --- client callbacks --- */
|
||||
|
||||
case LWS_CALLBACK_CLIENT_ESTABLISHED:
|
||||
lws_callback_on_writable(wsi);
|
||||
lwsl_user("%s: established connection, wsi = %p\n",
|
||||
__func__, wsi);
|
||||
break;
|
||||
|
||||
case LWS_CALLBACK_CLIENT_CLOSED:
|
||||
lwsl_user("%s: CLOSED\n", __func__);
|
||||
if(--nclients == 0) interrupted = 1;
|
||||
break;
|
||||
|
||||
case LWS_CALLBACK_CLIENT_WRITEABLE:
|
||||
|
||||
m = lws_write(wsi, msg + LWS_PRE, 128, LWS_WRITE_TEXT);
|
||||
if (m < 128) {
|
||||
lwsl_err("sending message failed: %d < %d\n", m, n);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Schedule the timer after minimum message delay plus the
|
||||
* random number of centiseconds.
|
||||
*/
|
||||
if (lws_get_random(lws_get_context(wsi), &r, 2) == 2) {
|
||||
n = message_delay + 10000*(r % 100);
|
||||
lwsl_debug("set timer on %d usecs\n", n);
|
||||
lws_set_timer_usecs(wsi, n);
|
||||
}
|
||||
break;
|
||||
|
||||
case LWS_CALLBACK_TIMER:
|
||||
// Let the main loop know we want to send another message to the
|
||||
// server
|
||||
lws_callback_on_writable(wsi);
|
||||
break;
|
||||
|
||||
case LWS_CALLBACK_CLIENT_RECEIVE:
|
||||
#if defined(_DEBUG)
|
||||
first = lws_is_first_fragment(wsi);
|
||||
final = lws_is_final_fragment(wsi);
|
||||
remain = lws_remaining_packet_payload(wsi);
|
||||
lwsl_debug("LWS_CALLBACK_RECEIVE: len = %lu, first = %d, "
|
||||
"final = %d, remains = %lu\n",
|
||||
(unsigned long)len, first, final,
|
||||
(unsigned long)remain);
|
||||
#endif
|
||||
break;
|
||||
|
||||
case LWS_CALLBACK_WS_PEER_INITIATED_CLOSE:
|
||||
lwsl_notice("server initiated connection close: len = %lu, "
|
||||
"in = %s\n", (unsigned long)len, (char*)in);
|
||||
return 0;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return lws_callback_http_dummy(wsi, reason, user, in, len);
|
||||
}
|
||||
|
||||
static const struct lws_protocols protocols[] = {
|
||||
{ "spam-rx-tx", callback, 4096, 4096, 0, NULL, 0 },
|
||||
{ NULL, NULL, 0, 0 }
|
||||
};
|
||||
|
||||
static void
|
||||
sigint_handler(int sig)
|
||||
{
|
||||
interrupted = 1;
|
||||
}
|
||||
|
||||
int main(int argc, const char **argv)
|
||||
{
|
||||
struct lws_context_creation_info info;
|
||||
const char *p;
|
||||
int n = 0, logs =
|
||||
LLL_USER | LLL_ERR | LLL_WARN | LLL_NOTICE;
|
||||
#ifndef WIN32
|
||||
srandom(time(0));
|
||||
#endif
|
||||
|
||||
memset(msg, 'x', sizeof(msg));
|
||||
|
||||
signal(SIGINT, sigint_handler);
|
||||
|
||||
if (lws_cmdline_option(argc, argv, "-d"))
|
||||
logs |= LLL_INFO | LLL_DEBUG;
|
||||
|
||||
lws_set_log_level(logs, NULL);
|
||||
|
||||
memset(&info, 0, sizeof info); /* otherwise uninitialized garbage */
|
||||
info.options = LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT;
|
||||
info.port = CONTEXT_PORT_NO_LISTEN; /* we do not run any server */
|
||||
info.protocols = protocols;
|
||||
#if defined(LWS_WITH_MBEDTLS) || defined(USE_WOLFSSL)
|
||||
/*
|
||||
* OpenSSL uses the system trust store. mbedTLS has to be told which
|
||||
* CA to trust explicitly.
|
||||
*/
|
||||
info.client_ssl_ca_filepath = "./libwebsockets.org.cer";
|
||||
#endif
|
||||
|
||||
if ((p = lws_cmdline_option(argc, argv, "-h"))) {
|
||||
server_address = p;
|
||||
}
|
||||
|
||||
if ((p = lws_cmdline_option(argc, argv, "-s"))) {
|
||||
ssl_connection |=
|
||||
LCCSCF_USE_SSL |
|
||||
LCCSCF_ALLOW_SELFSIGNED |
|
||||
LCCSCF_SKIP_SERVER_CERT_HOSTNAME_CHECK;
|
||||
}
|
||||
|
||||
if ((p = lws_cmdline_option(argc, argv, "-p")))
|
||||
port = atoi(p);
|
||||
|
||||
if ((p = lws_cmdline_option(argc, argv, "-n"))) {
|
||||
n = atoi(p);
|
||||
if (n < 1)
|
||||
n = 1;
|
||||
if (n < nclients)
|
||||
nclients = n;
|
||||
lwsl_notice("Start test clients: %d\n", nclients);
|
||||
}
|
||||
|
||||
if ((p = lws_cmdline_option(argc, argv, "-c"))) {
|
||||
connection_delay = atoi(p);
|
||||
lwsl_notice("Connection delay: %d\n", connection_delay);
|
||||
}
|
||||
|
||||
if ((p = lws_cmdline_option(argc, argv, "-m"))) {
|
||||
message_delay = atoi(p);
|
||||
lwsl_notice("Message delay: %d\n", connection_delay);
|
||||
}
|
||||
|
||||
info.fd_limit_per_thread = 1 + nclients + 1;
|
||||
|
||||
context = lws_create_context(&info);
|
||||
if (!context) {
|
||||
lwsl_err("lws init failed\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
while (n >= 0 && !interrupted)
|
||||
n = lws_service(context, 0);
|
||||
|
||||
lwsl_notice("%s: exiting service loop. n = %d, interrupted = %d\n",
|
||||
__func__, n, interrupted);
|
||||
|
||||
lws_context_destroy(context);
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
project(lws-minimal-ws-server-threads-foreign-smp C)
|
||||
project(lws-minimal-ws-server-threads-foreign-libuv-smp C)
|
||||
cmake_minimum_required(VERSION 2.8)
|
||||
find_package(libwebsockets CONFIG REQUIRED)
|
||||
list(APPEND CMAKE_MODULE_PATH ${LWS_CMAKE_DIR})
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* lws-minimal-ws-server
|
||||
* lws-minimal-ws-server-threads-foreign-smp
|
||||
*
|
||||
* Written in 2010-2020 by Andy Green <andy@warmcat.com>
|
||||
*
|
||||
|
@ -44,6 +44,7 @@ static struct lws_protocols protocols[] = {
|
|||
static struct lws_context *context;
|
||||
static int interrupted;
|
||||
static uv_loop_t loop[COUNT_THREADS];
|
||||
static uv_signal_t *s, signal_outer[COUNT_THREADS];
|
||||
|
||||
static const struct lws_http_mount mount = {
|
||||
/* .mount_next */ NULL, /* linked-list "next" */
|
||||
|
@ -90,38 +91,54 @@ static const struct lws_protocol_vhost_options pvo = {
|
|||
|
||||
void *thread_service(void *threadid)
|
||||
{
|
||||
/*
|
||||
* This is a foreign thread context for each event loop... lws doesn't
|
||||
* know about it, except that it's getting called into from the event
|
||||
* lib bound to each of these.
|
||||
*
|
||||
* When closing, at the point we have detached everything related to
|
||||
* lws from the loop and destroyed the context we can as the "foreign
|
||||
* app" take care of stopping the foreign loop and cloing this thread.
|
||||
*
|
||||
* The call to lws_service_tsi just starts the related event loop
|
||||
*/
|
||||
while (lws_service_tsi(context, 0,
|
||||
(int)(lws_intptr_t)threadid) >= 0 &&
|
||||
!interrupted)
|
||||
lwsl_notice("%s\n", __func__);
|
||||
|
||||
lwsl_info("%s: thr %d: exiting\n", __func__, (int)(lws_intptr_t)threadid);
|
||||
|
||||
pthread_exit(NULL);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void signal_cb(uv_signal_t *watcher, int signum)
|
||||
static void
|
||||
signal_cb(uv_signal_t *watcher, int signum)
|
||||
{
|
||||
int n;
|
||||
|
||||
if (interrupted)
|
||||
return;
|
||||
n = (int)(watcher - signal_outer);
|
||||
|
||||
lwsl_notice("%s: thr %d: signal %d caught\n", __func__, n,
|
||||
watcher->signum);
|
||||
|
||||
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]);
|
||||
uv_close((uv_handle_t *)&signal_outer[n], NULL);
|
||||
if (!interrupted) {
|
||||
interrupted = 1;
|
||||
lws_context_destroy(context);
|
||||
}
|
||||
}
|
||||
|
||||
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];
|
||||
int actual_threads;
|
||||
const char *p;
|
||||
void *retval;
|
||||
|
||||
|
@ -132,15 +149,11 @@ int main(int argc, const char **argv)
|
|||
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);
|
||||
}
|
||||
s = &signal_outer[n];
|
||||
uv_signal_init(&loop[n], s);
|
||||
uv_signal_start(s, signal_cb, SIGINT);
|
||||
|
||||
foreign_loops[n] = &loop[n];
|
||||
}
|
||||
|
@ -162,11 +175,12 @@ int main(int argc, const char **argv)
|
|||
return 1;
|
||||
}
|
||||
|
||||
lwsl_notice(" Service threads: %d\n", lws_get_count_threads(context));
|
||||
actual_threads = lws_get_count_threads(context);
|
||||
lwsl_notice(" Service threads: %d\n", actual_threads);
|
||||
|
||||
/* start all the service threads */
|
||||
|
||||
for (n = 0; n < lws_get_count_threads(context); n++)
|
||||
for (n = 0; n < actual_threads; n++)
|
||||
if (pthread_create(&pthread_service[n], NULL, thread_service,
|
||||
(void *)(lws_intptr_t)n))
|
||||
lwsl_err("Failed to start service thread\n");
|
||||
|
@ -178,5 +192,13 @@ int main(int argc, const char **argv)
|
|||
|
||||
lws_context_destroy(context);
|
||||
|
||||
for (n = 0; n < COUNT_THREADS; n++) {
|
||||
int m;
|
||||
|
||||
m = uv_loop_close(&loop[n]);
|
||||
if (m)
|
||||
lwsl_notice("%s: uv_close_loop %d: %d\n", __func__, n, m);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 9.4 KiB After Width: | Height: | Size: 9.4 KiB |
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
Loading…
Add table
Reference in a new issue