Skip to content

Commit fb0ca16

Browse files
decsnycfriedt
authored andcommitted
samples: net: sockets: http_server: Dont block system workq
Since the netstats handler calls on functions which reach deep into the networking stack, there is a lot of points actually at which it can be blocked, even forever. So having this handler on the system workqueue is not a good idea and can even cause a deadlock in some cases if it's blocked waiting on a synchronization primitive that would be given by a work item scheduled later in the queue. Therefore, make a workqueue specifically for this http server socket instead of using the system one. Signed-off-by: Declan Snyder <[email protected]>
1 parent 1187e17 commit fb0ca16

File tree

1 file changed

+12
-2
lines changed
  • samples/net/sockets/http_server/src

1 file changed

+12
-2
lines changed

samples/net/sockets/http_server/src/ws.c

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,10 @@ static int netstats_collect(char *buf, size_t maxlen)
251251
return ret;
252252
}
253253

254+
#define WS_NETSTATS_STACK_SIZE 2048
255+
K_THREAD_STACK_DEFINE(ws_netstats_stack, WS_NETSTATS_STACK_SIZE);
256+
struct k_work_q ws_netstats_queue;
257+
254258
static void netstats_handler(struct k_work *work)
255259
{
256260
int ret;
@@ -271,7 +275,8 @@ static void netstats_handler(struct k_work *work)
271275
goto unregister;
272276
}
273277

274-
ret = k_work_reschedule(&ctx->work, K_MSEC(CONFIG_NET_SAMPLE_WEBSOCKET_STATS_INTERVAL));
278+
ret = k_work_reschedule_for_queue(&ws_netstats_queue, &ctx->work,
279+
K_MSEC(CONFIG_NET_SAMPLE_WEBSOCKET_STATS_INTERVAL));
275280
if (ret < 0) {
276281
LOG_ERR("Failed to schedule netstats work, err %d", ret);
277282
goto unregister;
@@ -286,6 +291,11 @@ static void netstats_handler(struct k_work *work)
286291

287292
int ws_netstats_init(void)
288293
{
294+
struct k_work_queue_config cfg = {.name = "ws_netstats_q"};
295+
296+
k_work_queue_init(&ws_netstats_queue);
297+
k_work_queue_start(&ws_netstats_queue, ws_netstats_stack, WS_NETSTATS_STACK_SIZE, 0, &cfg);
298+
289299
for (int i = 0; i < CONFIG_NET_SAMPLE_NUM_WEBSOCKET_HANDLERS; i++) {
290300
netstats_ctx[i].sock = -1;
291301
k_work_init_delayable(&netstats_ctx[i].work, netstats_handler);
@@ -344,7 +354,7 @@ int ws_netstats_setup(int ws_socket, struct http_request_ctx *request_ctx, void
344354

345355
netstats_ctx[slot].sock = ws_socket;
346356

347-
ret = k_work_reschedule(&netstats_ctx[slot].work, K_NO_WAIT);
357+
ret = k_work_reschedule_for_queue(&ws_netstats_queue, &netstats_ctx[slot].work, K_NO_WAIT);
348358
if (ret < 0) {
349359
LOG_ERR("Failed to schedule netstats work, err %d", ret);
350360
return ret;

0 commit comments

Comments
 (0)