OSDN Git Service

WinDebugInterface: Remove windows.h from header, resource cleanup.
authorFriedemann Kleint <Friedemann.Kleint@nokia.com>
Wed, 20 Apr 2011 08:12:17 +0000 (10:12 +0200)
committerFriedemann Kleint <Friedemann.Kleint@nokia.com>
Wed, 20 Apr 2011 08:13:05 +0000 (10:13 +0200)
Proper termination.

src/plugins/projectexplorer/windebuginterface.cpp
src/plugins/projectexplorer/windebuginterface.h
src/plugins/projectexplorer/winguiprocess.cpp

index 3fc4c2d..d4f732a 100644 (file)
 
 #include "windebuginterface.h"
 
+#include <windows.h>
+
+/*!
+    \class ProjectExplorer::Internal::WinDebugInterface
+    \brief Windows: Captures output of the Windows API OutputDebugString() function.
+
+    Emits output by process id.
+
+    OutputDebugString puts its data into a shared memory segment named
+    \c DBWIN_BUFFER which can be accessed via file mapping.
+
+    \sa ProjectExplorer::Internal::WinGuiProcess
+*/
+
 namespace ProjectExplorer {
 namespace Internal {
 
@@ -42,58 +56,80 @@ WinDebugInterface *WinDebugInterface::instance()
     return m_instance;
 }
 
-
 WinDebugInterface::WinDebugInterface(QObject *parent) :
     QThread(parent)
 {
     m_instance = this;
+    setObjectName(QLatin1String("WinDebugInterfaceThread"));
     start();
 }
 
 WinDebugInterface::~WinDebugInterface()
 {
-    terminate(); // Creator is shutting down anyway, no need to clean up.
-    wait(500);
+    if (m_waitHandles[TerminateEventHandle]) {
+        SetEvent(m_waitHandles[TerminateEventHandle]);
+        wait(500);
+    }
+    m_instance = 0;
 }
 
 void WinDebugInterface::run()
 {
-    HANDLE bufferReadyEvent = CreateEvent(NULL, FALSE, FALSE, L"DBWIN_BUFFER_READY");
-    if (!bufferReadyEvent)
-        return;
-    HANDLE dataReadyEvent = CreateEvent(NULL, FALSE, FALSE, L"DBWIN_DATA_READY");
-    if (!dataReadyEvent) {
-        CloseHandle(bufferReadyEvent);
-        return;
+    m_waitHandles[DataReadyEventHandle] = m_waitHandles[TerminateEventHandle] = 0;
+    m_bufferReadyEvent = 0;
+    m_sharedFile = 0;
+    m_sharedMem  = 0;
+    runLoop();
+    if (m_sharedMem) {
+        UnmapViewOfFile(m_sharedMem);
+        m_sharedMem = 0;
     }
-    HANDLE sharedFile = CreateFileMapping((HANDLE)-1, NULL, PAGE_READWRITE, 0, 4096, L"DBWIN_BUFFER");
-    if (!sharedFile) {
-        CloseHandle(dataReadyEvent);
-        CloseHandle(bufferReadyEvent);
-        return;
+    if (m_sharedFile) {
+        CloseHandle(m_sharedFile);
+        m_sharedFile = 0;
     }
-    LPVOID sharedMem = MapViewOfFile(sharedFile, FILE_MAP_READ, 0, 0,  512);
-    if (!sharedMem) {
-        CloseHandle(sharedFile);
-        CloseHandle(dataReadyEvent);
-        CloseHandle(bufferReadyEvent);
-        return;
+    if (m_waitHandles[TerminateEventHandle]) {
+        CloseHandle(m_waitHandles[TerminateEventHandle]);
+        m_waitHandles[TerminateEventHandle] = 0;
+    }
+    if (m_waitHandles[DataReadyEventHandle]) {
+        CloseHandle(m_waitHandles[DataReadyEventHandle]);
+        m_waitHandles[DataReadyEventHandle] = 0;
+    }
+    if (m_bufferReadyEvent) {
+        CloseHandle(m_bufferReadyEvent);
+        m_bufferReadyEvent = 0;
     }
+}
 
-    LPSTR  message;
-    LPDWORD processId;
+void WinDebugInterface::runLoop()
+{
+    m_waitHandles[TerminateEventHandle] = CreateEvent(NULL, FALSE, FALSE, NULL);
+    m_waitHandles[DataReadyEventHandle] = CreateEvent(NULL, FALSE, FALSE, L"DBWIN_DATA_READY");
+    if (!m_waitHandles[TerminateEventHandle] || !m_waitHandles[DataReadyEventHandle])
+        return;
+    m_bufferReadyEvent = CreateEvent(NULL, FALSE, FALSE, L"DBWIN_BUFFER_READY");
+    if (!m_bufferReadyEvent)
+        return;
+    m_sharedFile = CreateFileMapping((HANDLE)-1, NULL, PAGE_READWRITE, 0, 4096, L"DBWIN_BUFFER");
+    if (!m_sharedFile)
+        return;
+    m_sharedMem = MapViewOfFile(m_sharedFile, FILE_MAP_READ, 0, 0,  512);
+    if (!m_sharedMem)
+        return;
 
-    message = reinterpret_cast<LPSTR>(sharedMem) + sizeof(DWORD);
-    processId = reinterpret_cast<LPDWORD>(sharedMem);
+    LPSTR  message = reinterpret_cast<LPSTR>(m_sharedMem) + sizeof(DWORD);
+    LPDWORD processId = reinterpret_cast<LPDWORD>(m_sharedMem);
 
-    SetEvent(bufferReadyEvent);
+    SetEvent(m_bufferReadyEvent);
 
     while (true) {
-        DWORD ret = WaitForSingleObject(dataReadyEvent, INFINITE);
-
-        if (ret == WAIT_OBJECT_0) {
+        const DWORD ret = WaitForMultipleObjects(HandleCount, m_waitHandles, FALSE, INFINITE);
+        if (ret == WAIT_FAILED || ret - WAIT_OBJECT_0 == TerminateEventHandle)
+            break;
+        if (ret - WAIT_OBJECT_0 == DataReadyEventHandle) {
             emit debugOutput(*processId, QString::fromLocal8Bit(message));
-            SetEvent(bufferReadyEvent);
+            SetEvent(m_bufferReadyEvent);
         }
     }
 }
index a51d0a4..18b81dd 100644 (file)
@@ -35,8 +35,6 @@
 
 #include <QtCore/QThread>
 
-#include <windows.h>
-
 namespace ProjectExplorer {
 namespace Internal {
 
@@ -54,9 +52,17 @@ signals:
     void debugOutput(qint64 pid, const QString &message);
 
 private:
+    enum Handles { DataReadyEventHandle, TerminateEventHandle, HandleCount };
+
     void run();
+    void runLoop();
 
     static WinDebugInterface *m_instance;
+
+    Qt::HANDLE m_waitHandles[HandleCount];
+    Qt::HANDLE m_bufferReadyEvent;
+    Qt::HANDLE m_sharedFile;
+    void *m_sharedMem;
 };
 
 } // namespace Internal
index 8dd79ed..2267281 100644 (file)
@@ -47,6 +47,8 @@ using namespace ProjectExplorer::Internal;
 
     The output of a Windows GUI application would otherwise not be
     visible. Uses the debug interface and emits via a signal.
+
+    \sa ProjectExplorer::Internal::WinDebugInterface
 */
 
 WinGuiProcess::WinGuiProcess(QObject *parent) :