|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#include "OutputHandler.h" |
|
|
|
#include <assert.h> |
|
#include <errno.h> |
|
#include <sys/select.h> |
|
#include <unistd.h> |
|
|
|
#include <algorithm> |
|
#include <vector> |
|
|
|
#include "../shared/DebugClient.h" |
|
#include "Util.h" |
|
#include "WakeupFd.h" |
|
|
|
OutputHandler::OutputHandler( |
|
HANDLE conout, int outputfd, WakeupFd &completionWakeup) : |
|
m_conout(conout), |
|
m_outputfd(outputfd), |
|
m_completionWakeup(completionWakeup), |
|
m_threadHasBeenJoined(false), |
|
m_threadCompleted(0) |
|
{ |
|
pthread_create(&m_thread, NULL, OutputHandler::threadProcS, this); |
|
} |
|
|
|
void OutputHandler::shutdown() { |
|
if (!m_threadHasBeenJoined) { |
|
int ret = pthread_join(m_thread, NULL); |
|
assert(ret == 0 && "pthread_join failed"); |
|
m_threadHasBeenJoined = true; |
|
} |
|
} |
|
|
|
void OutputHandler::threadProc() { |
|
std::vector<char> buffer(4096); |
|
while (true) { |
|
DWORD numRead = 0; |
|
BOOL ret = ReadFile(m_conout, |
|
&buffer[0], buffer.size(), |
|
&numRead, NULL); |
|
if (!ret || numRead == 0) { |
|
if (!ret && GetLastError() == ERROR_BROKEN_PIPE) { |
|
trace("OutputHandler: pipe closed: numRead=%u", |
|
static_cast<unsigned int>(numRead)); |
|
} else { |
|
trace("OutputHandler: read failed: " |
|
"ret=%d lastError=0x%x numRead=%u", |
|
ret, |
|
static_cast<unsigned int>(GetLastError()), |
|
static_cast<unsigned int>(numRead)); |
|
} |
|
break; |
|
} |
|
if (!writeAll(m_outputfd, &buffer[0], numRead)) { |
|
break; |
|
} |
|
} |
|
m_threadCompleted = 1; |
|
m_completionWakeup.set(); |
|
} |
|
|