Debugger now listens for connections and will only allow one at a time.
This commit is contained in:
parent
597e196940
commit
1461792289
|
@ -231,6 +231,7 @@ void xe_socket_loop_destroy(xe_socket_loop_t* loop) {
|
|||
int xe_socket_loop_poll(xe_socket_loop_t* loop,
|
||||
bool check_read, bool check_write) {
|
||||
// Prep events object.
|
||||
loop->events[0].events = 0;
|
||||
if (check_read) {
|
||||
loop->events[0].events |= POLLIN;
|
||||
}
|
||||
|
|
|
@ -27,6 +27,7 @@ public:
|
|||
virtual ~DebugClient();
|
||||
|
||||
virtual int Setup() = 0;
|
||||
virtual void Close() = 0;
|
||||
|
||||
protected:
|
||||
DebugServer* debug_server_;
|
||||
|
|
|
@ -27,15 +27,20 @@ DEFINE_bool(wait_for_debugger, false,
|
|||
|
||||
|
||||
DebugServer::DebugServer(Emulator* emulator) :
|
||||
emulator_(emulator) {
|
||||
protocols_.push_back(
|
||||
new protocols::gdb::GDBProtocol(this));
|
||||
emulator_(emulator), lock_(0) {
|
||||
lock_ = xe_mutex_alloc(10000);
|
||||
|
||||
//protocols_.push_back(
|
||||
// new protocols::ws::WSProtocol(this));
|
||||
// new protocols::gdb::GDBProtocol(this));
|
||||
protocols_.push_back(
|
||||
new protocols::ws::WSProtocol(this));
|
||||
}
|
||||
|
||||
DebugServer::~DebugServer() {
|
||||
Shutdown();
|
||||
|
||||
xe_free(lock_);
|
||||
lock_ = 0;
|
||||
}
|
||||
|
||||
int DebugServer::Startup() {
|
||||
|
@ -67,6 +72,8 @@ int DebugServer::Startup() {
|
|||
}
|
||||
|
||||
void DebugServer::Shutdown() {
|
||||
xe_mutex_lock(lock_);
|
||||
|
||||
std::vector<DebugClient*> clients(clients_.begin(), clients_.end());
|
||||
clients_.clear();
|
||||
for (std::vector<DebugClient*>::iterator it = clients.begin();
|
||||
|
@ -80,18 +87,35 @@ void DebugServer::Shutdown() {
|
|||
it != protocols.end(); ++it) {
|
||||
delete *it;
|
||||
}
|
||||
|
||||
xe_mutex_unlock(lock_);
|
||||
}
|
||||
|
||||
void DebugServer::AddClient(DebugClient* debug_client) {
|
||||
xe_mutex_lock(lock_);
|
||||
|
||||
// Only one debugger at a time right now. Kill any old one.
|
||||
while (clients_.size()) {
|
||||
DebugClient* old_client = clients_.back();
|
||||
clients_.pop_back();
|
||||
old_client->Close();
|
||||
}
|
||||
|
||||
clients_.push_back(debug_client);
|
||||
|
||||
xe_mutex_unlock(lock_);
|
||||
}
|
||||
|
||||
void DebugServer::RemoveClient(DebugClient* debug_client) {
|
||||
xe_mutex_lock(lock_);
|
||||
|
||||
for (std::vector<DebugClient*>::iterator it = clients_.begin();
|
||||
it != clients_.end(); ++it) {
|
||||
if (*it == debug_client) {
|
||||
clients_.erase(it);
|
||||
return;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
xe_mutex_unlock(lock_);
|
||||
}
|
||||
|
|
|
@ -42,6 +42,8 @@ private:
|
|||
private:
|
||||
Emulator* emulator_;
|
||||
std::vector<Protocol*> protocols_;
|
||||
|
||||
xe_mutex_t* lock_;
|
||||
std::vector<DebugClient*> clients_;
|
||||
};
|
||||
|
||||
|
|
|
@ -68,6 +68,11 @@ int GDBClient::Setup() {
|
|||
return xe_thread_start(thread_);
|
||||
}
|
||||
|
||||
void GDBClient::Close() {
|
||||
xe_socket_close(socket_id_);
|
||||
socket_id_ = 0;
|
||||
}
|
||||
|
||||
void GDBClient::StartCallback(void* param) {
|
||||
GDBClient* client = reinterpret_cast<GDBClient*>(param);
|
||||
client->EventThread();
|
||||
|
|
|
@ -35,6 +35,7 @@ public:
|
|||
socket_t socket_id() const { return socket_id_; }
|
||||
|
||||
virtual int Setup();
|
||||
virtual void Close();
|
||||
|
||||
private:
|
||||
static void StartCallback(void* param);
|
||||
|
|
|
@ -61,6 +61,11 @@ int WSClient::Setup() {
|
|||
return xe_thread_start(thread_);
|
||||
}
|
||||
|
||||
void WSClient::Close() {
|
||||
xe_socket_close(socket_id_);
|
||||
socket_id_ = 0;
|
||||
}
|
||||
|
||||
void WSClient::StartCallback(void* param) {
|
||||
WSClient* client = reinterpret_cast<WSClient*>(param);
|
||||
client->EventThread();
|
||||
|
@ -305,6 +310,7 @@ void WSClient::EventThread() {
|
|||
}
|
||||
|
||||
wslay_event_context_free(ctx);
|
||||
delete this;
|
||||
}
|
||||
|
||||
void WSClient::Write(uint8_t** buffers, size_t* lengths, size_t count) {
|
||||
|
|
|
@ -35,6 +35,7 @@ public:
|
|||
socket_t socket_id() const { return socket_id_; }
|
||||
|
||||
virtual int Setup();
|
||||
virtual void Close();
|
||||
|
||||
void Write(uint8_t** buffers, size_t* lengths, size_t count);
|
||||
|
||||
|
|
|
@ -24,11 +24,22 @@ 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;
|
||||
}
|
||||
|
||||
WSProtocol::~WSProtocol() {
|
||||
if (thread_) {
|
||||
// Join thread.
|
||||
running_ = false;
|
||||
xe_thread_release(thread_);
|
||||
thread_ = 0;
|
||||
}
|
||||
if (accepted_event_ != INVALID_HANDLE_VALUE) {
|
||||
CloseHandle(accepted_event_);
|
||||
}
|
||||
if (socket_id_) {
|
||||
xe_socket_close(socket_id_);
|
||||
}
|
||||
|
@ -60,18 +71,29 @@ int WSProtocol::Setup() {
|
|||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
accepted_event_ = CreateEvent(NULL, FALSE, FALSE, NULL);
|
||||
|
||||
thread_ = xe_thread_create("WS Debugger Listener", StartCallback, this);
|
||||
running_ = true;
|
||||
return xe_thread_start(thread_);
|
||||
}
|
||||
|
||||
int WSProtocol::WaitForClient() {
|
||||
void WSProtocol::StartCallback(void* param) {
|
||||
WSProtocol* protocol = reinterpret_cast<WSProtocol*>(param);
|
||||
protocol->AcceptThread();
|
||||
}
|
||||
|
||||
void WSProtocol::AcceptThread() {
|
||||
while (running_) {
|
||||
if (!socket_id_) {
|
||||
return 1;
|
||||
break;
|
||||
}
|
||||
|
||||
// Accept the first connection we get.
|
||||
xe_socket_connection_t client_info;
|
||||
if (xe_socket_accept(socket_id_, &client_info)) {
|
||||
return 1;
|
||||
XELOGE("WS debugger failed to accept connection");
|
||||
break;
|
||||
}
|
||||
|
||||
XELOGI("WS debugger connected from %s", client_info.addr);
|
||||
|
@ -81,8 +103,14 @@ int WSProtocol::WaitForClient() {
|
|||
WSClient* client = new WSClient(debug_server_, client_info.socket);
|
||||
if (client->Setup()) {
|
||||
// Client failed to setup - abort.
|
||||
return 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
SetEvent(accepted_event_);
|
||||
}
|
||||
}
|
||||
|
||||
int WSProtocol::WaitForClient() {
|
||||
WaitForSingleObject(accepted_event_, INFINITE);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -33,10 +33,18 @@ public:
|
|||
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_;
|
||||
HANDLE accepted_event_;
|
||||
};
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue