From patchwork Tue Jul 9 11:08:57 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael Glembotzki X-Patchwork-Id: 1958340 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=googlegroups.com header.i=@googlegroups.com header.a=rsa-sha256 header.s=20230601 header.b=j4u2hKMo; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20230601 header.b=IWm5bpkv; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=googlegroups.com (client-ip=2a00:1450:4864:20::240; helo=mail-lj1-x240.google.com; envelope-from=swupdate+bncbdy5juxlviebbvvxws2amgqef7tig4i@googlegroups.com; receiver=patchwork.ozlabs.org) Received: from mail-lj1-x240.google.com (mail-lj1-x240.google.com [IPv6:2a00:1450:4864:20::240]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4WJJLy68Sdz1xpd for ; Tue, 9 Jul 2024 21:15:38 +1000 (AEST) Received: by mail-lj1-x240.google.com with SMTP id 38308e7fff4ca-2ee94443d31sf25206491fa.1 for ; Tue, 09 Jul 2024 04:15:38 -0700 (PDT) ARC-Seal: i=2; a=rsa-sha256; t=1720523735; cv=pass; d=google.com; s=arc-20160816; b=onPrqB/Lw5IOcnKgFWKMcvDuxBUlqcGVXEIy28Gi9knpudoWIGO3HWeyfxlP2vjlA9 3jFt332W//15x4IubQUBQ9qwmQDBUqE9LAoZwobp0FbTyKVGCC1T2RRRdb3FJaq4EtqB zdo08jXuFG8OocTXH1qXn8L0aRDeLD6zMLvCAkoULYrJYpowuSIWyMlVu1E7dHZbvfyY 0vImCyGAChAcgoiyLl08JKt2k46+U0isrW9zcR724zN60fcI1/Zs3na+OkQSdx0nrhcu N8sRI4FVL/WcZNDpwL9Xf1+n4D2E8eriB5FIaxcmuETORiybVg4O2NE0LMglShELk/yp ePXQ== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-unsubscribe:list-subscribe:list-archive:list-help:list-post :list-id:mailing-list:precedence:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:sender:dkim-signature :dkim-signature; bh=vC5JooHC3CSZZkJHGFm4x3WGXjXOKd5SznKPJjfD/MU=; fh=0lD0R4vV/TkwDxMviW6WMmhTL7VurkD1CSU1X+4LJkY=; b=rSmTFjhA3duyK34jvOSrk+MLJec5zHAYhNSmvEkhqC/wTuSxuUjV8APafAr4zfXW7m jNmeVKb7fwlkJgBdrUt2NBAg37D+zSDbdbOtDEnr42jLJctcwAk+m4KbtIhTzLgWxebf 2IJzt2g44Guk0zV1iGlgWj7wpkUEAAjo5UogrF5ciwBlJs9fZWTaqb06aIhD2tHGznwI oxmPMZLY4Yy+bEHUNkHc8xue/V/iCKjE1VgNcRBhMk2D7t8CI7zDb/AtOO99IYXen74h XCIawYeniGpBrE/3THcPySsEbkbxAKHeW6kNQCpwA6WKN11QsCOIn7mUefs0oS5zFwiP RxIA==; darn=patchwork.ozlabs.org ARC-Authentication-Results: i=2; gmr-mx.google.com; dkim=pass header.i=@gmail.com header.s=20230601 header.b=Ren5PiU3; spf=pass (google.com: domain of m.glembo@gmail.com designates 2a00:1450:4864:20::629 as permitted sender) smtp.mailfrom=m.glembo@gmail.com; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=googlegroups.com; s=20230601; t=1720523735; x=1721128535; darn=patchwork.ozlabs.org; h=list-unsubscribe:list-subscribe:list-archive:list-help:list-post :list-id:mailing-list:precedence:x-original-authentication-results :x-original-sender:mime-version:references:in-reply-to:message-id :date:subject:cc:to:from:sender:from:to:cc:subject:date:message-id :reply-to; bh=vC5JooHC3CSZZkJHGFm4x3WGXjXOKd5SznKPJjfD/MU=; b=j4u2hKMoHwoTbBdvt8gG86J6TAexQXvTx4g9EUMyG9ZQ6IK41nQT2b4mQQ08NThF6+ +4J6FXcLzm06B+Q2uvoFbB5SM5PadsdcdqA7VVUgDYP1eMmIfX7R1H8CLGOC/EWL3NKK MzV0BepUtlFulXk23WZpBDjj6osYr/jHbD81wxwq7Z2HJjCB9bpeUkS0qCpMIi2IPTCE /tUWU/2Hxa/0WcUWQ9L/pMl9/VW6UlM1lzMY4m2YlRuC4ZVMVDkm4AJHTY3DqBXW1hyg NMBRlAaGwBfZk4sYNfq+09OLAGL+RFh2kR717OwM8mtvGNXp8scyLRSuC3SFw4Z6gUzd 5Jsw== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1720523735; x=1721128535; darn=patchwork.ozlabs.org; h=list-unsubscribe:list-subscribe:list-archive:list-help:list-post :list-id:mailing-list:precedence:x-original-authentication-results :x-original-sender:mime-version:references:in-reply-to:message-id :date:subject:cc:to:from:from:to:cc:subject:date:message-id:reply-to; bh=vC5JooHC3CSZZkJHGFm4x3WGXjXOKd5SznKPJjfD/MU=; b=IWm5bpkvgvAHnWJ/XkF9rWS0n7s8rYHVZj0QXusQ9SMxTVdxiJTfscnUoFFcsoA4/s +uWk3thtnp+/jmy5Zi5ECWs7J9cDIXhBAcwNzHmqxcAQK2uPwrCn4FS1Is0qPz8QFlOS /cddBnpZa+PlRkyl7XN5EiDWmIbkjrwOFvu6wqh6Rd4le5VWDX77LfwjGjTIFbi4x07n /YBqmOJRHaFGdEjOEexqrbZ7sJvO7SfFEYGGt/2raDpvBdvL/6ONn4tRtIxs1qFP4Q73 H5g+E7RB4AnTEZddqZOfPPSUpAWKQNFEjzsmNGBx0MB4bftY9sOBCbPwvkyA6Z+3pe2B L0yQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1720523735; x=1721128535; h=list-unsubscribe:list-subscribe:list-archive:list-help:list-post :x-spam-checked-in-group:list-id:mailing-list:precedence :x-original-authentication-results:x-original-sender:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :x-beenthere:x-gm-message-state:sender:from:to:cc:subject:date :message-id:reply-to; bh=vC5JooHC3CSZZkJHGFm4x3WGXjXOKd5SznKPJjfD/MU=; b=VPF67SQFL6/osmrRPL6JOw6SvlwbsFZi15bjxGuGLtIIVut62fvuknNicVpgOxQ1v2 6v8nnD0u7d+Nz8bHAwmZWBXbkL2EMwxEROldwz3d4Kl8lw49IteOjD59gTAvmxcXp3Nu 4mIplnWPMcpFMazVaYrmJ2qEbX0Ux/ycWtIXYP5UxZoOIvJTbFQU8wsyg0mSe2bTVUHc RmgMfF/VtZxAziI2AoqFaWdv/Y0z0CZ9FUYtRxQ+dwispD70gOeOpPIE9Yb95fHmiaNV 5499cxcUdCJa3cSh9xIl4VGWKwH6aGpECTpmUyrlo0Z3IN2n45TdKUFjv6zFL3L+uFf3 dLeQ== Sender: swupdate@googlegroups.com X-Forwarded-Encrypted: i=2; AJvYcCVrnPGtlunUQZVc4EBGwfTKRfKZwdr5S/OV9clSvJkuybMK2od5ldiS3xjjIQ3TNsRH3FpsoMhPb+wPCHCvmg8RZGMhGeYsOmpntf/M7w== X-Gm-Message-State: AOJu0Yxlc/n+tLNzHtxtaK1w4kJnciYWUQNNVlY9dqyYVXbf0X7U3Wj5 /P/94pZyF5nCXHLCbeMO6ayQW73YT0N8MMxYgpi870WyRXvmxABG X-Google-Smtp-Source: AGHT+IHhjdQFSrgjBNt5E5UTh1E5K8RscFZVyxlT95fj5i7pTOYF9pEY9aPks/NPsgCmuoryipzjcw== X-Received: by 2002:a2e:9ed4:0:b0:2ee:6e94:632d with SMTP id 38308e7fff4ca-2eeb46a76cfmr4961171fa.15.1720523734968; Tue, 09 Jul 2024 04:15:34 -0700 (PDT) X-BeenThere: swupdate@googlegroups.com Received: by 2002:a05:651c:485:b0:2ec:4f16:19f1 with SMTP id 38308e7fff4ca-2ee8cceb3ecls10318361fa.0.-pod-prod-00-eu; Tue, 09 Jul 2024 04:15:32 -0700 (PDT) X-Received: by 2002:a2e:a40c:0:b0:2eb:ec25:b759 with SMTP id 38308e7fff4ca-2eeb468ab95mr5311621fa.3.1720523730977; Tue, 09 Jul 2024 04:15:30 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1720523730; cv=none; d=google.com; s=arc-20160816; b=yXqGYxNHFugnJ+qZbs2mMfM5KZ1DbiZiDTgtHGgba+iXw3YEqvFDhpa2LQwGkpdT2p 1nHQXf+TN1lp/bHLoYKHf3HC7oKA2dYwO9Aqx3B4PfBivDgTyUKkctkFV7oSUWd+T7kC JUmRZZyfhrprugAcuOdHHxgI9XbBTAs052G5+aH9iShOWThPh+3gtBSVy+EhRTh6eMs9 mvFva6NqAzcnmv97LastJkDToDDS1/uQjbdsFIifqw1QiMjQOMkq8EN4F52W4Lyb7WZO kpiLrErAR69NBLl+dzPnbwlwFu+Fyk4td1u4O3u+RCDFxzLGpgdIjYZ2ZHAW2W1pY137 XAJA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:dkim-signature; bh=YZmRABg+UkVVbVBxe0e71B7g6gbZnSz/4Y2W10Lfsuk=; fh=zydHuzCQWrku2OPQyZfraJZFcOpEXLQ/YBcu3QNiBd0=; b=w/Pjjd7H+oqsiL4w6SDu97hGHrWyEqkaSx5tapc73F+8LQv83lQfFLtJzXuCtEJgkN 4se1vauc8o3DEqA/kYsw882NSmSMTEDOiQPtAZe15oyEsbuQWHzgIoVk22Mb5X5AewWm VC7YqJwU+WG9QNuXC5eyUOI3t+Szg6kA6KWW9dAhay/a0kxzidh1B3FclomdwK371o9w z8SVOgZZZ5iIYWxCPYSXkhi0L2/AWDOWlfAIM4snIbDZQHXhRD8Po9Fm/qPdDTdQMfP0 pax/hKQNaQRc6BKW1fZmAuVIJkr73LtYAunPO0PP3gq+v93AEBlqBHBUxngDo+pw/TlW 1QaQ==; dara=google.com ARC-Authentication-Results: i=1; gmr-mx.google.com; dkim=pass header.i=@gmail.com header.s=20230601 header.b=Ren5PiU3; spf=pass (google.com: domain of m.glembo@gmail.com designates 2a00:1450:4864:20::629 as permitted sender) smtp.mailfrom=m.glembo@gmail.com; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: from mail-ej1-x629.google.com (mail-ej1-x629.google.com. [2a00:1450:4864:20::629]) by gmr-mx.google.com with ESMTPS id 38308e7fff4ca-2eeb3381fc5si334301fa.0.2024.07.09.04.15.30 for (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Tue, 09 Jul 2024 04:15:30 -0700 (PDT) Received-SPF: pass (google.com: domain of m.glembo@gmail.com designates 2a00:1450:4864:20::629 as permitted sender) client-ip=2a00:1450:4864:20::629; Received: by mail-ej1-x629.google.com with SMTP id a640c23a62f3a-a77cc73d35fso644518166b.0 for ; Tue, 09 Jul 2024 04:15:30 -0700 (PDT) X-Received: by 2002:a17:907:3fa0:b0:a6f:e03a:99d with SMTP id a640c23a62f3a-a780d0a4445mr183660966b.0.1720523730038; Tue, 09 Jul 2024 04:15:30 -0700 (PDT) Received: from PC-2635.irisgmbh.local (dslb-002-203-138-100.002.203.pools.vodafone-ip.de. [2.203.138.100]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-a780a6bc8adsm70739166b.14.2024.07.09.04.15.29 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 09 Jul 2024 04:15:29 -0700 (PDT) From: Michael Glembotzki To: swupdate@googlegroups.com Cc: Michael Glembotzki Subject: [swupdate] [V3][PATCH 21/21] mongoose: Replace deprecated mg_mkpipe() with mg_wakeup() Date: Tue, 9 Jul 2024 13:08:57 +0200 Message-ID: <20240709111440.8215-22-Michael.Glembotzki@iris-sensing.com> X-Mailer: git-send-email 2.44.0 In-Reply-To: <20240709111440.8215-1-Michael.Glembotzki@iris-sensing.com> References: <20240709111440.8215-1-Michael.Glembotzki@iris-sensing.com> MIME-Version: 1.0 X-Original-Sender: m.glembo@gmail.com X-Original-Authentication-Results: gmr-mx.google.com; dkim=pass header.i=@gmail.com header.s=20230601 header.b=Ren5PiU3; spf=pass (google.com: domain of m.glembo@gmail.com designates 2a00:1450:4864:20::629 as permitted sender) smtp.mailfrom=m.glembo@gmail.com; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Precedence: list Mailing-list: list swupdate@googlegroups.com; contact swupdate+owners@googlegroups.com List-ID: X-Spam-Checked-In-Group: swupdate@googlegroups.com X-Google-Group-Id: 605343134186 List-Post: , List-Help: , List-Archive: , List-Unsubscribe: , Use the new mg_wakeup() [1] mechansim to send data from the broadcast(s) to the parent event manager thread. Based on mongoose multi-threaded example [2]. [1] https://mongoose.ws/documentation/#mg_wakeup [2] https://github.com/cesanta/mongoose/blob/master/tutorials/core/multi-threaded-12m/main.c Signed-off-by: Michael Glembotzki --- mongoose/mongoose_interface.c | 104 ++++++++++++++++++++-------------- 1 file changed, 61 insertions(+), 43 deletions(-) diff --git a/mongoose/mongoose_interface.c b/mongoose/mongoose_interface.c index f67b1089..260ed8f9 100644 --- a/mongoose/mongoose_interface.c +++ b/mongoose/mongoose_interface.c @@ -64,6 +64,11 @@ struct file_upload_state { uint64_t last_io_time; }; +struct parent_connection_info { + struct mg_mgr *mgr; + unsigned long conn_id; +}; + static bool run_postupdate; static unsigned int watchdog_conn = 0; static struct mg_http_serve_opts s_http_server_opts; @@ -74,8 +79,6 @@ static bool ssl; static struct mg_tls_opts tls_opts; #endif -static int ws_pipe; - static int s_signo = 0; static void signal_handler(int signo) { s_signo = signo; @@ -358,30 +361,6 @@ static void restart_handler(struct mg_connection *nc, void *ev_data) mg_http_reply(nc, 201, "", "%s", "Device will reboot now.\n"); } -static void broadcast_callback(struct mg_connection *nc, int ev, - void __attribute__ ((__unused__)) *ev_data) -{ - static uint64_t last_io_time = 0; - if (ev == MG_EV_READ) { - struct mg_connection *t; - for (t = nc->mgr->conns; t != NULL; t = t->next) { - if (!t->is_websocket) continue; - mg_ws_send(t,(char *)nc->recv.buf, nc->recv.len, WEBSOCKET_OP_TEXT); - } - mg_iobuf_del(&nc->recv, 0, nc->recv.len); - last_io_time = mg_millis(); - } else if (ev == MG_EV_POLL) { - struct mg_connection *t; - uint64_t now = *((uint64_t *)ev_data); - if (now < last_io_time + 20000) return; - for (t = nc->mgr->conns; t != NULL; t = t->next) { - if (!t->is_websocket) continue; - mg_ws_send(t, "", 0, WEBSOCKET_OP_PING); - } - last_io_time = now; - } -} - static int level_to_rfc_5424(int level) { switch(level) { @@ -398,14 +377,18 @@ static int level_to_rfc_5424(int level) } } -static void broadcast(char *str) +static void broadcast(struct parent_connection_info *p, char *str) { - send(ws_pipe, str, strlen(str), 0); + mg_wakeup(p->mgr, p->conn_id, str, strlen(str)); } -static void *broadcast_message_thread(void __attribute__ ((__unused__)) *data) +static void *broadcast_message_thread(void *data) { int fd = -1; + struct parent_connection_info *p = (struct parent_connection_info *) data; + + if(!p) + return NULL; for (;;) { ipc_message msg; @@ -423,7 +406,7 @@ static void *broadcast_message_thread(void __attribute__ ((__unused__)) *data) ret = ipc_notify_receive(&fd, &msg); if (ret != sizeof(msg)) - return NULL; + break; if (strlen(msg.data.notify.msg) != 0 && msg.data.status.current != PROGRESS) { @@ -441,18 +424,24 @@ static void *broadcast_message_thread(void __attribute__ ((__unused__)) *data) level_to_rfc_5424(msg.data.notify.level), /* RFC 5424 */ text); - broadcast(str); + broadcast(p, str); } } + free(p); + return NULL; } -static void *broadcast_progress_thread(void __attribute__ ((__unused__)) *data) +static void *broadcast_progress_thread(void *data) { RECOVERY_STATUS status = -1; sourcetype source = -1; unsigned int step = 0; uint8_t percent = 0; int fd = -1; + struct parent_connection_info *p = (struct parent_connection_info *) data; + + if(!p) + return NULL; for (;;) { struct progress_msg msg; @@ -472,7 +461,7 @@ static void *broadcast_progress_thread(void __attribute__ ((__unused__)) *data) ret = progress_ipc_receive(&fd, &msg); if (ret != sizeof(msg)) - return NULL; + break; if (msg.status != PROGRESS && (msg.status != status || msg.status == FAILURE)) { @@ -486,7 +475,7 @@ static void *broadcast_progress_thread(void __attribute__ ((__unused__)) *data) "\t\"status\": \"%s\"\r\n" "}\r\n", escaped); - broadcast(str); + broadcast(p, str); } if (msg.source != source) { @@ -498,7 +487,7 @@ static void *broadcast_progress_thread(void __attribute__ ((__unused__)) *data) "\t\"source\": \"%s\"\r\n" "}\r\n", get_source_string(msg.source)); - broadcast(str); + broadcast(p, str); } if (msg.status == SUCCESS && msg.source == SOURCE_WEBSERVER && run_postupdate) { @@ -516,7 +505,7 @@ static void *broadcast_progress_thread(void __attribute__ ((__unused__)) *data) "\t\"source\": \"%s\"\r\n" "}\r\n", escaped); - broadcast(str); + broadcast(p, str); } if ((msg.cur_step != step || msg.cur_percent != percent) && @@ -538,9 +527,11 @@ static void *broadcast_progress_thread(void __attribute__ ((__unused__)) *data) msg.cur_step, escaped, msg.cur_percent); - broadcast(str); + broadcast(p, str); } } + free(p); + return NULL; } static void timer_ev_handler(void *fn_data) @@ -682,11 +673,20 @@ static void websocket_handler(struct mg_connection *nc, void *ev_data) { struct mg_http_message *hm = (struct mg_http_message *) ev_data; mg_ws_upgrade(nc, hm, NULL); + nc->data[0] = 'W'; // Set unique Websocket marker } static void ev_handler(struct mg_connection *nc, int ev, void *ev_data) { - if (nc->data[0] != 'M' && ev == MG_EV_HTTP_MSG) { + static uint64_t last_io_time = 0; + if (ev == MG_EV_OPEN && nc->is_listening) { + struct parent_connection_info *data = calloc(2, sizeof(struct parent_connection_info)); + data[0].mgr = nc->mgr; + data[0].conn_id = nc->id; + memcpy(&data[1], &data[0], sizeof(struct parent_connection_info)); + start_thread(broadcast_message_thread, &data[0]); + start_thread(broadcast_progress_thread, &data[1]); + } else if (nc->data[0] != 'M' && nc->data[0] != 'W' && ev == MG_EV_HTTP_MSG) { struct mg_http_message *hm = (struct mg_http_message *) ev_data; if (!mg_http_is_authorized(hm, global_auth_domain, global_auth_file)) mg_http_send_digest_auth_request(nc, global_auth_domain); @@ -696,7 +696,7 @@ static void ev_handler(struct mg_connection *nc, int ev, void *ev_data) restart_handler(nc, ev_data); else mg_http_serve_dir(nc, ev_data, &s_http_server_opts); - } else if (nc->data[0] != 'M' && ev == MG_EV_READ) { + } else if (nc->data[0] != 'M' && nc->data[0] != 'W' && ev == MG_EV_READ) { struct mg_http_message hm; int hlen = mg_http_parse((char *) nc->recv.buf, nc->recv.len, &hm); if (hlen > 0) { @@ -727,6 +727,27 @@ static void ev_handler(struct mg_connection *nc, int ev, void *ev_data) ERROR("%p %s", nc->fd, (char *) ev_data); } else if (ev == MG_EV_WS_MSG) { mg_iobuf_del(&nc->recv, 0, nc->recv.len); + } else if (ev == MG_EV_WAKEUP) { + // forward broadcast messages + struct mg_str *data = (struct mg_str *) ev_data; + struct mg_connection *t; + for (t = nc->mgr->conns; t != NULL; t = t->next) { + if (t->data[0] == 'W') { + mg_ws_send(t, data->buf, data->len, WEBSOCKET_OP_TEXT); + } + } + last_io_time = mg_millis(); + } else if (ev == MG_EV_POLL) { + // websocket heartbeat every 20s + struct mg_connection *t; + uint64_t now = *((uint64_t *)ev_data); + if (now < last_io_time + 20000) return; + for (t = nc->mgr->conns; t != NULL; t = t->next) { + if (t->data[0] == 'W') { + mg_ws_send(t, "", 0, WEBSOCKET_OP_PING); + } + } + last_io_time = now; } } @@ -908,8 +929,6 @@ int start_mongoose(const char *cfgfname, int argc, char *argv[]) signal(SIGTERM, signal_handler); mg_mgr_init(&mgr); - ws_pipe = mg_mkpipe(&mgr, broadcast_callback, NULL, true); - /* Parse url with port only fallback */ if (opts.port) { if (mg_url_port(opts.port) != 0) { @@ -934,8 +953,7 @@ int start_mongoose(const char *cfgfname, int argc, char *argv[]) exit(EXIT_FAILURE); } - start_thread(broadcast_message_thread, NULL); - start_thread(broadcast_progress_thread, NULL); + mg_wakeup_init(&mgr); INFO("Mongoose web server v%s with PID %d listening on %s and serving %s", MG_VERSION, getpid(), url, s_http_server_opts.root_dir);