Fixed an issue with the pthread_setspecific() where we weren't NULL-ing out
the thread specific data and were destroying the thread specfic data more
than once.

Also added the ability to ask a lldb::StateType if it is stopped with an
additional paramter of "must_exist" which means that the state must be a
stopped state for a process that still exists. This means that eStateExited
and eStateUnloaded will no longer return true if "must_exist" is set to true.



git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@144875 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/source/API/SBDebugger.cpp b/source/API/SBDebugger.cpp
index b15bc3d..b8be227 100644
--- a/source/API/SBDebugger.cpp
+++ b/source/API/SBDebugger.cpp
@@ -452,7 +452,7 @@
 {
     LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
 
-    const bool result = lldb_private::StateIsStoppedState (state);
+    const bool result = lldb_private::StateIsStoppedState (state, false);
     if (log)
         log->Printf ("SBDebugger::StateIsStoppedState (state=%s) => %i", 
                      StateAsCString (state), result);
diff --git a/source/Commands/CommandObjectProcess.cpp b/source/Commands/CommandObjectProcess.cpp
index e048182..d618c04 100644
--- a/source/Commands/CommandObjectProcess.cpp
+++ b/source/Commands/CommandObjectProcess.cpp
@@ -284,7 +284,8 @@
                         if (synchronous_execution)
                         {
                             state = process->WaitForProcessToStop (NULL);
-                            if (!StateIsStoppedState(state))
+                            const bool must_be_alive = true;
+                            if (!StateIsStoppedState(state, must_be_alive))
                             {
                                 result.AppendErrorWithFormat ("process isn't stopped: %s", StateAsCString(state));
                             }                    
diff --git a/source/Commands/CommandObjectTarget.cpp b/source/Commands/CommandObjectTarget.cpp
index 3ee3ab8..bbbca5e 100644
--- a/source/Commands/CommandObjectTarget.cpp
+++ b/source/Commands/CommandObjectTarget.cpp
@@ -82,7 +82,7 @@
         lldb::pid_t pid = process_sp->GetID();
         StateType state = process_sp->GetState();
         if (show_stopped_process_status)
-            show_process_status = StateIsStoppedState(state);
+            show_process_status = StateIsStoppedState(state, true);
         const char *state_cstr = StateAsCString (state);
         if (pid != LLDB_INVALID_PROCESS_ID)
             strm.Printf ("%spid=%i", properties++ > 0 ? ", " : " ( ", pid);
diff --git a/source/Core/State.cpp b/source/Core/State.cpp
index 8cb748f..c660477 100644
--- a/source/Core/State.cpp
+++ b/source/Core/State.cpp
@@ -90,7 +90,7 @@
 }
 
 bool
-lldb_private::StateIsStoppedState (StateType state)
+lldb_private::StateIsStoppedState (StateType state, bool must_exist)
 {
     switch (state)
     {
@@ -105,9 +105,11 @@
         break;
 
     case eStateUnloaded:
+    case eStateExited:
+        return !must_exist;
+
     case eStateStopped:
     case eStateCrashed:
-    case eStateExited:
     case eStateSuspended:
         return true;
     }
diff --git a/source/Host/macosx/Host.mm b/source/Host/macosx/Host.mm
index 7a84bde..db5c8e2 100644
--- a/source/Host/macosx/Host.mm
+++ b/source/Host/macosx/Host.mm
@@ -68,6 +68,9 @@
 using namespace lldb;
 using namespace lldb_private;
 
+static pthread_once_t g_thread_create_once = PTHREAD_ONCE_INIT;
+static pthread_key_t g_thread_create_key = 0;
+
 class MacOSXDarwinThread
 {
 public:
@@ -98,12 +101,17 @@
     ~MacOSXDarwinThread()
     {
         if (m_pool)
+        {
             [m_pool release];
+            m_pool = nil;
+        }
     }
 
     static void PThreadDestructor (void *v)
     {
-        delete (MacOSXDarwinThread*)v;
+        if (v)
+            delete static_cast<MacOSXDarwinThread*>(v);
+        ::pthread_setspecific (g_thread_create_key, NULL);
     }
 
 protected:
@@ -112,9 +120,6 @@
     DISALLOW_COPY_AND_ASSIGN (MacOSXDarwinThread);
 };
 
-static pthread_once_t g_thread_create_once = PTHREAD_ONCE_INIT;
-static pthread_key_t g_thread_create_key = 0;
-
 static void
 InitThreadCreated()
 {
diff --git a/source/Target/Process.cpp b/source/Target/Process.cpp
index ff5d718..3d917a6 100644
--- a/source/Target/Process.cpp
+++ b/source/Target/Process.cpp
@@ -1179,16 +1179,20 @@
     const uint32_t stop_id = GetStopID();
     if (m_thread_list.GetSize(false) == 0 || stop_id != m_thread_list.GetStopID())
     {
-        Mutex::Locker locker (m_thread_list.GetMutex ());
-        ThreadList new_thread_list(this);
-        // Always update the thread list with the protocol specific
-        // thread list
-        UpdateThreadList (m_thread_list, new_thread_list);
-        OperatingSystem *os = GetOperatingSystem ();
-        if (os)
-            os->UpdateThreadList (m_thread_list, new_thread_list);
-        m_thread_list.Update (new_thread_list);
-        m_thread_list.SetStopID (stop_id);
+        const StateType state = GetPrivateState();
+        if (StateIsStoppedState (state, true))
+        {
+            Mutex::Locker locker (m_thread_list.GetMutex ());
+            ThreadList new_thread_list(this);
+            // Always update the thread list with the protocol specific
+            // thread list
+            UpdateThreadList (m_thread_list, new_thread_list);
+            OperatingSystem *os = GetOperatingSystem ();
+            if (os)
+                os->UpdateThreadList (m_thread_list, new_thread_list);
+            m_thread_list.Update (new_thread_list);
+            m_thread_list.SetStopID (stop_id);
+        }
     }
 }
 
@@ -1236,7 +1240,7 @@
     if (state_changed)
     {
         m_private_state.SetValueNoLock (new_state);
-        if (StateIsStoppedState(new_state))
+        if (StateIsStoppedState(new_state, false))
         {
             m_mod_id.BumpStopID();
             m_memory_cache.Clear();
@@ -2167,7 +2171,7 @@
         event_sp.reset();
         state = WaitForStateChangedEventsPrivate (timeout, event_sp);
 
-        if (StateIsStoppedState(state))
+        if (StateIsStoppedState(state, false))
             break;
 
         // If state is invalid, then we timed out
@@ -2683,7 +2687,7 @@
                     }
                     else
                     {
-                        if (StateIsStoppedState (state))
+                        if (StateIsStoppedState (state, false))
                         {
                             // We caused the process to interrupt itself, so mark this
                             // as such in the stop event so clients can tell an interrupted
@@ -4247,7 +4251,7 @@
 Process::GetStatus (Stream &strm)
 {
     const StateType state = GetState();
-    if (StateIsStoppedState(state))
+    if (StateIsStoppedState(state, false))
     {
         if (state == eStateExited)
         {