Fixed issues suggested by Greg.

http://reviews.llvm.org/D6036

Files:
  include/lldb/Host/HostNativeProcessBase.h
  include/lldb/Host/HostProcess.h
  include/lldb/Host/MonitoringProcessLauncher.h
  include/lldb/Host/ProcessStatusMonitor.h
  include/lldb/Host/windows/ExitStatusMonitorWindows.h
  include/lldb/Host/windows/HostProcessWindows.h
  include/lldb/lldb-forward.h
  source/Host/CMakeLists.txt
  source/Host/common/Host.cpp
  source/Host/common/HostProcess.cpp
  source/Host/common/MonitoringProcessLauncher.cpp
  source/Host/common/ProcessStatusMonitor.cpp
  source/Host/windows/ExitStatusMonitorWindows.cpp
  source/Host/windows/HostProcessWindows.cpp
  source/Host/windows/ProcessLauncherWindows.cpp
Index: include/lldb/Host/HostNativeProcessBase.h
===================================================================
--- include/lldb/Host/HostNativeProcessBase.h
+++ include/lldb/Host/HostNativeProcessBase.h
@@ -34,6 +34,12 @@
     {}
     virtual ~HostNativeProcessBase() {}
 
+    lldb::process_t
+    GetProcess() const
+    {
+        return m_process;
+    }
+
     virtual Error Terminate() = 0;
     virtual Error GetMainModule(FileSpec &file_spec) const = 0;
 
Index: include/lldb/Host/HostProcess.h
===================================================================
--- include/lldb/Host/HostProcess.h
+++ include/lldb/Host/HostProcess.h
@@ -46,6 +46,7 @@
     Error Terminate();
     Error GetMainModule(FileSpec &file_spec) const;
 
+    lldb::process_t GetProcess() const;
     lldb::pid_t GetProcessId() const;
     bool IsRunning() const;
 
Index: include/lldb/Host/MonitoringProcessLauncher.h
===================================================================
--- include/lldb/Host/MonitoringProcessLauncher.h
+++ include/lldb/Host/MonitoringProcessLauncher.h
@@ -11,6 +11,7 @@
 #define lldb_Host_MonitoringProcessLauncher_h_
 
 #include "lldb/Host/ProcessLauncher.h"
+#include "lldb/lldb-forward.h"
 
 namespace lldb_private
 {
@@ -18,12 +19,13 @@
 class MonitoringProcessLauncher : public ProcessLauncher
 {
   public:
-    explicit MonitoringProcessLauncher(std::unique_ptr<ProcessLauncher> delegate_launcher);
+    MonitoringProcessLauncher(lldb::ProcessStatusMonitorSP monitor, ProcessLauncher &delegate_launcher);
 
     virtual HostProcess LaunchProcess(const ProcessLaunchInfo &launch_info, Error &error);
 
   private:
-    std::unique_ptr<ProcessLauncher> m_delegate_launcher;
+    lldb::ProcessStatusMonitorSP m_monitor;
+    ProcessLauncher &m_delegate_launcher;
 };
 }
 
Index: include/lldb/Host/ProcessStatusMonitor.h
===================================================================
--- /dev/null
+++ include/lldb/Host/ProcessStatusMonitor.h
@@ -0,0 +1,67 @@
+//===-- ProcessStatusMonitor.h ----------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_Host_ProcessStatusMonitor_H_
+#define liblldb_Host_ProcessStatusMonitor_H_
+
+#include "lldb/Core/Error.h"
+#include "lldb/Host/HostProcess.h"
+#include "lldb/lldb-types.h"
+
+#include <list>
+#include <utility>
+
+namespace lldb_private
+{
+typedef bool (*ProcessStatusMonitorCallback)(void *baton, lldb::pid_t pid, bool exited,
+                                             int signal,  // Zero for no signal
+                                             int status); // Exit value of process if signal is zero
+
+struct ProcessStatusMonitorCallbackEntry
+{
+    ProcessStatusMonitorCallbackEntry(ProcessStatusMonitorCallback callback, void *baton)
+        : m_callback(callback), m_baton(baton)
+    {
+    }
+    ProcessStatusMonitorCallback m_callback;
+    void *m_baton;
+};
+
+typedef std::list<ProcessStatusMonitorCallbackEntry> ProcessStatusMonitorCallbackList;
+typedef std::unique_ptr<ProcessStatusMonitorCallbackList> ProcessStatusMonitorCallbackListUP;
+
+//----------------------------------------------------------------------
+// ProcessStatusMonitor
+//
+// ProcessStatusMonitor accepts callback registrations and provides an interface
+// for implementors to initiate the monitoring of a given process.  This allows,
+// for example, an implementation that launches one thread per process, or another
+// implementation that can monitor many processes on the same thread.
+//----------------------------------------------------------------------
+class ProcessStatusMonitor
+{
+  public:
+    struct MonitorData
+    {
+        ProcessStatusMonitorCallbackListUP m_callbacks;
+        HostProcess m_process;
+    };
+
+    ProcessStatusMonitor();
+    virtual ~ProcessStatusMonitor() {}
+
+    void AddProcessEventCallback(ProcessStatusMonitorCallback callback, void *baton);
+    virtual void StartMonitoring(const HostProcess &process) = 0;
+
+  protected:
+    ProcessStatusMonitorCallbackListUP m_callbacks;
+};
+}
+
+#endif
Index: include/lldb/Host/windows/ExitStatusMonitorWindows.h
===================================================================
--- /dev/null
+++ include/lldb/Host/windows/ExitStatusMonitorWindows.h
@@ -0,0 +1,35 @@
+//===-- ExitStatusMonitor.h -------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_Host_windows_ExitStatusMonitor_H_
+#define liblldb_Host_windows_ExitStatusMonitor_H_
+
+#include "lldb/Host/ProcessStatusMonitor.h"
+
+namespace lldb_private
+{
+//----------------------------------------------------------------------
+// ExitStatusMonitor
+//
+// An simple process status monitor that initiates monitoring on a new thread
+// for every process, and notifies callbacks when a process exits.
+//----------------------------------------------------------------------
+class ExitStatusMonitor : public ProcessStatusMonitor
+{
+  public:
+    virtual ~ExitStatusMonitor() {}
+
+    virtual void StartMonitoring(const HostProcess &process);
+
+  private:
+    static lldb::thread_result_t MonitorThread(void *thread_data);
+};
+}
+
+#endif
Index: include/lldb/Host/windows/HostProcessWindows.h
===================================================================
--- include/lldb/Host/windows/HostProcessWindows.h
+++ include/lldb/Host/windows/HostProcessWindows.h
@@ -34,7 +34,6 @@
     virtual HostThread StartMonitoring(HostProcess::MonitorCallback callback, void *callback_baton, bool monitor_signals);
 
   private:
-    static lldb::thread_result_t MonitorThread(void *thread_arg);
 
     void Close();
 };
Index: include/lldb/lldb-forward.h
===================================================================
--- include/lldb/lldb-forward.h
+++ include/lldb/lldb-forward.h
@@ -161,7 +161,10 @@
 class   ProcessInstanceInfo;
 class   ProcessInstanceInfoList;
 class   ProcessInstanceInfoMatch;
+class   ProcessLauncher;
 class   ProcessLaunchInfo;
+class   ProcessStatusMonitor;
+class   ProcessStatusMonitorImpl;
 class   Property;
 struct  PropertyDefinition;
 class   PythonArray;
@@ -349,6 +352,9 @@
     typedef std::shared_ptr<lldb_private::OptionValueUUID> OptionValueUUIDSP;
     typedef std::shared_ptr<lldb_private::Platform> PlatformSP;
     typedef std::shared_ptr<lldb_private::Process> ProcessSP;
+    typedef std::unique_ptr<lldb_private::ProcessLauncher> ProcessLauncherUP;
+    typedef std::shared_ptr<lldb_private::ProcessStatusMonitor> ProcessStatusMonitorSP;
+    typedef std::unique_ptr<lldb_private::ProcessStatusMonitorImpl> ProcessStatusMonitorImplUP;
     typedef std::shared_ptr<lldb_private::ProcessAttachInfo> ProcessAttachInfoSP;
     typedef std::shared_ptr<lldb_private::ProcessLaunchInfo> ProcessLaunchInfoSP;
     typedef std::weak_ptr<lldb_private::Process> ProcessWP;
Index: source/Host/CMakeLists.txt
===================================================================
--- source/Host/CMakeLists.txt
+++ source/Host/CMakeLists.txt
@@ -22,6 +22,7 @@
   common/NativeProcessProtocol.cpp
   common/NativeThreadProtocol.cpp
   common/OptionParser.cpp
+  common/ProcessStatusMonitor.cpp
   common/ProcessRunLock.cpp
   common/Socket.cpp
   common/SocketAddress.cpp
@@ -51,6 +52,7 @@
     windows/PipeWindows.cpp
     windows/ProcessLauncherWindows.cpp
     windows/ProcessRunLock.cpp
+    windows/ExitStatusMonitorWindows.cpp
     windows/ThisThread.cpp
     windows/Windows.cpp
     )
Index: source/Host/common/Host.cpp
===================================================================
--- source/Host/common/Host.cpp
+++ source/Host/common/Host.cpp
@@ -64,6 +64,7 @@
 
 #if defined(_WIN32)
 #include "lldb/Host/windows/ProcessLauncherWindows.h"
+#include "lldb/Host/windows/ExitStatusMonitorWindows.h"
 #else
 #include "lldb/Host/posix/ProcessLauncherPosix.h"
 #endif
@@ -1032,13 +1033,14 @@
 Error
 Host::LaunchProcess (ProcessLaunchInfo &launch_info)
 {
-    std::unique_ptr<ProcessLauncher> delegate_launcher;
+    ProcessStatusMonitorSP delegate_monitor;
 #if defined(_WIN32)
-    delegate_launcher.reset(new ProcessLauncherWindows());
+    ProcessLauncherWindows delegate_launcher;
+    delegate_monitor.reset(new ExitStatusMonitor());
 #else
-    delegate_launcher.reset(new ProcessLauncherPosix());
+    ProcessLauncherPosix delegate_launcher;
 #endif
-    MonitoringProcessLauncher launcher(std::move(delegate_launcher));
+    MonitoringProcessLauncher launcher(delegate_monitor, delegate_launcher);
 
     Error error;
     HostProcess process = launcher.LaunchProcess(launch_info, error);
Index: source/Host/common/HostProcess.cpp
===================================================================
--- source/Host/common/HostProcess.cpp
+++ source/Host/common/HostProcess.cpp
@@ -38,6 +38,12 @@
     return m_native_process->GetMainModule(file_spec);
 }
 
+lldb::process_t
+HostProcess::GetProcess() const
+{
+    return m_native_process->GetProcess();
+}
+
 lldb::pid_t HostProcess::GetProcessId() const
 {
     return m_native_process->GetProcessId();
Index: source/Host/common/MonitoringProcessLauncher.cpp
===================================================================
--- source/Host/common/MonitoringProcessLauncher.cpp
+++ source/Host/common/MonitoringProcessLauncher.cpp
@@ -12,6 +12,7 @@
 #include "lldb/Core/Module.h"
 #include "lldb/Host/HostProcess.h"
 #include "lldb/Host/MonitoringProcessLauncher.h"
+#include "lldb/Host/ProcessStatusMonitor.h"
 #include "lldb/Target/Platform.h"
 #include "lldb/Target/Process.h"
 #include "lldb/Target/ProcessLaunchInfo.h"
@@ -19,8 +20,9 @@
 using namespace lldb;
 using namespace lldb_private;
 
-MonitoringProcessLauncher::MonitoringProcessLauncher(std::unique_ptr<ProcessLauncher> delegate_launcher)
-    : m_delegate_launcher(std::move(delegate_launcher))
+MonitoringProcessLauncher::MonitoringProcessLauncher(ProcessStatusMonitorSP monitor, ProcessLauncher &delegate_launcher)
+    : m_monitor(monitor)
+    , m_delegate_launcher(delegate_launcher)
 {
 }
 
@@ -65,7 +67,7 @@
     resolved_info.SetExecutableFile(exe_spec, false);
     assert(!resolved_info.GetFlags().Test(eLaunchFlagLaunchInTTY));
 
-    HostProcess process = m_delegate_launcher->LaunchProcess(resolved_info, error);
+    HostProcess process = m_delegate_launcher.LaunchProcess(resolved_info, error);
 
     if (process.GetProcessId() != LLDB_INVALID_PROCESS_ID)
     {
@@ -86,7 +88,21 @@
             callback = Process::SetProcessExitStatus;
         }
 
-        process.StartMonitoring(callback, baton, monitor_signals);
+        if (m_monitor)
+        {
+            // If the ProcessLaunchInfo specified a callback, make sure it's registered in
+            // addition to anything else that may have been registered by the creator of the
+            // status monitor.
+            m_monitor->AddProcessEventCallback(callback, baton);
+            m_monitor->StartMonitoring(process);
+        }
+        else
+        {
+            // FIXME: This branch should go away if everything used a ProcessStatusMonitor and we
+            // could assume that m_monitor was non-null.
+            process.StartMonitoring(callback, baton, monitor_signals);
+        }
+
         if (log)
             log->PutCString("started monitoring child process.");
     }
Index: source/Host/common/ProcessStatusMonitor.cpp
===================================================================
--- /dev/null
+++ source/Host/common/ProcessStatusMonitor.cpp
@@ -0,0 +1,24 @@
+//===-- ProcessStatusMonitor.cpp --------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Host/ProcessStatusMonitor.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+ProcessStatusMonitor::ProcessStatusMonitor()
+    : m_callbacks(new ProcessStatusMonitorCallbackList())
+{
+}
+
+void
+ProcessStatusMonitor::AddProcessEventCallback(ProcessStatusMonitorCallback callback, void *baton)
+{
+    m_callbacks->push_back(ProcessStatusMonitorCallbackEntry(callback, baton));
+}
Index: source/Host/windows/ExitStatusMonitorWindows.cpp
===================================================================
--- /dev/null
+++ source/Host/windows/ExitStatusMonitorWindows.cpp
@@ -0,0 +1,47 @@
+//===-- ExitStatusMonitorWindows.cpp ----------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Host/HostProcess.h"
+#include "lldb/Host/ThreadLauncher.h"
+#include "lldb/Host/windows/ExitStatusMonitorWindows.h"
+#include "lldb/Host/windows/windows.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+void
+ExitStatusMonitor::StartMonitoring(const HostProcess &process)
+{
+    if (!m_callbacks)
+        return;
+
+    MonitorData *thread_data = new MonitorData();
+    thread_data->m_callbacks = std::move(m_callbacks);
+    thread_data->m_process = process;
+    ThreadLauncher::LaunchThread("ExitStatusMonitorThread", MonitorThread, thread_data, nullptr);
+}
+
+lldb::thread_result_t
+ExitStatusMonitor::MonitorThread(void *data)
+{
+    MonitorData *thread_data = static_cast<MonitorData *>(data);
+    HostProcess process(thread_data->m_process);
+    std::unique_ptr<ProcessStatusMonitorCallbackList> callbacks(std::move(thread_data->m_callbacks));
+
+    DWORD exit_code = 0;
+    DWORD wait_result = ::WaitForSingleObject(process.GetProcess(), INFINITE);
+    ::GetExitCodeProcess(process.GetProcess(), &exit_code);
+
+    for (const auto &entry : *callbacks)
+        entry.m_callback(entry.m_baton, process.GetProcessId(), true, 0, exit_code);
+
+    delete thread_data;
+
+    return 0;
+}
Index: source/Host/windows/HostProcessWindows.cpp
===================================================================
--- source/Host/windows/HostProcessWindows.cpp
+++ source/Host/windows/HostProcessWindows.cpp
@@ -9,9 +9,11 @@
 
 #include "lldb/Host/FileSpec.h"
 #include "lldb/Host/HostThread.h"
+#include "lldb/Host/ProcessStatusMonitor.h"
 #include "lldb/Host/ThreadLauncher.h"
-#include "lldb/Host/windows/windows.h"
+#include "lldb/Host/windows/ExitStatusMonitorWindows.h"
 #include "lldb/Host/windows/HostProcessWindows.h"
+#include "lldb/Host/windows/windows.h"
 
 #include "llvm/ADT/STLExtras.h"
 
@@ -19,16 +21,6 @@
 
 using namespace lldb_private;
 
-namespace
-{
-struct MonitorInfo
-{
-    HostProcess::MonitorCallback callback;
-    void *baton;
-    HANDLE process_handle;
-};
-}
-
 HostProcessWindows::HostProcessWindows()
     : HostNativeProcessBase()
 {
@@ -91,34 +83,8 @@
 HostThread
 HostProcessWindows::StartMonitoring(HostProcess::MonitorCallback callback, void *callback_baton, bool monitor_signals)
 {
-    HostThread monitor_thread;
-    MonitorInfo *info = new MonitorInfo;
-    info->callback = callback;
-    info->baton = callback_baton;
-
-    // Since the life of this HostProcessWindows instance and the life of the process may be different, duplicate the handle so that
-    // the monitor thread can have ownership over its own copy of the handle.
-    HostThread result;
-    if (::DuplicateHandle(GetCurrentProcess(), m_process, GetCurrentProcess(), &info->process_handle, 0, FALSE, DUPLICATE_SAME_ACCESS))
-        result = ThreadLauncher::LaunchThread("ChildProcessMonitor", HostProcessWindows::MonitorThread, info, nullptr);
-    return result;
-}
-
-lldb::thread_result_t
-HostProcessWindows::MonitorThread(void *thread_arg)
-{
-    DWORD exit_code;
-
-    MonitorInfo *info = static_cast<MonitorInfo *>(thread_arg);
-    if (info)
-    {
-        DWORD wait_result = ::WaitForSingleObject(info->process_handle, INFINITE);
-        ::GetExitCodeProcess(info->process_handle, &exit_code);
-        info->callback(info->baton, ::GetProcessId(info->process_handle), true, 0, exit_code);
-        ::CloseHandle(info->process_handle);
-        delete (info);
-    }
-    return 0;
+    // Not implemented.  Remove this after converting to ProcessStatusMonitor.
+    return HostThread();
 }
 
 void HostProcessWindows::Close()
Index: source/Host/windows/ProcessLauncherWindows.cpp
===================================================================
--- source/Host/windows/ProcessLauncherWindows.cpp
+++ source/Host/windows/ProcessLauncherWindows.cpp
@@ -38,9 +38,13 @@
     startupinfo.hStdInput = stdin_handle;
     startupinfo.hStdOutput = stdout_handle;
 
+    DWORD flags = CREATE_NEW_CONSOLE;
+    if (launch_info.GetFlags().Test(eLaunchFlagDebug))
+        flags |= DEBUG_ONLY_THIS_PROCESS;
+
     executable = launch_info.GetExecutableFile().GetPath();
     launch_info.GetArguments().GetQuotedCommandString(commandLine);
-    BOOL result = ::CreateProcessA(executable.c_str(), const_cast<char *>(commandLine.c_str()), NULL, NULL, TRUE, CREATE_NEW_CONSOLE, NULL,
+    BOOL result = ::CreateProcessA(executable.c_str(), const_cast<char *>(commandLine.c_str()), NULL, NULL, TRUE, flags, NULL,
                                    launch_info.GetWorkingDirectory(), &startupinfo, &pi);
     if (result)
     {
_______________________________________________
lldb-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/lldb-commits

Reply via email to