Create a HostThread abstraction.

This patch moves creates a thread abstraction that represents a
thread running inside the LLDB process.  This is a replacement for
otherwise using lldb::thread_t, and provides a platform agnostic
interface to managing these threads.

Differential Revision: http://reviews.llvm.org/D5198

Reviewed by: Jim Ingham

llvm-svn: 217460
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
index 1f4dd93..2db518d 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
@@ -26,6 +26,7 @@
 #include "lldb/Host/Host.h"
 #include "lldb/Host/HostInfo.h"
 #include "lldb/Host/Socket.h"
+#include "lldb/Host/ThreadLauncher.h"
 #include "lldb/Host/TimeValue.h"
 #include "lldb/Target/Process.h"
 
@@ -153,7 +154,6 @@
     m_history (512),
     m_send_acks (true),
     m_is_platform (is_platform),
-    m_listen_thread (LLDB_INVALID_HOST_THREAD),
     m_listen_url ()
 {
 }
@@ -606,7 +606,7 @@
 GDBRemoteCommunication::StartListenThread (const char *hostname, uint16_t port)
 {
     Error error;
-    if (IS_VALID_LLDB_HOST_THREAD(m_listen_thread))
+    if (m_listen_thread.GetState() == eThreadStateRunning)
     {
         error.SetErrorString("listen thread already running");
     }
@@ -619,7 +619,7 @@
             snprintf(listen_url, sizeof(listen_url), "listen://%i", port);
         m_listen_url = listen_url;
         SetConnection(new ConnectionFileDescriptor());
-        m_listen_thread = Host::ThreadCreate (listen_url, GDBRemoteCommunication::ListenThread, this, &error);
+        m_listen_thread = ThreadLauncher::LaunchThread(listen_url, GDBRemoteCommunication::ListenThread, this, &error);
     }
     return error;
 }
@@ -627,10 +627,10 @@
 bool
 GDBRemoteCommunication::JoinListenThread ()
 {
-    if (IS_VALID_LLDB_HOST_THREAD(m_listen_thread))
+    if (m_listen_thread.GetState() == eThreadStateRunning)
     {
-        Host::ThreadJoin(m_listen_thread, NULL, NULL);
-        m_listen_thread = LLDB_INVALID_HOST_THREAD;
+        m_listen_thread.Join(nullptr);
+        m_listen_thread.Reset();
     }
     return true;
 }
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h
index b11d385..ac203a6 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h
@@ -20,6 +20,7 @@
 #include "lldb/lldb-public.h"
 #include "lldb/Core/Communication.h"
 #include "lldb/Core/Listener.h"
+#include "lldb/Host/HostThread.h"
 #include "lldb/Host/Mutex.h"
 #include "lldb/Host/Predicate.h"
 #include "lldb/Host/TimeValue.h"
@@ -281,8 +282,7 @@
     ListenThread (lldb::thread_arg_t arg);
 
 private:
-    
-    lldb::thread_t m_listen_thread;
+  lldb_private::HostThread m_listen_thread;
     std::string m_listen_url;
     
 
diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
index f35d954..28708be 100644
--- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
@@ -42,7 +42,9 @@
 #include "lldb/Core/StreamString.h"
 #include "lldb/Core/Timer.h"
 #include "lldb/Core/Value.h"
+#include "lldb/Host/HostThread.h"
 #include "lldb/Host/Symbols.h"
+#include "lldb/Host/ThreadLauncher.h"
 #include "lldb/Host/TimeValue.h"
 #include "lldb/Interpreter/CommandInterpreter.h"
 #include "lldb/Interpreter/CommandObject.h"
@@ -272,8 +274,6 @@
     m_last_stop_packet_mutex (Mutex::eMutexTypeNormal),
     m_register_info (),
     m_async_broadcaster (NULL, "lldb.process.gdb-remote.async-broadcaster"),
-    m_async_thread (LLDB_INVALID_HOST_THREAD),
-    m_async_thread_state(eAsyncThreadNotStarted),
     m_async_thread_state_mutex(Mutex::eMutexTypeRecursive),
     m_thread_ids (),
     m_continue_c_tids (),
@@ -1432,7 +1432,7 @@
             TimeValue timeout;
             timeout = TimeValue::Now();
             timeout.OffsetWithSeconds (5);
-            if (!IS_VALID_LLDB_HOST_THREAD(m_async_thread))
+            if (m_async_thread.GetState() != eThreadStateRunning)
             {
                 error.SetErrorString ("Trying to resume but the async thread is dead.");
                 if (log)
@@ -2891,30 +2891,22 @@
         log->Printf ("ProcessGDBRemote::%s ()", __FUNCTION__);
     
     Mutex::Locker start_locker(m_async_thread_state_mutex);
-    if (m_async_thread_state == eAsyncThreadNotStarted)
+    if (m_async_thread.GetState() != eThreadStateRunning)
     {
         // Create a thread that watches our internal state and controls which
         // events make it to clients (into the DCProcess event queue).
-        m_async_thread = Host::ThreadCreate ("<lldb.process.gdb-remote.async>", ProcessGDBRemote::AsyncThread, this, NULL);
-        if (IS_VALID_LLDB_HOST_THREAD(m_async_thread))
-        {
-            m_async_thread_state = eAsyncThreadRunning;
-            return true;
-        }
-        else
-            return false;
+
+        m_async_thread = ThreadLauncher::LaunchThread("<lldb.process.gdb-remote.async>", ProcessGDBRemote::AsyncThread, this, NULL);
     }
     else
     {
         // Somebody tried to start the async thread while it was either being started or stopped.  If the former, and
         // it started up successfully, then say all's well.  Otherwise it is an error, since we aren't going to restart it.
         if (log)
-            log->Printf ("ProcessGDBRemote::%s () - Called when Async thread was in state: %d.", __FUNCTION__, m_async_thread_state);
-        if (m_async_thread_state == eAsyncThreadRunning)
-            return true;
-        else
-            return false;
+            log->Printf("ProcessGDBRemote::%s () - Called when Async thread was in state: %d.", __FUNCTION__, m_async_thread.GetState());
     }
+
+    return (m_async_thread.GetState() == eThreadStateRunning);
 }
 
 void
@@ -2926,7 +2918,7 @@
         log->Printf ("ProcessGDBRemote::%s ()", __FUNCTION__);
 
     Mutex::Locker start_locker(m_async_thread_state_mutex);
-    if (m_async_thread_state == eAsyncThreadRunning)
+    if (m_async_thread.GetState() == eThreadStateRunning)
     {
         m_async_broadcaster.BroadcastEvent (eBroadcastBitAsyncThreadShouldExit);
         
@@ -2934,16 +2926,12 @@
         m_gdb_comm.Disconnect();    // Disconnect from the debug server.
 
         // Stop the stdio thread
-        if (IS_VALID_LLDB_HOST_THREAD(m_async_thread))
-        {
-            Host::ThreadJoin (m_async_thread, NULL, NULL);
-        }
-        m_async_thread_state = eAsyncThreadDone;
+        m_async_thread.Join(nullptr);
     }
     else
     {
         if (log)
-            log->Printf ("ProcessGDBRemote::%s () - Called when Async thread was in state: %d.", __FUNCTION__, m_async_thread_state);
+            log->Printf("ProcessGDBRemote::%s () - Called when Async thread was in state: %d.", __FUNCTION__, m_async_thread.GetState());
     }
 }
 
@@ -3086,7 +3074,7 @@
     if (log)
         log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64 ") thread exiting...", __FUNCTION__, arg, process->GetID());
 
-    process->m_async_thread = LLDB_INVALID_HOST_THREAD;
+    process->m_async_thread.Reset();
     return NULL;
 }
 
diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
index 942b31c..5e1365c 100644
--- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
+++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
@@ -25,6 +25,7 @@
 #include "lldb/Core/StringList.h"
 #include "lldb/Core/StructuredData.h"
 #include "lldb/Core/ThreadSafeValue.h"
+#include "lldb/Host/HostThread.h"
 #include "lldb/lldb-private-forward.h"
 #include "lldb/Target/Process.h"
 #include "lldb/Target/Thread.h"
@@ -324,13 +325,6 @@
         eBroadcastBitAsyncThreadShouldExit          = (1 << 1),
         eBroadcastBitAsyncThreadDidExit             = (1 << 2)
     };
-
-    typedef enum AsyncThreadState
-    {
-        eAsyncThreadNotStarted,
-        eAsyncThreadRunning,
-        eAsyncThreadDone
-    } AsyncThreadState;
     
     lldb_private::Flags m_flags;            // Process specific flags (see eFlags enums)
     GDBRemoteCommunicationClient m_gdb_comm;
@@ -339,8 +333,7 @@
     lldb_private::Mutex m_last_stop_packet_mutex;
     GDBRemoteDynamicRegisterInfo m_register_info;
     lldb_private::Broadcaster m_async_broadcaster;
-    lldb::thread_t m_async_thread;
-    AsyncThreadState m_async_thread_state;
+    lldb_private::HostThread m_async_thread;
     lldb_private::Mutex m_async_thread_state_mutex;
     typedef std::vector<lldb::tid_t> tid_collection;
     typedef std::vector< std::pair<lldb::tid_t,int> > tid_sig_collection;