From 00298ab24823a8cf922b693492929eac4ea71180 Mon Sep 17 00:00:00 2001
From: Friedemann Kleint <Friedemann.Kleint@nokia.com>
Date: Wed, 4 Nov 2009 15:19:02 +0100
Subject: [PATCH] WinGuiProcess: Fix hang if binary cannot be found.

..occurring in conjunction with custom run configuration
and S60 emulator. Ensure all handles are closed even
if start attempt failed.
Reviewed-by: con <qtc-committer@nokia.com>
---
 src/plugins/projectexplorer/winguiprocess.cpp | 123 ++++++++++--------
 src/plugins/projectexplorer/winguiprocess.h   |   3 +
 2 files changed, 69 insertions(+), 57 deletions(-)

diff --git a/src/plugins/projectexplorer/winguiprocess.cpp b/src/plugins/projectexplorer/winguiprocess.cpp
index 961a352dbe6..71ea57a749f 100644
--- a/src/plugins/projectexplorer/winguiprocess.cpp
+++ b/src/plugins/projectexplorer/winguiprocess.cpp
@@ -101,72 +101,81 @@ void WinGuiProcess::run()
     ZeroMemory(m_pid, sizeof(PROCESS_INFORMATION));
 
     m_exitCode = 0;
+    bool started = false;
 
     HANDLE bufferReadyEvent = NULL;
     HANDLE dataReadyEvent = NULL;
     HANDLE sharedFile = NULL;
-    LPVOID sharedMem = NULL;
-
-    bool dbgInterface = setupDebugInterface(bufferReadyEvent, dataReadyEvent, sharedFile, sharedMem);
-
-    QString cmdLine = createWinCommandline(m_program, m_args);
-    bool success = CreateProcessW(0, (WCHAR*)cmdLine.utf16(),
-                                  0, 0, TRUE, CREATE_UNICODE_ENVIRONMENT,
-                                  environment().isEmpty() ? 0
-                                  : createWinEnvironment(fixWinEnvironment(environment())).data(),
-                                  workingDirectory().isEmpty() ? 0
-                                  : (WCHAR*)QDir::convertSeparators(workingDirectory()).utf16(),
-                                  &si, m_pid);
-
-    if (!success) {
-        emit processError(tr("The process could not be started!"));
-        delete m_pid;
-        m_pid = 0;
-        return;
-    }
+    LPVOID sharedMem = 0;
 
-    if (!dbgInterface) {
-        emit receivedDebugOutput(tr("Cannot retrieve debugging output!"));
-        WaitForSingleObject(m_pid->hProcess, INFINITE);
-    } else {
-        LPSTR  message;
-        LPDWORD processId;
-        HANDLE toWaitFor[2];
-
-        message = reinterpret_cast<LPSTR>(sharedMem) + sizeof(DWORD);
-        processId = reinterpret_cast<LPDWORD>(sharedMem);
-
-        SetEvent(bufferReadyEvent);
-
-        toWaitFor[0] = dataReadyEvent;
-        toWaitFor[1] = m_pid->hProcess;
-
-        for (bool stop = false; !stop;) {
-            DWORD ret = WaitForMultipleObjects(2, toWaitFor, FALSE, INFINITE);
-
-            switch (ret) {
-            case WAIT_OBJECT_0 + 0:
-                if (*processId == m_pid->dwProcessId)
-                    emit receivedDebugOutput(QString::fromLocal8Bit(message));
-                SetEvent(bufferReadyEvent);
-                break;
-            case WAIT_OBJECT_0 + 1:
-                stop = true;
-                break;
-            }
+    do {
+
+        const bool dbgInterface = setupDebugInterface(bufferReadyEvent, dataReadyEvent, sharedFile, sharedMem);
+
+        const QString cmdLine = createWinCommandline(m_program, m_args);
+        started = CreateProcessW(0, (WCHAR*)cmdLine.utf16(),
+                                      0, 0, TRUE, CREATE_UNICODE_ENVIRONMENT,
+                                      environment().isEmpty() ? 0
+                                          : createWinEnvironment(fixWinEnvironment(environment())).data(),
+                                          workingDirectory().isEmpty() ? 0
+                                              : (WCHAR*)QDir::convertSeparators(workingDirectory()).utf16(),
+                                              &si, m_pid);
+
+        if (!started) {
+            emit processError(tr("The process could not be started!"));
+            break;
         }
-    }
 
-    GetExitCodeProcess(m_pid->hProcess, &m_exitCode);
-    emit processFinished(static_cast<int>(m_exitCode));
+        if (!dbgInterface) {
+            emit receivedDebugOutput(tr("Cannot retrieve debugging output!"));
+            WaitForSingleObject(m_pid->hProcess, INFINITE);
+        } else {
+            LPSTR  message;
+            LPDWORD processId;
+            HANDLE toWaitFor[2];
+
+            message = reinterpret_cast<LPSTR>(sharedMem) + sizeof(DWORD);
+            processId = reinterpret_cast<LPDWORD>(sharedMem);
+
+            SetEvent(bufferReadyEvent);
+
+            toWaitFor[0] = dataReadyEvent;
+            toWaitFor[1] = m_pid->hProcess;
+
+            for (bool stop = false; !stop;) {
+                DWORD ret = WaitForMultipleObjects(2, toWaitFor, FALSE, INFINITE);
+
+                switch (ret) {
+                case WAIT_OBJECT_0 + 0:
+                    if (*processId == m_pid->dwProcessId)
+                        emit receivedDebugOutput(QString::fromLocal8Bit(message));
+                    SetEvent(bufferReadyEvent);
+                    break;
+                case WAIT_OBJECT_0 + 1:
+                    stop = true;
+                    break;
+                }
+            }
+        }
+    } while (false);
 
-    UnmapViewOfFile(sharedMem);
-    CloseHandle(sharedFile);
-    CloseHandle(bufferReadyEvent);
-    CloseHandle(dataReadyEvent);
-    CloseHandle(m_pid->hProcess);
-    CloseHandle(m_pid->hThread);
+    if (started) {
+        GetExitCodeProcess(m_pid->hProcess, &m_exitCode);
+        emit processFinished(static_cast<int>(m_exitCode));
+    }
 
+    if (sharedMem)
+        UnmapViewOfFile(sharedMem);
+    if (sharedFile != NULL)
+        CloseHandle(sharedFile);
+    if (bufferReadyEvent != NULL)
+        CloseHandle(bufferReadyEvent);
+    if (dataReadyEvent != NULL)
+        CloseHandle(dataReadyEvent);
+    if (m_pid->hProcess != NULL)
+        CloseHandle(m_pid->hProcess);
+    if  (m_pid->hThread != NULL)
+        CloseHandle(m_pid->hThread);
     delete m_pid;
     m_pid = 0;
 }
diff --git a/src/plugins/projectexplorer/winguiprocess.h b/src/plugins/projectexplorer/winguiprocess.h
index 460651ff12c..c3ffee1e772 100644
--- a/src/plugins/projectexplorer/winguiprocess.h
+++ b/src/plugins/projectexplorer/winguiprocess.h
@@ -42,6 +42,9 @@ using namespace Utils;
 namespace ProjectExplorer {
 namespace Internal {
 
+/* Captures the debug output of a Windows GUI application (which
+ * would otherwise not be visible) using the debug interface and
+ * emits via a signal. */
 class WinGuiProcess : public QThread, public AbstractProcess
 {
     Q_OBJECT
-- 
GitLab