1
0
Fork 0
mirror of https://git.rwth-aachen.de/acs/public/villas/node/ synced 2025-03-09 00:00:00 +01:00

web: fix lws_callback_on_writable() on macOS caused by multithreading issues

This commit is contained in:
Steffen Vogel 2018-11-23 20:57:34 +02:00
parent 84aff14eed
commit 88b1ec7850
4 changed files with 35 additions and 5 deletions

View file

@ -26,6 +26,7 @@
#include <pthread.h>
#include <villas/common.h>
#include <villas/queue.h>
#ifdef __cplusplus
extern "C" {
@ -42,6 +43,8 @@ struct web {
struct lws_context *context; /**< The libwebsockets server context. */
struct lws_vhost *vhost; /**< The libwebsockets vhost. */
struct queue writables; /**< Queue of WSIs for which we will call lws_callback_on_writable() */
int port; /**< Port of the build in HTTP / WebSocket server. */
char *htdocs; /**< The root directory for files served via HTTP. */
char *ssl_cert; /**< Path to the SSL certitifcate for HTTPS / WSS. */
@ -65,6 +68,8 @@ int web_stop(struct web *w);
/** Parse HTTPd and WebSocket related options */
int web_parse(struct web *w, json_t *cfg);
void web_callback_on_writable(struct lws *wsi);
#ifdef __cplusplus
}
#endif

View file

@ -326,7 +326,7 @@ int api_stop(struct api *a)
s->state = API_SESSION_STATE_SHUTDOWN;
lws_callback_on_writable(s->wsi);
web_callback_on_writable(s->wsi);
}
for (int i = 0; i < 10 && list_length(&a->sessions) > 0; i++) {
@ -373,7 +373,7 @@ static void * api_worker(void *ctx)
queue_push(&s->response.queue, resp);
lws_callback_on_writable(s->wsi);
web_callback_on_writable(s->wsi);
}
return NULL;

View file

@ -164,7 +164,7 @@ static int websocket_connection_write(struct websocket_connection *c, struct sam
/* Client connections which are currently conecting don't have an associate c->wsi yet */
if (c->wsi)
lws_callback_on_writable(c->wsi);
web_callback_on_writable(c->wsi);
return 0;
}

View file

@ -165,19 +165,34 @@ static void logger(int level, const char *msg) {
}
}
void web_callback_on_writable(struct lws *wsi)
{
struct lws_context *ctx = lws_get_context(wsi);
struct web *w = lws_context_user(ctx);
queue_push(&w->writables, (void *) wsi);
}
static void * web_worker(void *ctx)
{
struct lws *wsi;
struct web *w = ctx;
for (;;)
for (;;) {
lws_service(w->context, 100);
while (queue_available(&w->writables)) {
queue_pull(&w->writables, (void **) &wsi);
lws_callback_on_writable(wsi);
}
}
return NULL;
}
int web_init(struct web *w, struct api *a)
{
int lvl = LLL_ERR | LLL_WARN | LLL_NOTICE;
int ret, lvl = LLL_ERR | LLL_WARN | LLL_NOTICE;
if (global_log->level >=10 && global_log->facilities & LOG_WEB)
lvl |= (1 << LLL_COUNT) - 1;
@ -190,6 +205,10 @@ int web_init(struct web *w, struct api *a)
w->port = getuid() > 0 ? 8080 : 80; /**< @todo Use libcap to check if user can bind to ports < 1024 */
w->htdocs = strdup(WEB_PATH);
ret = queue_init(&w->writables, 128, &memory_heap);
if (ret)
return ret;
w->state = STATE_INITIALIZED;
return 0;
@ -312,6 +331,8 @@ int web_stop(struct web *w)
int web_destroy(struct web *w)
{
int ret;
if (w->state == STATE_DESTROYED)
return 0;
@ -328,6 +349,10 @@ int web_destroy(struct web *w)
if (w->htdocs)
free(w->htdocs);
ret = queue_destroy(&w->writables);
if (ret)
return ret;
w->state = STATE_DESTROYED;
return 0;