From 7b398c01f6469bcf83c7e48359f87a99cdf58465 Mon Sep 17 00:00:00 2001 From: Philip Rideout Date: Tue, 20 Jul 2021 09:10:26 -0700 Subject: [PATCH] matdbg: support multiple simultaneous clients. Previously, if you accidentally had two matdbg tabs open in Chrome, the web app would hang. This fixes two bugs that prevented multiple simultaneous clients: 1) The websocket handler broadcasted edit events to only the most recent connection. 2) The number of server threads was only 2, but the actual web app requires at least 2 threads for each instance, due to the externally linked CSS file. --- libs/matdbg/src/DebugServer.cpp | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/libs/matdbg/src/DebugServer.cpp b/libs/matdbg/src/DebugServer.cpp index 2b8bc82c1d..6816d35082 100644 --- a/libs/matdbg/src/DebugServer.cpp +++ b/libs/matdbg/src/DebugServer.cpp @@ -31,6 +31,8 @@ #include +#include + #include #include @@ -334,7 +336,7 @@ public: } void handleReadyState(CivetServer *server, struct mg_connection *conn) override { - mConnection = conn; + mConnections.insert(conn); } bool handleData(CivetServer *server, struct mg_connection *conn, int bits, char *data, @@ -417,21 +419,22 @@ public: } void handleClose(CivetServer *server, const struct mg_connection *conn) override { - mConnection = nullptr; + struct mg_connection *key = const_cast(conn); + mConnections.erase(key); } - // Notify the JavaScript client that a new material package has been loaded. + // Notify all JavaScript clients that a new material package has been loaded. void addMaterial(const DebugServer::MaterialRecord& material) { - if (mConnection) { + for (auto connection : mConnections) { char matid[9] = {}; snprintf(matid, sizeof(matid), "%8.8x", material.key); - mg_websocket_write(mConnection, MG_WEBSOCKET_OPCODE_TEXT, matid, 8); + mg_websocket_write(connection, MG_WEBSOCKET_OPCODE_TEXT, matid, 8); } } private: DebugServer* mServer; - struct mg_connection* mConnection = nullptr; + tsl::robin_set mConnections; }; DebugServer::DebugServer(Backend backend, int port) : mBackend(backend) { @@ -441,11 +444,13 @@ DebugServer::DebugServer(Backend backend, int port) : mBackend(backend) { mCss = CString((const char*) MATDBG_RESOURCES_STYLE_DATA, MATDBG_RESOURCES_STYLE_SIZE - 1); #endif - // By default the server spawns 50 threads so we override this to 2. This limits the server - // to having no more than 2 HTTP clients, which is perfectly fine for debugging purposes. + // By default the server spawns 50 threads so we override this to 10. According to the civetweb + // documentation, "it is recommended to use num_threads of at least 5, since browsers often + /// establish multiple connections to load a single web page, including all linked documents + // (CSS, JavaScript, images, ...)." If this count is too small, the web app basically hangs. const char* kServerOptions[] = { "listening_ports", "8080", - "num_threads", "2", + "num_threads", "10", "error_log_file", "civetweb.txt", nullptr };