diff --git a/src/gui/src/IpcReader.cpp b/src/gui/src/IpcReader.cpp index df0d3d0f..1e7f2551 100644 --- a/src/gui/src/IpcReader.cpp +++ b/src/gui/src/IpcReader.cpp @@ -22,7 +22,8 @@ #include IpcReader::IpcReader(QTcpSocket* socket) : -m_Socket(socket) +m_Socket(socket), +m_ReadyRead(false) { connect(socket, SIGNAL(readyRead()), this, SLOT(readyRead())); } @@ -34,7 +35,7 @@ IpcReader::~IpcReader() void IpcReader::readyRead() { std::cout << "ready read" << std::endl; - m_Ready.wakeAll(); + m_ReadyRead = true; } void IpcReader::run() @@ -60,7 +61,7 @@ void IpcReader::run() } default: - std::cerr << "aborting, message invalid: " << codeBuf[0] << std::endl; + std::cerr << "aborting, message invalid: " << (unsigned int)codeBuf[0] << std::endl; return; } } @@ -68,9 +69,6 @@ void IpcReader::run() void IpcReader::readStream(char* buffer, int length) { - QMutex mutex; - mutex.lock(); - QDataStream stream(m_Socket); std::cout << "reading stream" << std::endl; @@ -81,7 +79,14 @@ void IpcReader::readStream(char* buffer, int length) if (got == 0) { std::cout << "end of buffer, waiting" << std::endl; - m_Ready.wait(&mutex); + + // i'd love nothing more than to use a wait condition here, but + // qt is such a fucker with mutexes (can't lock/unlock between + // threads?! wtf?!). i'd just rather not go there (patches welcome). + while (!m_ReadyRead) { + QThread::usleep(100); + } + m_ReadyRead = false; } else if (got == -1) { std::cout << "socket ended, aborting" << std::endl; diff --git a/src/gui/src/IpcReader.h b/src/gui/src/IpcReader.h index 95ae6998..13684cba 100644 --- a/src/gui/src/IpcReader.h +++ b/src/gui/src/IpcReader.h @@ -18,7 +18,6 @@ #pragma once #include -#include class QTcpSocket; @@ -44,5 +43,5 @@ private slots: private: QTcpSocket* m_Socket; - QWaitCondition m_Ready; + bool m_ReadyRead; }; diff --git a/src/lib/base/CLog.h b/src/lib/base/CLog.h index 928d156d..54dfbd99 100644 --- a/src/lib/base/CLog.h +++ b/src/lib/base/CLog.h @@ -114,7 +114,8 @@ public: static CLog* getInstance(); //! Get the console filter level (messages above this are not sent to console). - int getConsoleMaxLevel() const { return kDEBUG1; } + int getConsoleMaxLevel() const { return kDEBUG2; } + //@} private: diff --git a/src/lib/ipc/CIpcLogOutputter.cpp b/src/lib/ipc/CIpcLogOutputter.cpp index b0556b4f..408bb292 100644 --- a/src/lib/ipc/CIpcLogOutputter.cpp +++ b/src/lib/ipc/CIpcLogOutputter.cpp @@ -61,7 +61,13 @@ CIpcLogOutputter::show(bool showIfEmpty) } bool -CIpcLogOutputter::write(ELevel, const char* text) +CIpcLogOutputter::write(ELevel level, const char* text) +{ + return write(level, text, false); +} + +bool +CIpcLogOutputter::write(ELevel, const char* text, bool force) { // sending the buffer generates log messages, which we must throw // away (otherwise this would cause recursion). this is just a drawback @@ -69,7 +75,7 @@ CIpcLogOutputter::write(ELevel, const char* text) // away log messages not generated by the ipc, but it seems like it // would be difficult to distinguish (other than looking at the stack // trace somehow). perhaps a file stream might be a better option :-/ - if (m_sending) { + if (m_sending && !force) { return true; } diff --git a/src/lib/ipc/CIpcLogOutputter.h b/src/lib/ipc/CIpcLogOutputter.h index 5e17c566..5f1ca576 100644 --- a/src/lib/ipc/CIpcLogOutputter.h +++ b/src/lib/ipc/CIpcLogOutputter.h @@ -38,6 +38,7 @@ public: virtual void close(); virtual void show(bool showIfEmpty); virtual bool write(ELevel level, const char* message); + virtual bool write(ELevel level, const char* text, bool force); private: void bufferThread(void*); diff --git a/src/lib/platform/CMSWindowsRelauncher.cpp b/src/lib/platform/CMSWindowsRelauncher.cpp index 04780798..ca61642a 100644 --- a/src/lib/platform/CMSWindowsRelauncher.cpp +++ b/src/lib/platform/CMSWindowsRelauncher.cpp @@ -414,9 +414,11 @@ CMSWindowsRelauncher::outputLoop(void*) ARCH->sleep(1); } else { - // send process output over IPC to GUI. buffer[bytesRead] = '\0'; - m_ipcLogOutputter.write(kINFO, buffer); + + // send process output over IPC to GUI, and force it to be sent + // which bypasses the ipc logging anti-recursion mechanism. + m_ipcLogOutputter.write(kINFO, buffer, true); } }