Windows/DebugOutput: Check that only one process reads output

Only one process can attach to the system wide application output
buffer. Re-add checks that makes sure we don't try to attach
as second one.

Change-Id: Ic50b43b8d0ac58d792075b59ecb3e490fdb75df8
Reviewed-on: http://codereview.qt.nokia.com/827
Reviewed-by: Qt Sanity Bot <qt_sanity_bot@ovi.com>
Reviewed-by: Tobias Hunger <tobias.hunger@nokia.com>
This commit is contained in:
Kai Koehne
2011-06-28 12:40:25 +02:00
committed by Tobias Hunger
parent 2d4b5fcb65
commit 7827af9712
4 changed files with 25 additions and 12 deletions

View File

@@ -117,6 +117,8 @@ ApplicationLauncher::ApplicationLauncher(QObject *parent)
this, SLOT(processStopped())); this, SLOT(processStopped()));
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
connect(WinDebugInterface::instance(), SIGNAL(cannotRetrieveDebugOutput()),
this, SLOT(cannotRetrieveDebugOutput()));
connect(WinDebugInterface::instance(), SIGNAL(debugOutput(qint64,QString)), connect(WinDebugInterface::instance(), SIGNAL(debugOutput(qint64,QString)),
this, SLOT(checkDebugOutput(qint64,QString))); this, SLOT(checkDebugOutput(qint64,QString)));
#endif #endif
@@ -154,8 +156,6 @@ void ApplicationLauncher::start(Mode mode, const QString &program, const QString
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
if (!WinDebugInterface::instance()->isRunning()) if (!WinDebugInterface::instance()->isRunning())
WinDebugInterface::instance()->start(); // Try to start listener again... WinDebugInterface::instance()->start(); // Try to start listener again...
if (!WinDebugInterface::instance()->isRunning())
emit appendMessage(msgWinCannotRetrieveDebuggingOutput(), Utils::ErrorMessageFormat);
#endif #endif
d->m_currentMode = mode; d->m_currentMode = mode;
@@ -247,6 +247,11 @@ void ApplicationLauncher::readStandardError()
} }
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
void ApplicationLauncher::cannotRetrieveDebugOutput()
{
emit appendMessage(msgWinCannotRetrieveDebuggingOutput(), Utils::ErrorMessageFormat);
}
void ApplicationLauncher::checkDebugOutput(qint64 pid, const QString &message) void ApplicationLauncher::checkDebugOutput(qint64 pid, const QString &message)
{ {
if (applicationPID() == pid) if (applicationPID() == pid)

View File

@@ -83,6 +83,7 @@ private slots:
void readStandardOutput(); void readStandardOutput();
void readStandardError(); void readStandardError();
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
void cannotRetrieveDebugOutput();
void checkDebugOutput(qint64 pid, const QString &message); void checkDebugOutput(qint64 pid, const QString &message);
#endif #endif
void processDone(int, QProcess::ExitStatus); void processDone(int, QProcess::ExitStatus);

View File

@@ -77,7 +77,8 @@ void WinDebugInterface::run()
m_bufferReadyEvent = 0; m_bufferReadyEvent = 0;
m_sharedFile = 0; m_sharedFile = 0;
m_sharedMem = 0; m_sharedMem = 0;
runLoop(); if (!runLoop())
emit cannotRetrieveDebugOutput();
if (m_sharedMem) { if (m_sharedMem) {
UnmapViewOfFile(m_sharedMem); UnmapViewOfFile(m_sharedMem);
m_sharedMem = 0; m_sharedMem = 0;
@@ -100,21 +101,25 @@ void WinDebugInterface::run()
} }
} }
void WinDebugInterface::runLoop() bool WinDebugInterface::runLoop()
{ {
m_waitHandles[TerminateEventHandle] = CreateEvent(NULL, FALSE, FALSE, NULL); m_waitHandles[TerminateEventHandle] = CreateEvent(NULL, FALSE, FALSE, NULL);
if (GetLastError() == ERROR_ALREADY_EXISTS)
return false;
m_waitHandles[DataReadyEventHandle] = CreateEvent(NULL, FALSE, FALSE, L"DBWIN_DATA_READY"); m_waitHandles[DataReadyEventHandle] = CreateEvent(NULL, FALSE, FALSE, L"DBWIN_DATA_READY");
if (!m_waitHandles[TerminateEventHandle] || !m_waitHandles[DataReadyEventHandle]) if (!m_waitHandles[TerminateEventHandle] || !m_waitHandles[DataReadyEventHandle]
return; || GetLastError() == ERROR_ALREADY_EXISTS)
return false;
m_bufferReadyEvent = CreateEvent(NULL, FALSE, FALSE, L"DBWIN_BUFFER_READY"); m_bufferReadyEvent = CreateEvent(NULL, FALSE, FALSE, L"DBWIN_BUFFER_READY");
if (!m_bufferReadyEvent) if (!m_bufferReadyEvent
return; || GetLastError() == ERROR_ALREADY_EXISTS)
return false;
m_sharedFile = CreateFileMapping((HANDLE)-1, NULL, PAGE_READWRITE, 0, 4096, L"DBWIN_BUFFER"); m_sharedFile = CreateFileMapping((HANDLE)-1, NULL, PAGE_READWRITE, 0, 4096, L"DBWIN_BUFFER");
if (!m_sharedFile) if (!m_sharedFile || GetLastError() == ERROR_ALREADY_EXISTS)
return; return false;
m_sharedMem = MapViewOfFile(m_sharedFile, FILE_MAP_READ, 0, 0, 512); m_sharedMem = MapViewOfFile(m_sharedFile, FILE_MAP_READ, 0, 0, 512);
if (!m_sharedMem) if (!m_sharedMem)
return; return false;
LPSTR message = reinterpret_cast<LPSTR>(m_sharedMem) + sizeof(DWORD); LPSTR message = reinterpret_cast<LPSTR>(m_sharedMem) + sizeof(DWORD);
LPDWORD processId = reinterpret_cast<LPDWORD>(m_sharedMem); LPDWORD processId = reinterpret_cast<LPDWORD>(m_sharedMem);
@@ -130,6 +135,7 @@ void WinDebugInterface::runLoop()
SetEvent(m_bufferReadyEvent); SetEvent(m_bufferReadyEvent);
} }
} }
return true;
} }
} // namespace Internal } // namespace Internal

View File

@@ -50,12 +50,13 @@ public:
signals: signals:
void debugOutput(qint64 pid, const QString &message); void debugOutput(qint64 pid, const QString &message);
void cannotRetrieveDebugOutput();
private: private:
enum Handles { DataReadyEventHandle, TerminateEventHandle, HandleCount }; enum Handles { DataReadyEventHandle, TerminateEventHandle, HandleCount };
void run(); void run();
void runLoop(); bool runLoop();
static WinDebugInterface *m_instance; static WinDebugInterface *m_instance;