1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152
|
#include "XDebugCommThread.h"
#include "XDebugManager.h"
#include <wx/buffer.h>
#include <file_logger.h>
#include <string>
#include <wx/log.h>
void XDebugComThread::SendMsg(const wxString& msg) { m_queue.Post(msg); }
XDebugComThread::~XDebugComThread() { Stop(); }
void XDebugComThread::Stop()
{
if(IsAlive()) {
Delete(NULL, wxTHREAD_WAIT_BLOCK);
} else {
Wait(wxTHREAD_WAIT_BLOCK);
}
}
void* XDebugComThread::Entry()
{
clDEBUG() << "CodeLite >>> XDebugComThread started" << clEndl;
//----------------------------------------------------------------
// Start the debugger server and wait for XDebug to connect to us
//----------------------------------------------------------------
clSocketBase::Ptr_t client;
int retry(0);
try {
wxString connectionString;
connectionString << "tcp://" << m_host << ":" << m_port;
clDEBUG() << "CodeLite >>> Creating server on:" << connectionString << clEndl;
m_server.Start(connectionString);
clDEBUG() << "CodeLite >>> Listening on" << m_host << ":" << m_port << clEndl;
// Wait for new connection (up to m_waitForConnTimeout seconds, which defaults to 5 seconds )
do {
if((m_waitForConnTimeout > 0) && (retry > m_waitForConnTimeout)) {
// Don't wait any longer for XDebug
m_xdebugMgr->CallAfter(&XDebugManager::XDebugNotConnecting);
return NULL;
}
client = m_server.WaitForNewConnection(1);
++retry;
clDEBUG() << "CodeLite >>> Waiting for connection.." << clEndl;
} while(!TestDestroy() && !client);
CL_DEBUG("CodeLite >>> Successfully accepted connection from XDebug!");
m_xdebugMgr->CallAfter(&XDebugManager::SetConnected, true);
//----------------------------------------------------------------
// Protocol:
// First we read the init XML
//----------------------------------------------------------------
std::string initXML;
if(DoReadReply(initXML, client)) {
m_xdebugMgr->CallAfter(&XDebugManager::OnSocketInput, initXML);
} else {
// Something bad happened
m_xdebugMgr->CallAfter(&XDebugManager::OnCommThreadTerminated);
return NULL;
}
// The main loop: request-reply mode
while(!TestDestroy()) {
wxString command;
if(m_queue.ReceiveTimeout(20, command) == wxMSGQUEUE_NO_ERROR) {
DoSendCommand(command, client);
// Wait for the reply
std::string reply;
if(!DoReadReply(reply, client)) {
// AN error occurred - close session
break;
}
// Notify XDebugManager
m_xdebugMgr->CallAfter(&XDebugManager::OnSocketInput, reply);
}
}
} catch(clSocketException& e) {
CL_DEBUG("XDebugComThread caught an exception: %s", e.what());
m_xdebugMgr->CallAfter(&XDebugManager::OnCommThreadTerminated);
return NULL;
}
m_xdebugMgr->CallAfter(&XDebugManager::OnCommThreadTerminated);
return NULL;
}
bool XDebugComThread::DoReadReply(std::string& reply, clSocketBase::Ptr_t client)
{
if(!client) {
return false;
}
try {
// Read the data length
wxString length;
while(true) {
char c = 0;
size_t count = 0;
client->Read(&c, 1, count);
if(c == 0) {
break;
}
length << c;
}
long dataLengh(0);
if(!length.ToCLong(&dataLengh)) {
// session terminated!
return false;
}
// Read the actual buffer
++dataLengh; // +1 for NULL
char* buffer = new char[dataLengh];
memset(buffer, 0, dataLengh);
size_t actualSize(0);
client->Read(buffer, dataLengh, actualSize);
std::string content(buffer, dataLengh);
reply.swap(content);
wxDELETEA(buffer);
} catch(clSocketException& e) {
wxUnusedVar(e);
return false;
}
return true;
}
void XDebugComThread::DoSendCommand(const wxString& command, clSocketBase::Ptr_t client)
{
// got message, process it
if(!client) {
return;
}
CL_DEBUGS(wxString() << "CodeLite >>> " << command);
wxMemoryBuffer buff;
buff.AppendData(command.mb_str(wxConvISO8859_1), command.length());
buff.AppendByte(0);
std::string cmd((const char*)buff.GetData(), buff.GetDataLen());
client->Send(cmd);
}
|