Index: lldb/trunk/include/lldb/Core/Debugger.h =================================================================== --- lldb/trunk/include/lldb/Core/Debugger.h +++ lldb/trunk/include/lldb/Core/Debugger.h @@ -365,7 +365,7 @@ bool IsHandlingEvents () const { - return m_event_handler_thread.GetState() == eThreadStateRunning; + return m_event_handler_thread.IsJoinable(); } protected: Index: lldb/trunk/include/lldb/Host/HostNativeThreadBase.h =================================================================== --- lldb/trunk/include/lldb/Host/HostNativeThreadBase.h +++ lldb/trunk/include/lldb/Host/HostNativeThreadBase.h @@ -13,7 +13,6 @@ #include "lldb/Core/Error.h" #include "lldb/lldb-defines.h" #include "lldb/lldb-types.h" -#include "lldb/lldb-private-enumerations.h" namespace lldb_private { @@ -36,11 +35,10 @@ virtual Error Join(lldb::thread_result_t *result) = 0; virtual Error Cancel() = 0; + virtual bool IsJoinable() const; virtual void Reset(); lldb::thread_t Release(); - void SetState(ThreadState state); - ThreadState GetState() const; lldb::thread_t GetSystemHandle() const; lldb::thread_result_t GetResult() const; @@ -48,7 +46,6 @@ static lldb::thread_result_t THREAD_ROUTINE ThreadCreateTrampoline(lldb::thread_arg_t arg); lldb::thread_t m_thread; - ThreadState m_state; lldb::thread_result_t m_result; }; } Index: lldb/trunk/include/lldb/Host/HostThread.h =================================================================== --- lldb/trunk/include/lldb/Host/HostThread.h +++ lldb/trunk/include/lldb/Host/HostThread.h @@ -40,8 +40,7 @@ void Reset(); lldb::thread_t Release(); - void SetState(ThreadState state); - ThreadState GetState() const; + bool IsJoinable() const; HostNativeThreadBase &GetNativeThread(); const HostNativeThreadBase &GetNativeThread() const; lldb::thread_result_t GetResult() const; Index: lldb/trunk/include/lldb/Host/posix/HostThreadPosix.h =================================================================== --- lldb/trunk/include/lldb/Host/posix/HostThreadPosix.h +++ lldb/trunk/include/lldb/Host/posix/HostThreadPosix.h @@ -1,4 +1,4 @@ -//===-- HostThreadWindows.h -------------------------------------*- C++ -*-===// +//===-- HostThreadPosix.h -------------------------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // Index: lldb/trunk/include/lldb/Target/Process.h =================================================================== --- lldb/trunk/include/lldb/Target/Process.h +++ lldb/trunk/include/lldb/Target/Process.h @@ -3008,7 +3008,7 @@ bool PrivateStateThreadIsValid () const { - return m_private_state_thread.GetState() != eThreadStateInvalid; + return m_private_state_thread.IsJoinable(); } void Index: lldb/trunk/include/lldb/lldb-private-enumerations.h =================================================================== --- lldb/trunk/include/lldb/lldb-private-enumerations.h +++ lldb/trunk/include/lldb/lldb-private-enumerations.h @@ -241,18 +241,6 @@ } ExitType; //---------------------------------------------------------------------- -// State for running threads -//---------------------------------------------------------------------- -enum ThreadState -{ - eThreadStateInvalid, // The thread does not represent a current or past thread. - eThreadStateRunning, // The thread is currently running. - eThreadStateExited, // The thread's start routine returned normally. - eThreadStateCancelling, // The thread has been sent a cancellation request. - eThreadStateCancelled // The thread was cancelled before completing normally. -}; - -//---------------------------------------------------------------------- // Boolean result of running a Type Validator //---------------------------------------------------------------------- enum class TypeValidatorResult : bool { Index: lldb/trunk/source/Core/Communication.cpp =================================================================== --- lldb/trunk/source/Core/Communication.cpp +++ lldb/trunk/source/Core/Communication.cpp @@ -233,7 +233,7 @@ if (error_ptr) error_ptr->Clear(); - if (m_read_thread.GetState() == eThreadStateRunning) + if (m_read_thread.IsJoinable()) return true; lldb_private::LogIfAnyCategoriesSet (LIBLLDB_LOG_COMMUNICATION, @@ -245,7 +245,7 @@ m_read_thread_enabled = true; m_read_thread = ThreadLauncher::LaunchThread(thread_name, Communication::ReadThread, this, error_ptr); - if (m_read_thread.GetState() != eThreadStateRunning) + if (!m_read_thread.IsJoinable()) m_read_thread_enabled = false; return m_read_thread_enabled; } @@ -253,7 +253,7 @@ bool Communication::StopReadThread (Error *error_ptr) { - if (m_read_thread.GetState() != eThreadStateRunning) + if (!m_read_thread.IsJoinable()) return true; lldb_private::LogIfAnyCategoriesSet (LIBLLDB_LOG_COMMUNICATION, @@ -266,18 +266,16 @@ // error = m_read_thread.Cancel(); Error error = m_read_thread.Join(nullptr); - m_read_thread.Reset(); return error.Success(); } bool Communication::JoinReadThread (Error *error_ptr) { - if (m_read_thread.GetState() != eThreadStateRunning) + if (!m_read_thread.IsJoinable()) return true; Error error = m_read_thread.Join(nullptr); - m_read_thread.Reset(); return error.Success(); } Index: lldb/trunk/source/Core/Debugger.cpp =================================================================== --- lldb/trunk/source/Core/Debugger.cpp +++ lldb/trunk/source/Core/Debugger.cpp @@ -3336,19 +3336,18 @@ bool Debugger::StartEventHandlerThread() { - if (m_event_handler_thread.GetState() != eThreadStateRunning) + if (!m_event_handler_thread.IsJoinable()) m_event_handler_thread = ThreadLauncher::LaunchThread("lldb.debugger.event-handler", EventHandlerThread, this, NULL); - return m_event_handler_thread.GetState() == eThreadStateRunning; + return m_event_handler_thread.IsJoinable(); } void Debugger::StopEventHandlerThread() { - if (m_event_handler_thread.GetState() == eThreadStateRunning) + if (m_event_handler_thread.IsJoinable()) { GetCommandInterpreter().BroadcastEvent(CommandInterpreter::eBroadcastBitQuitCommandReceived); m_event_handler_thread.Join(nullptr); - m_event_handler_thread.Reset(); } } @@ -3365,20 +3364,19 @@ bool Debugger::StartIOHandlerThread() { - if (m_io_handler_thread.GetState() != eThreadStateRunning) + if (!m_io_handler_thread.IsJoinable()) m_io_handler_thread = ThreadLauncher::LaunchThread("lldb.debugger.io-handler", IOHandlerThread, this, NULL); - return m_io_handler_thread.GetState() == eThreadStateRunning; + return m_io_handler_thread.IsJoinable(); } void Debugger::StopIOHandlerThread() { - if (m_io_handler_thread.GetState() == eThreadStateRunning) + if (m_io_handler_thread.IsJoinable()) { if (m_input_file_sp) m_input_file_sp->GetFile().Close(); m_io_handler_thread.Join(nullptr); - m_io_handler_thread.Reset(); } } Index: lldb/trunk/source/Host/common/HostNativeThreadBase.cpp =================================================================== --- lldb/trunk/source/Host/common/HostNativeThreadBase.cpp +++ lldb/trunk/source/Host/common/HostNativeThreadBase.cpp @@ -19,30 +19,16 @@ HostNativeThreadBase::HostNativeThreadBase() : m_thread(LLDB_INVALID_HOST_THREAD) - , m_state(eThreadStateInvalid) , m_result(0) { } HostNativeThreadBase::HostNativeThreadBase(thread_t thread) : m_thread(thread) - , m_state((thread == LLDB_INVALID_HOST_THREAD) ? eThreadStateInvalid : eThreadStateRunning) , m_result(0) { } -void -HostNativeThreadBase::SetState(ThreadState state) -{ - m_state = state; -} - -ThreadState -HostNativeThreadBase::GetState() const -{ - return m_state; -} - lldb::thread_t HostNativeThreadBase::GetSystemHandle() const { @@ -55,11 +41,16 @@ return m_result; } +bool +HostNativeThreadBase::IsJoinable() const +{ + return m_thread != LLDB_INVALID_HOST_THREAD; +} + void HostNativeThreadBase::Reset() { m_thread = LLDB_INVALID_HOST_THREAD; - m_state = eThreadStateInvalid; m_result = 0; } @@ -68,7 +59,6 @@ { lldb::thread_t result = m_thread; m_thread = LLDB_INVALID_HOST_THREAD; - m_state = eThreadStateInvalid; m_result = 0; return result; Index: lldb/trunk/source/Host/common/HostThread.cpp =================================================================== --- lldb/trunk/source/Host/common/HostThread.cpp +++ lldb/trunk/source/Host/common/HostThread.cpp @@ -47,16 +47,10 @@ return m_native_thread->Release(); } -void -HostThread::SetState(ThreadState state) -{ - m_native_thread->SetState(state); -} - -ThreadState -HostThread::GetState() const +bool +HostThread::IsJoinable() const { - return m_native_thread->GetState(); + return m_native_thread->IsJoinable(); } HostNativeThreadBase & Index: lldb/trunk/source/Host/posix/HostThreadPosix.cpp =================================================================== --- lldb/trunk/source/Host/posix/HostThreadPosix.cpp +++ lldb/trunk/source/Host/posix/HostThreadPosix.cpp @@ -10,8 +10,10 @@ #include "lldb/Core/Error.h" #include "lldb/Host/posix/HostThreadPosix.h" +#include #include +using namespace lldb; using namespace lldb_private; HostThreadPosix::HostThreadPosix() @@ -31,13 +33,16 @@ HostThreadPosix::Join(lldb::thread_result_t *result) { Error error; - lldb::thread_result_t thread_result; - int err = ::pthread_join(m_thread, &thread_result); - error.SetError(err, lldb::eErrorTypePOSIX); - if (err == 0) + if (IsJoinable()) { - m_state = (m_state == eThreadStateCancelling) ? eThreadStateCancelled : eThreadStateExited; + lldb::thread_result_t thread_result; + int err = ::pthread_join(m_thread, &thread_result); + error.SetError(err, lldb::eErrorTypePOSIX); } + else + error.SetError(EINVAL, eErrorTypePOSIX); + + Reset(); return error; } @@ -46,9 +51,7 @@ { Error error; int err = ::pthread_cancel(m_thread); - error.SetError(err, lldb::eErrorTypePOSIX); - if (err == 0) - m_state = eThreadStateCancelling; + error.SetError(err, eErrorTypePOSIX); return error; } @@ -58,6 +61,7 @@ { Error error; int err = ::pthread_detach(m_thread); - error.SetError(err, lldb::eErrorTypePOSIX); + error.SetError(err, eErrorTypePOSIX); + Reset(); return error; } Index: lldb/trunk/source/Host/windows/HostThreadWindows.cpp =================================================================== --- lldb/trunk/source/Host/windows/HostThreadWindows.cpp +++ lldb/trunk/source/Host/windows/HostThreadWindows.cpp @@ -36,21 +36,21 @@ HostThreadWindows::Join(lldb::thread_result_t *result) { Error error; - if (WAIT_OBJECT_0 != ::WaitForSingleObject(m_thread, INFINITE)) + if (IsJoinable()) { - error.SetError(::GetLastError(), lldb::eErrorTypeWin32); - return error; - } - - m_state = (m_state == eThreadStateCancelling) ? eThreadStateCancelled : eThreadStateExited; - - if (result) - { - DWORD dword_result = 0; - if (!::GetExitCodeThread(m_thread, &dword_result)) - *result = 0; - *result = dword_result; + DWORD wait_result = ::WaitForSingleObject(m_thread, INFINITE); + if (WAIT_OBJECT_0 == wait_result && result) + { + DWORD exit_code = 0; + if (!::GetExitCodeThread(m_thread, &exit_code)) + *result = 0; + *result = exit_code; + } + else if (WAIT_OBJECT_0 != wait_result) + error.SetError(::GetLastError(), eErrorTypeWin32); } + else + error.SetError(ERROR_INVALID_HANDLE, eErrorTypeWin32); return error; } Index: lldb/trunk/source/Plugins/Process/Linux/NativeProcessLinux.cpp =================================================================== --- lldb/trunk/source/Plugins/Process/Linux/NativeProcessLinux.cpp +++ lldb/trunk/source/Plugins/Process/Linux/NativeProcessLinux.cpp @@ -1396,7 +1396,7 @@ // Finally, start monitoring the child process for change in state. m_monitor_thread = Host::StartMonitoringChildProcess( NativeProcessLinux::MonitorCallback, this, GetID(), true); - if (m_monitor_thread.GetState() != eThreadStateRunning) + if (!m_monitor_thread.IsJoinable()) { error.SetErrorToGenericError(); error.SetErrorString ("Process attach failed to create monitor thread for NativeProcessLinux::MonitorCallback."); @@ -1474,7 +1474,7 @@ // Finally, start monitoring the child process for change in state. m_monitor_thread = Host::StartMonitoringChildProcess ( NativeProcessLinux::MonitorCallback, this, GetID (), true); - if (m_monitor_thread.GetState() != eThreadStateRunning) + if (!m_monitor_thread.IsJoinable()) { error.SetErrorToGenericError (); error.SetErrorString ("Process attach failed to create monitor thread for NativeProcessLinux::MonitorCallback."); @@ -1495,7 +1495,7 @@ { static const char *g_thread_name = "lldb.process.nativelinux.operation"; - if (m_operation_thread.GetState() == eThreadStateRunning) + if (m_operation_thread.IsJoinable()) return; m_operation_thread = ThreadLauncher::LaunchThread(g_thread_name, LaunchOpThread, args, &error); @@ -1804,7 +1804,7 @@ { static const char *g_thread_name = "lldb.process.linux.operation"; - if (m_operation_thread.GetState() == eThreadStateRunning) + if (m_operation_thread.IsJoinable()) return; m_operation_thread = ThreadLauncher::LaunchThread(g_thread_name, AttachOpThread, args, &error); @@ -3645,11 +3645,10 @@ void NativeProcessLinux::StopMonitoringChildProcess() { - if (m_monitor_thread.GetState() == eThreadStateRunning) + if (m_monitor_thread.IsJoinable()) { m_monitor_thread.Cancel(); m_monitor_thread.Join(nullptr); - m_monitor_thread.Reset(); } } @@ -3671,12 +3670,11 @@ void NativeProcessLinux::StopOpThread() { - if (m_operation_thread.GetState() != eThreadStateRunning) + if (!m_operation_thread.IsJoinable()) return; m_operation_thread.Cancel(); m_operation_thread.Join(nullptr); - m_operation_thread.Reset(); } bool Index: lldb/trunk/source/Plugins/Process/Linux/ProcessMonitor.cpp =================================================================== --- lldb/trunk/source/Plugins/Process/Linux/ProcessMonitor.cpp +++ lldb/trunk/source/Plugins/Process/Linux/ProcessMonitor.cpp @@ -1199,7 +1199,7 @@ // Finally, start monitoring the child process for change in state. m_monitor_thread = Host::StartMonitoringChildProcess( ProcessMonitor::MonitorCallback, this, GetPID(), true); - if (m_monitor_thread.GetState() != eThreadStateRunning) + if (!m_monitor_thread.IsJoinable()) { error.SetErrorToGenericError(); error.SetErrorString("Process launch failed."); @@ -1250,7 +1250,7 @@ // Finally, start monitoring the child process for change in state. m_monitor_thread = Host::StartMonitoringChildProcess( ProcessMonitor::MonitorCallback, this, GetPID(), true); - if (m_monitor_thread.GetState() != eThreadStateRunning) + if (!m_monitor_thread.IsJoinable()) { error.SetErrorToGenericError(); error.SetErrorString("Process attach failed."); @@ -1270,7 +1270,7 @@ { static const char *g_thread_name = "lldb.process.linux.operation"; - if (m_operation_thread.GetState() == eThreadStateRunning) + if (m_operation_thread.IsJoinable()) return; m_operation_thread = ThreadLauncher::LaunchThread(g_thread_name, LaunchOpThread, args, &error); @@ -1493,7 +1493,7 @@ { static const char *g_thread_name = "lldb.process.linux.operation"; - if (m_operation_thread.GetState() == eThreadStateRunning) + if (m_operation_thread.IsJoinable()) return; m_operation_thread = ThreadLauncher::LaunchThread(g_thread_name, AttachOpThread, args, &error); @@ -2466,11 +2466,10 @@ void ProcessMonitor::StopMonitoringChildProcess() { - if (m_monitor_thread.GetState() == eThreadStateRunning) + if (m_monitor_thread.IsJoinable()) { m_monitor_thread.Cancel(); m_monitor_thread.Join(nullptr); - m_monitor_thread.Reset(); } } @@ -2491,10 +2490,9 @@ void ProcessMonitor::StopOpThread() { - if (m_operation_thread.GetState() != eThreadStateRunning) + if (!m_operation_thread.IsJoinable()) return; m_operation_thread.Cancel(); m_operation_thread.Join(nullptr); - m_operation_thread.Reset(); } Index: lldb/trunk/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp =================================================================== --- lldb/trunk/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp +++ lldb/trunk/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp @@ -469,7 +469,7 @@ Error error; Log *log (ProcessKDPLog::GetLogIfAllCategoriesSet (KDP_LOG_PROCESS)); // Only start the async thread if we try to do any process control - if (m_async_thread.GetState() != eThreadStateRunning) + if (!m_async_thread.IsJoinable()) StartAsyncThread(); bool resume = false; @@ -870,11 +870,11 @@ if (log) log->Printf ("ProcessKDP::StartAsyncThread ()"); - if (m_async_thread.GetState() == eThreadStateRunning) + if (m_async_thread.IsJoinable()) return true; m_async_thread = ThreadLauncher::LaunchThread("", ProcessKDP::AsyncThread, this, NULL); - return m_async_thread.GetState() == eThreadStateRunning; + return m_async_thread.IsJoinable(); } void @@ -888,11 +888,8 @@ m_async_broadcaster.BroadcastEvent (eBroadcastBitAsyncThreadShouldExit); // Stop the stdio thread - if (m_async_thread.GetState() == eThreadStateRunning) - { + if (m_async_thread.IsJoinable()) m_async_thread.Join(nullptr); - m_async_thread.Reset(); - } } Index: lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp =================================================================== --- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp +++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp @@ -634,7 +634,7 @@ GDBRemoteCommunication::StartListenThread (const char *hostname, uint16_t port) { Error error; - if (m_listen_thread.GetState() == eThreadStateRunning) + if (m_listen_thread.IsJoinable()) { error.SetErrorString("listen thread already running"); } @@ -655,11 +655,8 @@ bool GDBRemoteCommunication::JoinListenThread () { - if (m_listen_thread.GetState() == eThreadStateRunning) - { + if (m_listen_thread.IsJoinable()) m_listen_thread.Join(nullptr); - m_listen_thread.Reset(); - } return true; } Index: lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp =================================================================== --- lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp +++ lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp @@ -1432,7 +1432,7 @@ TimeValue timeout; timeout = TimeValue::Now(); timeout.OffsetWithSeconds (5); - if (m_async_thread.GetState() != eThreadStateRunning) + if (!m_async_thread.IsJoinable()) { error.SetErrorString ("Trying to resume but the async thread is dead."); if (log) @@ -2891,22 +2891,17 @@ log->Printf ("ProcessGDBRemote::%s ()", __FUNCTION__); Mutex::Locker start_locker(m_async_thread_state_mutex); - if (m_async_thread.GetState() != eThreadStateRunning) + if (!m_async_thread.IsJoinable()) { // Create a thread that watches our internal state and controls which // events make it to clients (into the DCProcess event queue). m_async_thread = ThreadLauncher::LaunchThread("", 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.GetState()); - } + else if (log) + log->Printf("ProcessGDBRemote::%s () - Called when Async thread was already running.", __FUNCTION__); - return (m_async_thread.GetState() == eThreadStateRunning); + return m_async_thread.IsJoinable(); } void @@ -2918,7 +2913,7 @@ log->Printf ("ProcessGDBRemote::%s ()", __FUNCTION__); Mutex::Locker start_locker(m_async_thread_state_mutex); - if (m_async_thread.GetState() == eThreadStateRunning) + if (m_async_thread.IsJoinable()) { m_async_broadcaster.BroadcastEvent (eBroadcastBitAsyncThreadShouldExit); @@ -2928,11 +2923,8 @@ // Stop the stdio thread m_async_thread.Join(nullptr); } - else - { - if (log) - log->Printf("ProcessGDBRemote::%s () - Called when Async thread was in state: %d.", __FUNCTION__, m_async_thread.GetState()); - } + else if (log) + log->Printf("ProcessGDBRemote::%s () - Called when Async thread was not running.", __FUNCTION__); } Index: lldb/trunk/source/Target/Process.cpp =================================================================== --- lldb/trunk/source/Target/Process.cpp +++ lldb/trunk/source/Target/Process.cpp @@ -3867,7 +3867,7 @@ // Create the private state thread, and start it running. m_private_state_thread = ThreadLauncher::LaunchThread(thread_name, Process::PrivateStateThread, this, NULL); - if (m_private_state_thread.GetState() == eThreadStateRunning) + if (m_private_state_thread.IsJoinable()) { ResumePrivateStateThread(); return true; @@ -3917,7 +3917,7 @@ // thread starts exiting since the private state thread will NULL this out // when it exits HostThread private_state_thread(m_private_state_thread); - if (private_state_thread.GetState() == eThreadStateRunning) + if (private_state_thread.IsJoinable()) { TimeValue timeout_time; bool timed_out; @@ -5578,7 +5578,7 @@ } // END WAIT LOOP // If we had to start up a temporary private state thread to run this thread plan, shut it down now. - if (backup_private_state_thread.GetState() != eThreadStateInvalid) + if (backup_private_state_thread.IsJoinable()) { StopPrivateStateThread(); Error error; Index: lldb/trunk/tools/lldb-gdbserver/lldb-gdbserver.cpp =================================================================== --- lldb/trunk/tools/lldb-gdbserver/lldb-gdbserver.cpp +++ lldb/trunk/tools/lldb-gdbserver/lldb-gdbserver.cpp @@ -281,7 +281,7 @@ StartListenThread (const char *hostname, uint16_t port) { Error error; - if (s_listen_thread.GetState() == eThreadStateRunning) + if (s_listen_thread.IsJoinable()) { error.SetErrorString("listen thread already running"); } @@ -303,11 +303,8 @@ static bool JoinListenThread () { - if (s_listen_thread.GetState() == eThreadStateRunning) - { + if (s_listen_thread.IsJoinable()) s_listen_thread.Join(nullptr); - s_listen_thread.Reset(); - } return true; }