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

ws-server-threads-smp: modernize

This commit is contained in:
Andy Green 2021-09-20 05:50:46 +01:00
parent ed8865e2b2
commit 0fda90c40a
5 changed files with 68 additions and 19 deletions

View file

@ -207,6 +207,7 @@ The generic states defined are:
|`LWS_SYSTATE_AUTH2`|Optional second access token for different services|
|`LWS_SYSTATE_OPERATIONAL`|The system is ready for user code to work normally|
|`LWS_SYSTATE_POLICY_INVALID`|All connections are being dropped because policy information is changing. It will transition back to `LWS_SYSTATE_INITIALIZED` and onward to `OPERATIONAL` again afterwards with the new policy|
|`LWS_SYSTATE_CONTEXT_DESTROYING`|Context is going down and smd with it|
### Inserting a notifier

View file

@ -139,6 +139,7 @@ typedef enum { /* keep system_state_names[] in sync in context.c */
* drop everything done with old
* policy, switch to new then enter
* LWS_SYSTATE_POLICY_VALID */
LWS_SYSTATE_CONTEXT_DESTROYING, /* Context is being destroyed */
} lws_system_states_t;
/* Captive Portal Detect -related */

View file

@ -1286,6 +1286,7 @@ void
lws_vhost_destroy1(struct lws_vhost *vh)
{
struct lws_context *context = vh->context;
int n;
lwsl_vhost_info(vh, "\n");
@ -1294,6 +1295,14 @@ lws_vhost_destroy1(struct lws_vhost *vh)
if (vh->being_destroyed)
goto out;
/*
* let's lock all the pts, to enforce pt->vh order... pt is refcounted
* so it's OK if we acquire it later inside this
*/
for (n = 0; n < context->count_threads; n++)
lws_pt_lock((&context->pt[n]), __func__);
lws_vhost_lock(vh); /* -------------- vh { */
#if defined(LWS_WITH_TLS_SESSIONS) && defined(LWS_WITH_TLS)
@ -1390,6 +1399,9 @@ lws_vhost_destroy1(struct lws_vhost *vh)
lws_vhost_unlock(vh); /* } vh -------------- */
for (n = 0; n < context->count_threads; n++)
lws_pt_unlock((&context->pt[n]));
out:
lws_context_unlock(context); /* --------------------------- context { */
}
@ -1525,7 +1537,7 @@ __lws_vhost_destroy2(struct lws_vhost *vh)
#endif
#if LWS_MAX_SMP > 1
lws_mutex_refcount_destroy(&context->mr);
lws_mutex_refcount_destroy(&vh->mr);
#endif
#if defined(LWS_WITH_UNIX_SOCK)

View file

@ -75,7 +75,8 @@ static const char * system_state_names[] = {
"AUTH1",
"AUTH2",
"OPERATIONAL",
"POLICY_INVALID"
"POLICY_INVALID",
"DESTROYING"
};
@ -2084,6 +2085,9 @@ next:
if (context->event_loop_ops->destroy_context2)
context->event_loop_ops->destroy_context2(context);
lws_state_transition_steps(&context->mgr_system,
LWS_SYSTATE_CONTEXT_DESTROYING);
/*
* finalize destroy of pt and things hanging off it
*/

View file

@ -41,7 +41,8 @@ static struct lws_protocols protocols[] = {
};
static struct lws_context *context;
static int interrupted;
static int interrupted, started;
static pthread_t pthread_service[COUNT_THREADS];
static const struct lws_http_mount mount = {
/* .mount_next */ NULL, /* linked-list "next" */
@ -98,18 +99,58 @@ void *thread_service(void *threadid)
return NULL;
}
static int
system_notify_cb(lws_state_manager_t *mgr, lws_state_notify_link_t *link,
int current, int target)
{
struct lws_context *context = mgr->parent;
void *retval;
if (current != target)
return 0;
switch (current) {
case LWS_SYSTATE_OPERATIONAL:
lwsl_notice(" Service threads: %d\n",
lws_get_count_threads(context));
/* start all the service threads */
for (started = 1; started < lws_get_count_threads(context);
started++)
if (pthread_create(&pthread_service[started], NULL,
thread_service,
(void *)(lws_intptr_t)started))
lwsl_err("Failed to start service thread\n");
break;
case LWS_SYSTATE_CONTEXT_DESTROYING:
/* wait for all the service threads to exit */
while ((--started) >= 1)
pthread_join(pthread_service[started], &retval);
break;
}
return 0;
}
lws_state_notify_link_t notifier = { { NULL, NULL, NULL },
system_notify_cb, "app" };
lws_state_notify_link_t *na[] = { &notifier, NULL };
void sigint_handler(int sig)
{
interrupted = 1;
lws_cancel_service(context);
}
int main(int argc, const char **argv)
{
int n, logs = LLL_USER | LLL_ERR | LLL_WARN | LLL_NOTICE;
pthread_t pthread_service[COUNT_THREADS];
int logs = LLL_USER | LLL_ERR | LLL_WARN | LLL_NOTICE;
struct lws_context_creation_info info;
const char *p;
void *retval;
int n = 0;
signal(SIGINT, sigint_handler);
@ -125,6 +166,7 @@ int main(int argc, const char **argv)
info.protocols = protocols;
info.pvo = &pvo; /* per-vhost options */
info.count_threads = COUNT_THREADS;
info.register_notifier_list = na;
info.options =
LWS_SERVER_OPTION_HTTP_HEADERS_SECURITY_BEST_PRACTICES_ENFORCE;
@ -134,19 +176,8 @@ int main(int argc, const char **argv)
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);
while (n >= 0 && !interrupted)
n = lws_service(context, 0);
lws_context_destroy(context);