From 6bb5b002e0a66dfc7e7bcc1bc1234455b4e4e687 Mon Sep 17 00:00:00 2001 From: "Dr. Chat" Date: Sun, 5 Jul 2015 13:31:51 -0500 Subject: [PATCH] Gracefully handle debugger accept thread already running --- src/xenia/debug/debugger.cc | 122 +++++++++++++++++++----------------- src/xenia/debug/debugger.h | 1 + 2 files changed, 64 insertions(+), 59 deletions(-) diff --git a/src/xenia/debug/debugger.cc b/src/xenia/debug/debugger.cc index e8b887e47..44c033337 100644 --- a/src/xenia/debug/debugger.cc +++ b/src/xenia/debug/debugger.cc @@ -58,7 +58,8 @@ Breakpoint::~Breakpoint() = default; Debugger::Debugger(Emulator* emulator) : emulator_(emulator), listen_socket_(INVALID_SOCKET), - client_socket_(INVALID_SOCKET) { + client_socket_(INVALID_SOCKET), + accept_thread_running_(false) { WSADATA wsa_data; WSAStartup(MAKEWORD(2, 2), &wsa_data); } @@ -134,67 +135,70 @@ void SendResponse(SOCKET client_socket, flatbuffers::FlatBufferBuilder& fbb, } void Debugger::PreLaunch() { - accept_thread_ = std::thread([this]() { - xe::threading::set_name("Debugger Server"); + if (!accept_thread_running_) { + accept_thread_running_ = true; + accept_thread_ = std::thread([this]() { + xe::threading::set_name("Debugger Server"); - while (listen_socket_ != INVALID_SOCKET) { - sockaddr_in6 client_addr; - int client_count = sizeof(client_addr); - SOCKET client_socket_id = - accept(listen_socket_, reinterpret_cast(&client_addr), - &client_count); - if (client_socket_id == INVALID_SOCKET) { - XELOGE("Failed to accept socket"); - continue; - } - - // Only one debugger at a time. - if (client_socket_ != INVALID_SOCKET) { - XELOGW("Ignoring debugger connection as one is already connected"); - closesocket(client_socket_id); - continue; - } - - // Setup recv thread. - client_socket_ = client_socket_id; - receive_thread_ = std::thread([this]() { - xe::threading::set_name("Debugger Connection"); - - while (client_socket_ != INVALID_SOCKET) { - // Read length prefix. - uint32_t length = 0; - int r = recv(client_socket_, reinterpret_cast(&length), 4, - MSG_WAITALL); - if (r != 4) { - // Failed? - XELOGE("Failed to recv debug data length - dead connection?"); - if (FLAGS_exit_with_debugger) { - exit(1); - } - break; - } - - // Read body. - std::vector body(length); - r = recv(client_socket_, reinterpret_cast(body.data()), length, - MSG_WAITALL); - if (r != length) { - // Failed? - XELOGE("Failed to recv debug data body - dead connection?"); - if (FLAGS_exit_with_debugger) { - exit(1); - } - break; - } - - // Read message contents and dispatch. - OnMessage(std::move(body)); + while (listen_socket_ != INVALID_SOCKET) { + sockaddr_in6 client_addr; + int client_count = sizeof(client_addr); + SOCKET client_socket_id = + accept(listen_socket_, reinterpret_cast(&client_addr), + &client_count); + if (client_socket_id == INVALID_SOCKET) { + XELOGE("Failed to accept socket"); + continue; } - }); - // This will WaitForClient if it was waiting. - } - }); + // Only one debugger at a time. + if (client_socket_ != INVALID_SOCKET) { + XELOGW("Ignoring debugger connection as one is already connected"); + closesocket(client_socket_id); + continue; + } + + // Setup recv thread. + client_socket_ = client_socket_id; + receive_thread_ = std::thread([this]() { + xe::threading::set_name("Debugger Connection"); + + while (client_socket_ != INVALID_SOCKET) { + // Read length prefix. + uint32_t length = 0; + int r = recv(client_socket_, reinterpret_cast(&length), 4, + MSG_WAITALL); + if (r != 4) { + // Failed? + XELOGE("Failed to recv debug data length - dead connection?"); + if (FLAGS_exit_with_debugger) { + exit(1); + } + break; + } + + // Read body. + std::vector body(length); + r = recv(client_socket_, reinterpret_cast(body.data()), + length, MSG_WAITALL); + if (r != length) { + // Failed? + XELOGE("Failed to recv debug data body - dead connection?"); + if (FLAGS_exit_with_debugger) { + exit(1); + } + break; + } + + // Read message contents and dispatch. + OnMessage(std::move(body)); + } + }); + + // This will WaitForClient if it was waiting. + } + }); + } if (FLAGS_wait_for_debugger) { // Wait for the first client. diff --git a/src/xenia/debug/debugger.h b/src/xenia/debug/debugger.h index 9bb446679..08b3d4266 100644 --- a/src/xenia/debug/debugger.h +++ b/src/xenia/debug/debugger.h @@ -111,6 +111,7 @@ class Debugger { Emulator* emulator_; uintptr_t listen_socket_; + bool accept_thread_running_; std::thread accept_thread_; xe::threading::Fence accept_fence_; uintptr_t client_socket_;