From 6bec3db3fb623c193583cb1c1002399085f42dfa Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 21 Apr 2018 15:33:34 -0700 Subject: [PATCH] Debugger: Disconnect on shutdown/disable. Although, it could be made safe to keep them up when restarting with debugging still enabled. --- Core/Debugger/WebSocket.cpp | 31 +++++++++++++++++++++++++++++++ Core/Debugger/WebSocket.h | 2 ++ Core/WebServer.cpp | 2 ++ ext/native/net/http_server.cpp | 2 +- ext/native/net/http_server.h | 1 + 5 files changed, 37 insertions(+), 1 deletion(-) diff --git a/Core/Debugger/WebSocket.cpp b/Core/Debugger/WebSocket.cpp index 6343a8331d..d42fdbd3a2 100644 --- a/Core/Debugger/WebSocket.cpp +++ b/Core/Debugger/WebSocket.cpp @@ -15,6 +15,8 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. +#include +#include #include "thread/threadutil.h" #include "Core/Debugger/WebSocket.h" #include "Core/Debugger/WebSocket/WebSocketUtils.h" @@ -54,12 +56,25 @@ static const std::vector subscribers({ { &WebSocketCPUCoreInit, nullptr }, }); +// To handle webserver restart, keep track of how many running. +static volatile int debuggersConnected = 0; +static volatile bool stopRequested = false; +static std::mutex stopLock; +static std::condition_variable stopCond; + +static void UpdateConnected(int delta) { + std::lock_guard guard(stopLock); + debuggersConnected += delta; + stopCond.notify_all(); +} + void HandleDebuggerRequest(const http::Request &request) { net::WebSocketServer *ws = net::WebSocketServer::CreateAsUpgrade(request, "debugger.ppsspp.org"); if (!ws) return; setCurrentThreadName("Debugger"); + UpdateConnected(1); LogBroadcaster logger; GameBroadcaster game; @@ -103,6 +118,10 @@ void HandleDebuggerRequest(const http::Request &request) { logger.Broadcast(ws); game.Broadcast(ws); stepping.Broadcast(ws); + + if (stopRequested) { + ws->Close(net::WebSocketClose::GOING_AWAY); + } } for (size_t i = 0; i < subscribers.size(); ++i) { @@ -114,4 +133,16 @@ void HandleDebuggerRequest(const http::Request &request) { } delete ws; + UpdateConnected(-1); +} + +void StopAllDebuggers() { + std::unique_lock guard(stopLock); + while (debuggersConnected != 0) { + stopRequested = true; + stopCond.wait(guard); + } + + // Reset it back for next time. + stopRequested = false; } diff --git a/Core/Debugger/WebSocket.h b/Core/Debugger/WebSocket.h index 73b4e5fe8f..0151ca686a 100644 --- a/Core/Debugger/WebSocket.h +++ b/Core/Debugger/WebSocket.h @@ -22,3 +22,5 @@ class Request; } void HandleDebuggerRequest(const http::Request &request); +// Note: blocks. +void StopAllDebuggers(); diff --git a/Core/WebServer.cpp b/Core/WebServer.cpp index d0f7c39fe7..f5fdf68754 100644 --- a/Core/WebServer.cpp +++ b/Core/WebServer.cpp @@ -216,6 +216,8 @@ static void ExecuteWebServer() { } http->Stop(); + StopAllDebuggers(); + delete http; // Move to STARTING to lock flags/STOPPING. if (UpdateStatus(ServerStatus::STARTING, ServerStatus::RESTARTING)) { diff --git a/ext/native/net/http_server.cpp b/ext/native/net/http_server.cpp index ace77907c4..c77dd37169 100644 --- a/ext/native/net/http_server.cpp +++ b/ext/native/net/http_server.cpp @@ -279,7 +279,7 @@ void Server::HandleConnection(int conn_fd) { WLOG("Bad request, ignoring."); return; } - HandleRequestDefault(request); + HandleRequest(request); // TODO: Way to mark the content body as read, read it here if never read. // This allows the handler to stream if need be. diff --git a/ext/native/net/http_server.h b/ext/native/net/http_server.h index 5220bda762..6fc97d907b 100644 --- a/ext/native/net/http_server.h +++ b/ext/native/net/http_server.h @@ -63,6 +63,7 @@ private: class Server { public: Server(threading::Executor *executor); + virtual ~Server() {} typedef std::function UrlHandlerFunc; typedef std::map UrlHandlerMap;