Fix up the HostThread interface, making the interface simpler.

Reviewed by: Greg Clayton
Differential Revision: http://reviews.llvm.org/D5417

llvm-svn: 218325
This commit is contained in:
Zachary Turner 2014-09-23 18:32:09 +00:00
parent 4364fef82f
commit acee96ae52
19 changed files with 81 additions and 134 deletions

View File

@ -365,7 +365,7 @@ public:
bool
IsHandlingEvents () const
{
return m_event_handler_thread.GetState() == eThreadStateRunning;
return m_event_handler_thread.IsJoinable();
}
protected:

View File

@ -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 @@ class HostNativeThreadBase
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 @@ class HostNativeThreadBase
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;
};
}

View File

@ -40,8 +40,7 @@ class HostThread
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;

View File

@ -1,4 +1,4 @@
//===-- HostThreadWindows.h -------------------------------------*- C++ -*-===//
//===-- HostThreadPosix.h -------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//

View File

@ -3008,7 +3008,7 @@ protected:
bool
PrivateStateThreadIsValid () const
{
return m_private_state_thread.GetState() != eThreadStateInvalid;
return m_private_state_thread.IsJoinable();
}
void

View File

@ -240,18 +240,6 @@ typedef enum ExitType {
eExitTypeStop, // The exit status represents the stop signal that caused the program to exit (i.e. WIFSTOPPED() was true)
} 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
//----------------------------------------------------------------------

View File

@ -233,7 +233,7 @@ Communication::StartReadThread (Error *error_ptr)
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 @@ Communication::StartReadThread (Error *error_ptr)
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 @@ Communication::StartReadThread (Error *error_ptr)
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 @@ Communication::StopReadThread (Error *error_ptr)
// 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();
}

View File

@ -3336,19 +3336,18 @@ Debugger::EventHandlerThread (lldb::thread_arg_t arg)
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 @@ Debugger::IOHandlerThread (lldb::thread_arg_t arg)
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();
}
}

View File

@ -19,30 +19,16 @@ using namespace lldb_private;
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 @@ HostNativeThreadBase::GetResult() const
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 @@ HostNativeThreadBase::Release()
{
lldb::thread_t result = m_thread;
m_thread = LLDB_INVALID_HOST_THREAD;
m_state = eThreadStateInvalid;
m_result = 0;
return result;

View File

@ -47,16 +47,10 @@ HostThread::Release()
return m_native_thread->Release();
}
void
HostThread::SetState(ThreadState state)
bool
HostThread::IsJoinable() const
{
m_native_thread->SetState(state);
}
ThreadState
HostThread::GetState() const
{
return m_native_thread->GetState();
return m_native_thread->IsJoinable();
}
HostNativeThreadBase &

View File

@ -10,8 +10,10 @@
#include "lldb/Core/Error.h"
#include "lldb/Host/posix/HostThreadPosix.h"
#include <errno.h>
#include <pthread.h>
using namespace lldb;
using namespace lldb_private;
HostThreadPosix::HostThreadPosix()
@ -31,13 +33,16 @@ Error
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 @@ HostThreadPosix::Cancel()
{
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 @@ HostThreadPosix::Detach()
{
Error error;
int err = ::pthread_detach(m_thread);
error.SetError(err, lldb::eErrorTypePOSIX);
error.SetError(err, eErrorTypePOSIX);
Reset();
return error;
}

View File

@ -36,21 +36,21 @@ Error
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;
}

View File

@ -1396,7 +1396,7 @@ WAIT_AGAIN:
// 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 @@ WAIT_AGAIN:
// 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 @@ NativeProcessLinux::StartLaunchOpThread(LaunchArgs *args, Error &error)
{
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 @@ NativeProcessLinux::StartAttachOpThread(AttachArgs *args, lldb_private::Error &e
{
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 @@ NativeProcessLinux::DupDescriptor(const char *path, int fd, int flags)
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 @@ NativeProcessLinux::StopMonitor()
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

View File

@ -1199,7 +1199,7 @@ WAIT_AGAIN:
// 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 @@ WAIT_AGAIN:
// 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 @@ ProcessMonitor::StartLaunchOpThread(LaunchArgs *args, Error &error)
{
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 @@ ProcessMonitor::StartAttachOpThread(AttachArgs *args, lldb_private::Error &error
{
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 @@ ProcessMonitor::DupDescriptor(const char *path, int fd, int flags)
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 @@ ProcessMonitor::StopMonitor()
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();
}

View File

@ -469,7 +469,7 @@ ProcessKDP::DoResume ()
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 @@ ProcessKDP::StartAsyncThread ()
if (log)
log->Printf ("ProcessKDP::StartAsyncThread ()");
if (m_async_thread.GetState() == eThreadStateRunning)
if (m_async_thread.IsJoinable())
return true;
m_async_thread = ThreadLauncher::LaunchThread("<lldb.process.kdp-remote.async>", ProcessKDP::AsyncThread, this, NULL);
return m_async_thread.GetState() == eThreadStateRunning;
return m_async_thread.IsJoinable();
}
void
@ -888,11 +888,8 @@ ProcessKDP::StopAsyncThread ()
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();
}
}

View File

@ -634,7 +634,7 @@ Error
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 @@ GDBRemoteCommunication::StartListenThread (const char *hostname, uint16_t port)
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;
}

View File

@ -1432,7 +1432,7 @@ ProcessGDBRemote::DoResume ()
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 @@ ProcessGDBRemote::StartAsyncThread ()
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("<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.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 @@ ProcessGDBRemote::StopAsyncThread ()
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 @@ ProcessGDBRemote::StopAsyncThread ()
// 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__);
}

View File

@ -3867,7 +3867,7 @@ Process::StartPrivateStateThread (bool force)
// 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 @@ Process::ControlPrivateStateThread (uint32_t signal)
// 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 @@ Process::RunThreadPlan (ExecutionContext &exe_ctx,
} // 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;

View File

@ -281,7 +281,7 @@ static Error
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 @@ StartListenThread (const char *hostname, uint16_t port)
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;
}