WaitForClient moved to server, now working.

This commit is contained in:
Ben Vanik 2013-12-20 23:52:47 -08:00
parent 8a7bd7b69a
commit d98d5c855a
7 changed files with 76 additions and 43 deletions

View File

@ -30,8 +30,10 @@ DebugServer::DebugServer(Emulator* emulator) :
emulator_(emulator), lock_(0) {
lock_ = xe_mutex_alloc(10000);
//protocols_.push_back(
// new protocols::gdb::GDBProtocol(this));
client_event_ = CreateEvent(NULL, FALSE, FALSE, NULL);
protocols_.push_back(
new protocols::gdb::GDBProtocol(this));
protocols_.push_back(
new protocols::ws::WSProtocol(this));
}
@ -39,10 +41,19 @@ DebugServer::DebugServer(Emulator* emulator) :
DebugServer::~DebugServer() {
Shutdown();
CloseHandle(client_event_);
xe_free(lock_);
lock_ = 0;
}
bool DebugServer::has_clients() {
xe_mutex_lock(lock_);
bool has_clients = clients_.size() > 0;
xe_mutex_unlock(lock_);
return has_clients;
}
int DebugServer::Startup() {
return 0;
}
@ -66,7 +77,7 @@ int DebugServer::BeforeEntry() {
// If desired, wait until the first client connects.
//if (FLAGS_wait_for_debugger) {
XELOGI("Waiting for debugger...");
if (protocols_[0]->WaitForClient()) {
if (WaitForClient()) {
return 1;
}
XELOGI("Debugger attached, continuing...");
@ -95,6 +106,13 @@ void DebugServer::Shutdown() {
xe_mutex_unlock(lock_);
}
int DebugServer::WaitForClient() {
while (!has_clients()) {
WaitForSingleObject(client_event_, INFINITE);
}
return 0;
}
void DebugServer::AddClient(DebugClient* debug_client) {
xe_mutex_lock(lock_);
@ -108,6 +126,8 @@ void DebugServer::AddClient(DebugClient* debug_client) {
clients_.push_back(debug_client);
xe_mutex_unlock(lock_);
SetEvent(client_event_);
}
void DebugServer::RemoveClient(DebugClient* debug_client) {

View File

@ -32,10 +32,14 @@ public:
Emulator* emulator() const { return emulator_; }
bool has_clients();
int Startup();
int BeforeEntry();
void Shutdown();
int WaitForClient();
private:
void AddClient(DebugClient* debug_client);
void RemoveClient(DebugClient* debug_client);
@ -48,6 +52,7 @@ private:
xe_mutex_t* lock_;
std::vector<DebugClient*> clients_;
HANDLE client_event_;
};

View File

@ -27,7 +27,6 @@ public:
virtual ~Protocol();
virtual int Setup() = 0;
virtual int WaitForClient() = 0;
protected:
DebugServer* debug_server_;

View File

@ -24,11 +24,18 @@ using namespace xe::debug::protocols::gdb;
GDBProtocol::GDBProtocol(DebugServer* debug_server) :
port_(0), socket_id_(0), thread_(0), running_(false),
Protocol(debug_server) {
port_ = FLAGS_gdb_debug_port;
}
GDBProtocol::~GDBProtocol() {
if (thread_) {
// Join thread.
running_ = false;
xe_thread_release(thread_);
thread_ = 0;
}
if (socket_id_) {
xe_socket_close(socket_id_);
}
@ -60,29 +67,39 @@ int GDBProtocol::Setup() {
return 1;
}
return 0;
}
int GDBProtocol::WaitForClient() {
if (!socket_id_) {
return 1;
}
// Accept the first connection we get.
xe_socket_connection_t client_info;
if (xe_socket_accept(socket_id_, &client_info)) {
return 1;
}
XELOGI("GDB debugger connected from %s", client_info.addr);
// Create the client object.
// Note that the client will delete itself when done.
GDBClient* client = new GDBClient(debug_server_, client_info.socket);
if (client->Setup()) {
// Client failed to setup - abort.
return 1;
}
thread_ = xe_thread_create("GDB Debugger Listener", StartCallback, this);
running_ = true;
return xe_thread_start(thread_);
return 0;
}
void GDBProtocol::StartCallback(void* param) {
GDBProtocol* protocol = reinterpret_cast<GDBProtocol*>(param);
protocol->AcceptThread();
}
void GDBProtocol::AcceptThread() {
while (running_) {
if (!socket_id_) {
break;
}
// Accept the first connection we get.
xe_socket_connection_t client_info;
if (xe_socket_accept(socket_id_, &client_info)) {
XELOGE("WS debugger failed to accept connection");
break;
}
XELOGI("WS debugger connected from %s", client_info.addr);
// Create the client object.
// Note that the client will delete itself when done.
GDBClient* client = new GDBClient(debug_server_, client_info.socket);
if (client->Setup()) {
// Client failed to setup - abort.
continue;
}
}
}

View File

@ -31,12 +31,18 @@ public:
virtual ~GDBProtocol();
virtual int Setup();
virtual int WaitForClient();
private:
static void StartCallback(void* param);
void AcceptThread();
protected:
uint32_t port_;
socket_t socket_id_;
xe_thread_ref thread_;
bool running_;
};

View File

@ -9,6 +9,7 @@
#include <xenia/debug/protocols/ws/ws_protocol.h>
#include <xenia/debug/debug_server.h>
#include <xenia/debug/protocols/ws/ws_client.h>
#include <gflags/gflags.h>
@ -25,7 +26,6 @@ DEFINE_int32(ws_debug_port, 6200,
WSProtocol::WSProtocol(DebugServer* debug_server) :
port_(0), socket_id_(0), thread_(0), running_(false),
accepted_event_(INVALID_HANDLE_VALUE),
Protocol(debug_server) {
port_ = FLAGS_ws_debug_port;
}
@ -37,9 +37,6 @@ WSProtocol::~WSProtocol() {
xe_thread_release(thread_);
thread_ = 0;
}
if (accepted_event_ != INVALID_HANDLE_VALUE) {
CloseHandle(accepted_event_);
}
if (socket_id_) {
xe_socket_close(socket_id_);
}
@ -71,8 +68,6 @@ int WSProtocol::Setup() {
return 1;
}
accepted_event_ = CreateEvent(NULL, FALSE, FALSE, NULL);
thread_ = xe_thread_create("WS Debugger Listener", StartCallback, this);
running_ = true;
return xe_thread_start(thread_);
@ -105,12 +100,5 @@ void WSProtocol::AcceptThread() {
// Client failed to setup - abort.
continue;
}
SetEvent(accepted_event_);
}
}
int WSProtocol::WaitForClient() {
WaitForSingleObject(accepted_event_, INFINITE);
return 0;
}

View File

@ -31,7 +31,6 @@ public:
virtual ~WSProtocol();
virtual int Setup();
virtual int WaitForClient();
private:
static void StartCallback(void* param);
@ -44,7 +43,6 @@ protected:
xe_thread_ref thread_;
bool running_;
HANDLE accepted_event_;
};