[Lldb-commits] [lldb] d081077 - [lldb] Modernize ThreadLauncher
Pavel Labath via lldb-commits
lldb-commits at lists.llvm.org
Wed Feb 23 05:26:17 PST 2022
Author: Pavel Labath
Date: 2022-02-23T14:25:59+01:00
New Revision: d0810779b1f310d99176467d5d5b5aa4e26d7eb5
URL: https://github.com/llvm/llvm-project/commit/d0810779b1f310d99176467d5d5b5aa4e26d7eb5
DIFF: https://github.com/llvm/llvm-project/commit/d0810779b1f310d99176467d5d5b5aa4e26d7eb5.diff
LOG: [lldb] Modernize ThreadLauncher
Accept a function object instead of a raw pointer. This avoids a bunch
of boilerplate typically needed to pass arguments to the thread
functions.
Differential Revision: https://reviews.llvm.org/D120321
Added:
lldb/unittests/Host/ThreadLauncherTest.cpp
Modified:
lldb/include/lldb/Core/Communication.h
lldb/include/lldb/Core/Debugger.h
lldb/include/lldb/Host/ThreadLauncher.h
lldb/include/lldb/Target/Process.h
lldb/source/API/SBHostOS.cpp
lldb/source/Core/Communication.cpp
lldb/source/Core/Debugger.cpp
lldb/source/Host/common/Host.cpp
lldb/source/Host/common/HostNativeThreadBase.cpp
lldb/source/Host/common/ThreadLauncher.cpp
lldb/source/Host/macosx/objcxx/Host.mm
lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp
lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.h
lldb/source/Plugins/Process/Windows/Common/DebuggerThread.cpp
lldb/source/Plugins/Process/Windows/Common/DebuggerThread.h
lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h
lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
lldb/source/Target/Process.cpp
lldb/unittests/Host/CMakeLists.txt
Removed:
################################################################################
diff --git a/lldb/include/lldb/Core/Communication.h b/lldb/include/lldb/Core/Communication.h
index fdcb6c5fb9822..44b3a16a05269 100644
--- a/lldb/include/lldb/Core/Communication.h
+++ b/lldb/include/lldb/Core/Communication.h
@@ -277,7 +277,7 @@ class Communication : public Broadcaster {
/// \b True if the read thread is running, \b false otherwise.
bool ReadThreadIsRunning();
- /// The static read thread function. This function will call the "DoRead"
+ /// The read thread function. This function will call the "DoRead"
/// function continuously and wait for data to become available. When data
/// is received it will append the available data to the internal cache and
/// broadcast a \b eBroadcastBitReadThreadGotBytes event.
@@ -289,7 +289,7 @@ class Communication : public Broadcaster {
/// \b NULL.
///
/// \see void Communication::ReadThreadGotBytes (const uint8_t *, size_t);
- static lldb::thread_result_t ReadThread(lldb::thread_arg_t comm_ptr);
+ lldb::thread_result_t ReadThread();
void SetReadThreadBytesReceivedCallback(ReadThreadBytesReceived callback,
void *callback_baton);
diff --git a/lldb/include/lldb/Core/Debugger.h b/lldb/include/lldb/Core/Debugger.h
index f9a1f1eea54f2..d4fae0c5d09cb 100644
--- a/lldb/include/lldb/Core/Debugger.h
+++ b/lldb/include/lldb/Core/Debugger.h
@@ -439,8 +439,6 @@ class Debugger : public std::enable_shared_from_this<Debugger>,
void StopEventHandlerThread();
- static lldb::thread_result_t EventHandlerThread(lldb::thread_arg_t arg);
-
void PushIOHandler(const lldb::IOHandlerSP &reader_sp,
bool cancel_top_handler = true);
@@ -454,9 +452,9 @@ class Debugger : public std::enable_shared_from_this<Debugger>,
void JoinIOHandlerThread();
- static lldb::thread_result_t IOHandlerThread(lldb::thread_arg_t arg);
+ lldb::thread_result_t IOHandlerThread();
- void DefaultEventHandler();
+ lldb::thread_result_t DefaultEventHandler();
void HandleBreakpointEvent(const lldb::EventSP &event_sp);
diff --git a/lldb/include/lldb/Host/ThreadLauncher.h b/lldb/include/lldb/Host/ThreadLauncher.h
index 00b42fa6a11d5..8bb6c79466a76 100644
--- a/lldb/include/lldb/Host/ThreadLauncher.h
+++ b/lldb/include/lldb/Host/ThreadLauncher.h
@@ -20,8 +20,8 @@ namespace lldb_private {
class ThreadLauncher {
public:
static llvm::Expected<HostThread>
- LaunchThread(llvm::StringRef name, lldb::thread_func_t thread_function,
- lldb::thread_arg_t thread_arg,
+ LaunchThread(llvm::StringRef name,
+ std::function<lldb::thread_result_t()> thread_function,
size_t min_stack_byte_size = 0); // Minimum stack size in bytes,
// set stack size to zero for
// default platform thread stack
@@ -29,12 +29,11 @@ class ThreadLauncher {
struct HostThreadCreateInfo {
std::string thread_name;
- lldb::thread_func_t thread_fptr;
- lldb::thread_arg_t thread_arg;
+ std::function<lldb::thread_result_t()> impl;
- HostThreadCreateInfo(const char *name, lldb::thread_func_t fptr,
- lldb::thread_arg_t arg)
- : thread_name(name ? name : ""), thread_fptr(fptr), thread_arg(arg) {}
+ HostThreadCreateInfo(std::string thread_name,
+ std::function<lldb::thread_result_t()> impl)
+ : thread_name(std::move(thread_name)), impl(std::move(impl)) {}
};
};
}
diff --git a/lldb/include/lldb/Target/Process.h b/lldb/include/lldb/Target/Process.h
index adceec619ff04..23debbee705ea 100644
--- a/lldb/include/lldb/Target/Process.h
+++ b/lldb/include/lldb/Target/Process.h
@@ -2989,17 +2989,6 @@ void PruneThreadPlans();
void ResumePrivateStateThread();
private:
- struct PrivateStateThreadArgs {
- PrivateStateThreadArgs(Process *p, bool s)
- : process(p), is_secondary_thread(s){};
- Process *process;
- bool is_secondary_thread;
- };
-
- // arg is a pointer to a new'ed PrivateStateThreadArgs structure.
- // PrivateStateThread will free it for you.
- static lldb::thread_result_t PrivateStateThread(void *arg);
-
// The starts up the private state thread that will watch for events from the
// debugee. Pass true for is_secondary_thread in the case where you have to
// temporarily spin up a secondary state thread to handle events from a hand-
diff --git a/lldb/source/API/SBHostOS.cpp b/lldb/source/API/SBHostOS.cpp
index 06cf654031a1d..cb026fd9203b9 100644
--- a/lldb/source/API/SBHostOS.cpp
+++ b/lldb/source/API/SBHostOS.cpp
@@ -102,7 +102,9 @@ lldb::thread_t SBHostOS::ThreadCreate(const char *name,
void *thread_arg, SBError *error_ptr) {
LLDB_INSTRUMENT_VA(name, thread_function, thread_arg, error_ptr);
llvm::Expected<HostThread> thread =
- ThreadLauncher::LaunchThread(name, thread_function, thread_arg);
+ ThreadLauncher::LaunchThread(name, [thread_function, thread_arg] {
+ return thread_function(thread_arg);
+ });
if (!thread) {
if (error_ptr)
error_ptr->SetError(Status(thread.takeError()));
diff --git a/lldb/source/Core/Communication.cpp b/lldb/source/Core/Communication.cpp
index 0e4d4fc49a429..f41ce46ede88f 100644
--- a/lldb/source/Core/Communication.cpp
+++ b/lldb/source/Core/Communication.cpp
@@ -213,7 +213,7 @@ bool Communication::StartReadThread(Status *error_ptr) {
m_read_thread_enabled = true;
m_read_thread_did_exit = false;
auto maybe_thread = ThreadLauncher::LaunchThread(
- thread_name, Communication::ReadThread, this);
+ thread_name, [this] { return ReadThread(); });
if (maybe_thread) {
m_read_thread = *maybe_thread;
} else {
@@ -311,12 +311,10 @@ size_t Communication::ReadFromConnection(void *dst, size_t dst_len,
bool Communication::ReadThreadIsRunning() { return m_read_thread_enabled; }
-lldb::thread_result_t Communication::ReadThread(lldb::thread_arg_t p) {
- Communication *comm = (Communication *)p;
-
+lldb::thread_result_t Communication::ReadThread() {
Log *log = GetLog(LLDBLog::Communication);
- LLDB_LOGF(log, "%p Communication::ReadThread () thread starting...", p);
+ LLDB_LOG(log, "Communication({0}) thread starting...", this);
uint8_t buf[1024];
@@ -324,11 +322,11 @@ lldb::thread_result_t Communication::ReadThread(lldb::thread_arg_t p) {
ConnectionStatus status = eConnectionStatusSuccess;
bool done = false;
bool disconnect = false;
- while (!done && comm->m_read_thread_enabled) {
- size_t bytes_read = comm->ReadFromConnection(
+ while (!done && m_read_thread_enabled) {
+ size_t bytes_read = ReadFromConnection(
buf, sizeof(buf), std::chrono::seconds(5), status, &error);
if (bytes_read > 0 || status == eConnectionStatusEndOfFile)
- comm->AppendBytesToCache(buf, bytes_read, true, status);
+ AppendBytesToCache(buf, bytes_read, true, status);
switch (status) {
case eConnectionStatusSuccess:
@@ -336,12 +334,12 @@ lldb::thread_result_t Communication::ReadThread(lldb::thread_arg_t p) {
case eConnectionStatusEndOfFile:
done = true;
- disconnect = comm->GetCloseOnEOF();
+ disconnect = GetCloseOnEOF();
break;
case eConnectionStatusError: // Check GetError() for details
if (error.GetType() == eErrorTypePOSIX && error.GetError() == EIO) {
// EIO on a pipe is usually caused by remote shutdown
- disconnect = comm->GetCloseOnEOF();
+ disconnect = GetCloseOnEOF();
done = true;
}
if (error.Fail())
@@ -352,7 +350,7 @@ lldb::thread_result_t Communication::ReadThread(lldb::thread_arg_t p) {
// SynchronizeWithReadThread()
// The connection returns eConnectionStatusInterrupted only when there is
// no input pending to be read, so we can signal that.
- comm->BroadcastEvent(eBroadcastBitNoMorePendingInput);
+ BroadcastEvent(eBroadcastBitNoMorePendingInput);
break;
case eConnectionStatusNoConnection: // No connection
case eConnectionStatusLostConnection: // Lost connection while connected to
@@ -367,26 +365,25 @@ lldb::thread_result_t Communication::ReadThread(lldb::thread_arg_t p) {
}
}
log = GetLog(LLDBLog::Communication);
- if (log)
- LLDB_LOGF(log, "%p Communication::ReadThread () thread exiting...", p);
+ LLDB_LOG(log, "Communication({0}) thread exiting...", this);
// Handle threads wishing to synchronize with us.
{
// Prevent new ones from showing up.
- comm->m_read_thread_did_exit = true;
+ m_read_thread_did_exit = true;
// Unblock any existing thread waiting for the synchronization signal.
- comm->BroadcastEvent(eBroadcastBitNoMorePendingInput);
+ BroadcastEvent(eBroadcastBitNoMorePendingInput);
// Wait for the thread to finish...
- std::lock_guard<std::mutex> guard(comm->m_synchronize_mutex);
+ std::lock_guard<std::mutex> guard(m_synchronize_mutex);
// ... and disconnect.
if (disconnect)
- comm->Disconnect();
+ Disconnect();
}
// Let clients know that this thread is exiting
- comm->BroadcastEvent(eBroadcastBitReadThreadDidExit);
+ BroadcastEvent(eBroadcastBitReadThreadDidExit);
return {};
}
diff --git a/lldb/source/Core/Debugger.cpp b/lldb/source/Core/Debugger.cpp
index b4ef65c2a87f0..ae4fb93e6d4af 100644
--- a/lldb/source/Core/Debugger.cpp
+++ b/lldb/source/Core/Debugger.cpp
@@ -1576,7 +1576,7 @@ void Debugger::CancelForwardEvents(const ListenerSP &listener_sp) {
m_forward_listener_sp.reset();
}
-void Debugger::DefaultEventHandler() {
+lldb::thread_result_t Debugger::DefaultEventHandler() {
ListenerSP listener_sp(GetListener());
ConstString broadcaster_class_target(Target::GetStaticBroadcasterClass());
ConstString broadcaster_class_process(Process::GetStaticBroadcasterClass());
@@ -1662,10 +1662,6 @@ void Debugger::DefaultEventHandler() {
}
}
}
-}
-
-lldb::thread_result_t Debugger::EventHandlerThread(lldb::thread_arg_t arg) {
- ((Debugger *)arg)->DefaultEventHandler();
return {};
}
@@ -1687,8 +1683,9 @@ bool Debugger::StartEventHandlerThread() {
// Use larger 8MB stack for this thread
llvm::Expected<HostThread> event_handler_thread =
- ThreadLauncher::LaunchThread(thread_name, EventHandlerThread, this,
- g_debugger_event_thread_stack_bytes);
+ ThreadLauncher::LaunchThread(
+ thread_name, [this] { return DefaultEventHandler(); },
+ g_debugger_event_thread_stack_bytes);
if (event_handler_thread) {
m_event_handler_thread = *event_handler_thread;
@@ -1716,10 +1713,9 @@ void Debugger::StopEventHandlerThread() {
}
}
-lldb::thread_result_t Debugger::IOHandlerThread(lldb::thread_arg_t arg) {
- Debugger *debugger = (Debugger *)arg;
- debugger->RunIOHandlers();
- debugger->StopEventHandlerThread();
+lldb::thread_result_t Debugger::IOHandlerThread() {
+ RunIOHandlers();
+ StopEventHandlerThread();
return {};
}
@@ -1728,7 +1724,7 @@ bool Debugger::HasIOHandlerThread() { return m_io_handler_thread.IsJoinable(); }
bool Debugger::StartIOHandlerThread() {
if (!m_io_handler_thread.IsJoinable()) {
llvm::Expected<HostThread> io_handler_thread = ThreadLauncher::LaunchThread(
- "lldb.debugger.io-handler", IOHandlerThread, this,
+ "lldb.debugger.io-handler", [this] { return IOHandlerThread(); },
8 * 1024 * 1024); // Use larger 8MB stack for this thread
if (io_handler_thread) {
m_io_handler_thread = *io_handler_thread;
diff --git a/lldb/source/Host/common/Host.cpp b/lldb/source/Host/common/Host.cpp
index f6cb82408e3c5..8bfc54aa387ee 100644
--- a/lldb/source/Host/common/Host.cpp
+++ b/lldb/source/Host/common/Host.cpp
@@ -92,29 +92,22 @@ using namespace lldb;
using namespace lldb_private;
#if !defined(__APPLE__) && !defined(_WIN32)
-struct MonitorInfo {
- lldb::pid_t pid; // The process ID to monitor
- Host::MonitorChildProcessCallback
- callback; // The callback function to call when "pid" exits or signals
- bool monitor_signals; // If true, call the callback when "pid" gets signaled.
-};
-
-static thread_result_t MonitorChildProcessThreadFunction(void *arg);
+static thread_result_t
+MonitorChildProcessThreadFunction(::pid_t pid,
+ Host::MonitorChildProcessCallback callback,
+ bool monitor_signals);
llvm::Expected<HostThread> Host::StartMonitoringChildProcess(
const Host::MonitorChildProcessCallback &callback, lldb::pid_t pid,
bool monitor_signals) {
- MonitorInfo *info_ptr = new MonitorInfo();
-
- info_ptr->pid = pid;
- info_ptr->callback = callback;
- info_ptr->monitor_signals = monitor_signals;
-
char thread_name[256];
::snprintf(thread_name, sizeof(thread_name),
"<lldb.host.wait4(pid=%" PRIu64 ")>", pid);
- return ThreadLauncher::LaunchThread(
- thread_name, MonitorChildProcessThreadFunction, info_ptr, 0);
+ assert(pid <= UINT32_MAX);
+ return ThreadLauncher::LaunchThread(thread_name, [pid, callback,
+ monitor_signals] {
+ return MonitorChildProcessThreadFunction(pid, callback, monitor_signals);
+ });
}
#ifndef __linux__
@@ -163,20 +156,14 @@ static bool CheckForMonitorCancellation() {
return false;
}
-static thread_result_t MonitorChildProcessThreadFunction(void *arg) {
+static thread_result_t
+MonitorChildProcessThreadFunction(::pid_t pid,
+ Host::MonitorChildProcessCallback callback,
+ bool monitor_signals) {
Log *log = GetLog(LLDBLog::Process);
- const char *function = __FUNCTION__;
- LLDB_LOGF(log, "%s (arg = %p) thread starting...", function, arg);
-
- MonitorInfo *info = (MonitorInfo *)arg;
+ LLDB_LOG(log, "pid = {0}, monitor_signals = {1}", pid, monitor_signals);
- const Host::MonitorChildProcessCallback callback = info->callback;
- const bool monitor_signals = info->monitor_signals;
-
- assert(info->pid <= UINT32_MAX);
- const ::pid_t pid = monitor_signals ? -1 * getpgid(info->pid) : info->pid;
-
- delete info;
+ pid = monitor_signals ? -1 * getpgid(pid) : pid;
int status = -1;
#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__OpenBSD__)
@@ -194,8 +181,7 @@ static thread_result_t MonitorChildProcessThreadFunction(void *arg) {
while (true) {
log = GetLog(LLDBLog::Process);
- LLDB_LOGF(log, "%s ::waitpid (pid = %" PRIi32 ", &status, options = %i)...",
- function, pid, options);
+ LLDB_LOG(log, "::waitpid({0}, &status, {1})...", pid, options);
if (CheckForMonitorCancellation())
break;
@@ -211,8 +197,8 @@ static thread_result_t MonitorChildProcessThreadFunction(void *arg) {
continue;
else {
LLDB_LOG(log,
- "arg = {0}, thread exiting because waitpid failed ({1})...",
- arg, llvm::sys::StrError());
+ "pid = {0}, thread exiting because waitpid failed ({1})...",
+ pid, llvm::sys::StrError());
break;
}
} else if (wait_pid > 0) {
@@ -245,12 +231,11 @@ static thread_result_t MonitorChildProcessThreadFunction(void *arg) {
#endif
log = GetLog(LLDBLog::Process);
- LLDB_LOGF(log,
- "%s ::waitpid (pid = %" PRIi32
- ", &status, options = %i) => pid = %" PRIi32
- ", status = 0x%8.8x (%s), signal = %i, exit_state = %i",
- function, pid, options, wait_pid, status, status_cstr, signal,
- exit_status);
+ LLDB_LOG(log,
+ "::waitpid({0}, &status, {1}) => pid = {2}, status = {3:x} "
+ "({4}), signal = {5}, exit_state = {6}",
+ pid, options, wait_pid, status, status_cstr, signal,
+ exit_status);
if (exited || (signal != 0 && monitor_signals)) {
bool callback_return = false;
@@ -259,18 +244,18 @@ static thread_result_t MonitorChildProcessThreadFunction(void *arg) {
// If our process exited, then this thread should exit
if (exited && wait_pid == abs(pid)) {
- LLDB_LOGF(log,
- "%s (arg = %p) thread exiting because pid received "
- "exit signal...",
- __FUNCTION__, arg);
+ LLDB_LOG(
+ log,
+ "pid = {0} thread exiting because pid received exit signal...",
+ pid);
break;
}
// If the callback returns true, it means this process should exit
if (callback_return) {
- LLDB_LOGF(log,
- "%s (arg = %p) thread exiting because callback "
- "returned true...",
- __FUNCTION__, arg);
+ LLDB_LOG(
+ log,
+ "pid = {0} thread exiting because callback returned true...",
+ pid);
break;
}
}
@@ -278,9 +263,7 @@ static thread_result_t MonitorChildProcessThreadFunction(void *arg) {
}
}
- log = GetLog(LLDBLog::Process);
- LLDB_LOGF(log, "%s (arg = %p) thread exiting...", __FUNCTION__, arg);
-
+ LLDB_LOG(GetLog(LLDBLog::Process), "pid = {0} thread exiting...", pid);
return nullptr;
}
diff --git a/lldb/source/Host/common/HostNativeThreadBase.cpp b/lldb/source/Host/common/HostNativeThreadBase.cpp
index 4e69306e4d659..5814a7fd54bb5 100644
--- a/lldb/source/Host/common/HostNativeThreadBase.cpp
+++ b/lldb/source/Host/common/HostNativeThreadBase.cpp
@@ -52,16 +52,12 @@ lldb::thread_t HostNativeThreadBase::Release() {
lldb::thread_result_t
HostNativeThreadBase::ThreadCreateTrampoline(lldb::thread_arg_t arg) {
- ThreadLauncher::HostThreadCreateInfo *info =
- (ThreadLauncher::HostThreadCreateInfo *)arg;
- llvm::set_thread_name(info->thread_name);
-
- thread_func_t thread_fptr = info->thread_fptr;
- thread_arg_t thread_arg = info->thread_arg;
+ std::unique_ptr<ThreadLauncher::HostThreadCreateInfo> info_up(
+ (ThreadLauncher::HostThreadCreateInfo *)arg);
+ llvm::set_thread_name(info_up->thread_name);
Log *log = GetLog(LLDBLog::Thread);
LLDB_LOGF(log, "thread created");
- delete info;
- return thread_fptr(thread_arg);
+ return info_up->impl();
}
diff --git a/lldb/source/Host/common/ThreadLauncher.cpp b/lldb/source/Host/common/ThreadLauncher.cpp
index bd104b3e4aed2..28c90215f8747 100644
--- a/lldb/source/Host/common/ThreadLauncher.cpp
+++ b/lldb/source/Host/common/ThreadLauncher.cpp
@@ -21,17 +21,18 @@
using namespace lldb;
using namespace lldb_private;
-llvm::Expected<HostThread> ThreadLauncher::LaunchThread(
- llvm::StringRef name, lldb::thread_func_t thread_function,
- lldb::thread_arg_t thread_arg, size_t min_stack_byte_size) {
- // Host::ThreadCreateTrampoline will delete this pointer for us.
- HostThreadCreateInfo *info_ptr =
- new HostThreadCreateInfo(name.data(), thread_function, thread_arg);
+llvm::Expected<HostThread>
+ThreadLauncher::LaunchThread(llvm::StringRef name,
+ std::function<thread_result_t()> impl,
+ size_t min_stack_byte_size) {
+ // Host::ThreadCreateTrampoline will take ownership if thread creation is
+ // successful.
+ auto info_up = std::make_unique<HostThreadCreateInfo>(name.str(), impl);
lldb::thread_t thread;
#ifdef _WIN32
thread = (lldb::thread_t)::_beginthreadex(
0, (unsigned)min_stack_byte_size,
- HostNativeThread::ThreadCreateTrampoline, info_ptr, 0, NULL);
+ HostNativeThread::ThreadCreateTrampoline, info_up.get(), 0, NULL);
if (thread == LLDB_INVALID_HOST_THREAD)
return llvm::errorCodeToError(llvm::mapWindowsError(GetLastError()));
#else
@@ -63,7 +64,7 @@ llvm::Expected<HostThread> ThreadLauncher::LaunchThread(
}
int err =
::pthread_create(&thread, thread_attr_ptr,
- HostNativeThread::ThreadCreateTrampoline, info_ptr);
+ HostNativeThread::ThreadCreateTrampoline, info_up.get());
if (destroy_attr)
::pthread_attr_destroy(&thread_attr);
@@ -73,5 +74,6 @@ llvm::Expected<HostThread> ThreadLauncher::LaunchThread(
std::error_code(err, std::generic_category()));
#endif
+ info_up.release();
return HostThread(thread);
}
diff --git a/lldb/source/Host/macosx/objcxx/Host.mm b/lldb/source/Host/macosx/objcxx/Host.mm
index 969173e7122cd..ab2c295004e4c 100644
--- a/lldb/source/Host/macosx/objcxx/Host.mm
+++ b/lldb/source/Host/macosx/objcxx/Host.mm
@@ -136,8 +136,7 @@
#if TARGET_OS_OSX
-static void *AcceptPIDFromInferior(void *arg) {
- const char *connect_url = (const char *)arg;
+static void *AcceptPIDFromInferior(const char *connect_url) {
ConnectionFileDescriptor file_conn;
Status error;
if (file_conn.Connect(connect_url, &error) == eConnectionStatusSuccess) {
@@ -286,7 +285,7 @@ repeat with the_window in (get windows)\n\
// to the process that we wanted to launch. So when our process actually
// gets launched, we will handshake with it and get the process ID for it.
llvm::Expected<HostThread> accept_thread = ThreadLauncher::LaunchThread(
- unix_socket_name, AcceptPIDFromInferior, connect_url);
+ unix_socket_name, [&] { return AcceptPIDFromInferior(connect_url); });
if (!accept_thread)
return Status(accept_thread.takeError());
diff --git a/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp b/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp
index 65112275892a3..8843dc87e5cbf 100644
--- a/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp
+++ b/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp
@@ -724,7 +724,7 @@ bool ProcessKDP::StartAsyncThread() {
return true;
llvm::Expected<HostThread> async_thread = ThreadLauncher::LaunchThread(
- "<lldb.process.kdp-remote.async>", ProcessKDP::AsyncThread, this);
+ "<lldb.process.kdp-remote.async>", [this] { return AsyncThread(); });
if (!async_thread) {
LLDB_LOG_ERROR(GetLog(LLDBLog::Host), async_thread.takeError(),
"failed to launch host thread: {}");
@@ -746,25 +746,21 @@ void ProcessKDP::StopAsyncThread() {
m_async_thread.Join(nullptr);
}
-void *ProcessKDP::AsyncThread(void *arg) {
- ProcessKDP *process = (ProcessKDP *)arg;
-
- const lldb::pid_t pid = process->GetID();
+void *ProcessKDP::AsyncThread() {
+ const lldb::pid_t pid = GetID();
Log *log = GetLog(KDPLog::Process);
LLDB_LOGF(log,
- "ProcessKDP::AsyncThread (arg = %p, pid = %" PRIu64
- ") thread starting...",
- arg, pid);
+ "ProcessKDP::AsyncThread(pid = %" PRIu64 ") thread starting...",
+ pid);
ListenerSP listener_sp(Listener::MakeListener("ProcessKDP::AsyncThread"));
EventSP event_sp;
const uint32_t desired_event_mask =
eBroadcastBitAsyncContinue | eBroadcastBitAsyncThreadShouldExit;
- if (listener_sp->StartListeningForEvents(&process->m_async_broadcaster,
- desired_event_mask) ==
- desired_event_mask) {
+ if (listener_sp->StartListeningForEvents(
+ &m_async_broadcaster, desired_event_mask) == desired_event_mask) {
bool done = false;
while (!done) {
LLDB_LOGF(log,
@@ -787,9 +783,9 @@ void *ProcessKDP::AsyncThread(void *arg) {
switch (event_type) {
case eBroadcastBitAsyncContinue: {
is_running = true;
- if (process->m_comm.WaitForPacketWithTimeoutMicroSeconds(
+ if (m_comm.WaitForPacketWithTimeoutMicroSeconds(
exc_reply_packet, 1 * USEC_PER_SEC)) {
- ThreadSP thread_sp(process->GetKernelThread());
+ ThreadSP thread_sp(GetKernelThread());
if (thread_sp) {
lldb::RegisterContextSP reg_ctx_sp(
thread_sp->GetRegisterContext());
@@ -801,7 +797,7 @@ void *ProcessKDP::AsyncThread(void *arg) {
// TODO: parse the stop reply packet
is_running = false;
- process->SetPrivateState(eStateStopped);
+ SetPrivateState(eStateStopped);
} else {
// Check to see if we are supposed to exit. There is no way to
// interrupt a running kernel, so all we can do is wait for an
@@ -843,12 +839,10 @@ void *ProcessKDP::AsyncThread(void *arg) {
}
}
- LLDB_LOGF(log,
- "ProcessKDP::AsyncThread (arg = %p, pid = %" PRIu64
- ") thread exiting...",
- arg, pid);
+ LLDB_LOGF(log, "ProcessKDP::AsyncThread(pid = %" PRIu64 ") thread exiting...",
+ pid);
- process->m_async_thread.Reset();
+ m_async_thread.Reset();
return NULL;
}
diff --git a/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.h b/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.h
index 3386354d0b4cb..a8cfb0ec9f870 100644
--- a/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.h
+++ b/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.h
@@ -179,7 +179,7 @@ class ProcessKDP : public lldb_private::Process {
void StopAsyncThread();
- static void *AsyncThread(void *arg);
+ void *AsyncThread();
private:
// For ProcessKDP only
diff --git a/lldb/source/Plugins/Process/Windows/Common/DebuggerThread.cpp b/lldb/source/Plugins/Process/Windows/Common/DebuggerThread.cpp
index a78ca2aabe134..e442650f0920e 100644
--- a/lldb/source/Plugins/Process/Windows/Common/DebuggerThread.cpp
+++ b/lldb/source/Plugins/Process/Windows/Common/DebuggerThread.cpp
@@ -36,25 +36,6 @@
using namespace lldb;
using namespace lldb_private;
-namespace {
-struct DebugLaunchContext {
- DebugLaunchContext(DebuggerThread *thread,
- const ProcessLaunchInfo &launch_info)
- : m_thread(thread), m_launch_info(launch_info) {}
- DebuggerThread *m_thread;
- ProcessLaunchInfo m_launch_info;
-};
-
-struct DebugAttachContext {
- DebugAttachContext(DebuggerThread *thread, lldb::pid_t pid,
- const ProcessAttachInfo &attach_info)
- : m_thread(thread), m_pid(pid), m_attach_info(attach_info) {}
- DebuggerThread *m_thread;
- lldb::pid_t m_pid;
- ProcessAttachInfo m_attach_info;
-};
-} // namespace
-
DebuggerThread::DebuggerThread(DebugDelegateSP debug_delegate)
: m_debug_delegate(debug_delegate), m_pid_to_detach(0),
m_is_shutting_down(false) {
@@ -68,11 +49,9 @@ Status DebuggerThread::DebugLaunch(const ProcessLaunchInfo &launch_info) {
LLDB_LOG(log, "launching '{0}'", launch_info.GetExecutableFile().GetPath());
Status result;
- DebugLaunchContext *context = new DebugLaunchContext(this, launch_info);
-
- llvm::Expected<HostThread> secondary_thread =
- ThreadLauncher::LaunchThread("lldb.plugin.process-windows.secondary[?]",
- DebuggerThreadLaunchRoutine, context);
+ llvm::Expected<HostThread> secondary_thread = ThreadLauncher::LaunchThread(
+ "lldb.plugin.process-windows.secondary[?]",
+ [this, launch_info] { return DebuggerThreadLaunchRoutine(launch_info); });
if (!secondary_thread) {
result = Status(secondary_thread.takeError());
LLDB_LOG(log, "couldn't launch debugger thread. {0}", result);
@@ -87,11 +66,10 @@ Status DebuggerThread::DebugAttach(lldb::pid_t pid,
LLDB_LOG(log, "attaching to '{0}'", pid);
Status result;
- DebugAttachContext *context = new DebugAttachContext(this, pid, attach_info);
-
- llvm::Expected<HostThread> secondary_thread =
- ThreadLauncher::LaunchThread("lldb.plugin.process-windows.secondary[?]",
- DebuggerThreadAttachRoutine, context);
+ llvm::Expected<HostThread> secondary_thread = ThreadLauncher::LaunchThread(
+ "lldb.plugin.process-windows.secondary[?]", [this, pid, attach_info] {
+ return DebuggerThreadAttachRoutine(pid, attach_info);
+ });
if (!secondary_thread) {
result = Status(secondary_thread.takeError());
LLDB_LOG(log, "couldn't attach to process '{0}'. {1}", pid, result);
@@ -100,22 +78,6 @@ Status DebuggerThread::DebugAttach(lldb::pid_t pid,
return result;
}
-lldb::thread_result_t DebuggerThread::DebuggerThreadLaunchRoutine(void *data) {
- DebugLaunchContext *context = static_cast<DebugLaunchContext *>(data);
- lldb::thread_result_t result =
- context->m_thread->DebuggerThreadLaunchRoutine(context->m_launch_info);
- delete context;
- return result;
-}
-
-lldb::thread_result_t DebuggerThread::DebuggerThreadAttachRoutine(void *data) {
- DebugAttachContext *context = static_cast<DebugAttachContext *>(data);
- lldb::thread_result_t result = context->m_thread->DebuggerThreadAttachRoutine(
- context->m_pid, context->m_attach_info);
- delete context;
- return result;
-}
-
lldb::thread_result_t DebuggerThread::DebuggerThreadLaunchRoutine(
const ProcessLaunchInfo &launch_info) {
// Grab a shared_ptr reference to this so that we know it won't get deleted
diff --git a/lldb/source/Plugins/Process/Windows/Common/DebuggerThread.h b/lldb/source/Plugins/Process/Windows/Common/DebuggerThread.h
index 56701307fd757..e3439ff34584b 100644
--- a/lldb/source/Plugins/Process/Windows/Common/DebuggerThread.h
+++ b/lldb/source/Plugins/Process/Windows/Common/DebuggerThread.h
@@ -91,10 +91,8 @@ class DebuggerThread : public std::enable_shared_from_this<DebuggerThread> {
// exit.
bool m_detached = false;
- static lldb::thread_result_t DebuggerThreadLaunchRoutine(void *data);
lldb::thread_result_t
DebuggerThreadLaunchRoutine(const ProcessLaunchInfo &launch_info);
- static lldb::thread_result_t DebuggerThreadAttachRoutine(void *data);
lldb::thread_result_t
DebuggerThreadAttachRoutine(lldb::pid_t pid,
const ProcessAttachInfo &launch_info);
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
index 38d9e400978d2..d660a4d070421 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
@@ -843,7 +843,7 @@ Status GDBRemoteCommunication::StartListenThread(const char *hostname,
m_listen_url = listen_url;
SetConnection(std::make_unique<ConnectionFileDescriptor>());
llvm::Expected<HostThread> listen_thread = ThreadLauncher::LaunchThread(
- listen_url, GDBRemoteCommunication::ListenThread, this);
+ listen_url, [this] { return GDBRemoteCommunication::ListenThread(); });
if (!listen_thread)
return Status(listen_thread.takeError());
m_listen_thread = *listen_thread;
@@ -857,23 +857,22 @@ bool GDBRemoteCommunication::JoinListenThread() {
return true;
}
-lldb::thread_result_t
-GDBRemoteCommunication::ListenThread(lldb::thread_arg_t arg) {
- GDBRemoteCommunication *comm = (GDBRemoteCommunication *)arg;
+lldb::thread_result_t GDBRemoteCommunication::ListenThread() {
Status error;
ConnectionFileDescriptor *connection =
- (ConnectionFileDescriptor *)comm->GetConnection();
+ (ConnectionFileDescriptor *)GetConnection();
if (connection) {
// Do the listen on another thread so we can continue on...
if (connection->Connect(
- comm->m_listen_url.c_str(), [comm](llvm::StringRef port_str) {
+ m_listen_url.c_str(),
+ [this](llvm::StringRef port_str) {
uint16_t port = 0;
llvm::to_integer(port_str, port, 10);
- comm->m_port_promise.set_value(port);
+ m_port_promise.set_value(port);
},
&error) != eConnectionStatusSuccess)
- comm->SetConnection(nullptr);
+ SetConnection(nullptr);
}
return {};
}
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h
index afc7e740d4c96..a325baa59ba3e 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h
@@ -218,7 +218,7 @@ class GDBRemoteCommunication : public Communication {
bool JoinListenThread();
- static lldb::thread_result_t ListenThread(lldb::thread_arg_t arg);
+ lldb::thread_result_t ListenThread();
private:
// Promise used to grab the port number from listening thread
diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
index c40e738cae515..3f5cb1606f21b 100644
--- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
@@ -3541,8 +3541,10 @@ bool ProcessGDBRemote::StartAsyncThread() {
// Create a thread that watches our internal state and controls which
// events make it to clients (into the DCProcess event queue).
- llvm::Expected<HostThread> async_thread = ThreadLauncher::LaunchThread(
- "<lldb.process.gdb-remote.async>", ProcessGDBRemote::AsyncThread, this);
+ llvm::Expected<HostThread> async_thread =
+ ThreadLauncher::LaunchThread("<lldb.process.gdb-remote.async>", [this] {
+ return ProcessGDBRemote::AsyncThread();
+ });
if (!async_thread) {
LLDB_LOG_ERROR(GetLog(LLDBLog::Host), async_thread.takeError(),
"failed to launch host thread: {}");
@@ -3580,14 +3582,10 @@ void ProcessGDBRemote::StopAsyncThread() {
__FUNCTION__);
}
-thread_result_t ProcessGDBRemote::AsyncThread(void *arg) {
- ProcessGDBRemote *process = (ProcessGDBRemote *)arg;
-
+thread_result_t ProcessGDBRemote::AsyncThread() {
Log *log = GetLog(GDBRLog::Process);
- LLDB_LOGF(log,
- "ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64
- ") thread starting...",
- __FUNCTION__, arg, process->GetID());
+ LLDB_LOGF(log, "ProcessGDBRemote::%s(pid = %" PRIu64 ") thread starting...",
+ __FUNCTION__, GetID());
EventSP event_sp;
@@ -3603,19 +3601,19 @@ thread_result_t ProcessGDBRemote::AsyncThread(void *arg) {
// fetch loop.
bool done = false;
- while (!done && process->GetPrivateState() != eStateExited) {
+ while (!done && GetPrivateState() != eStateExited) {
LLDB_LOGF(log,
- "ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64
+ "ProcessGDBRemote::%s(pid = %" PRIu64
") listener.WaitForEvent (NULL, event_sp)...",
- __FUNCTION__, arg, process->GetID());
+ __FUNCTION__, GetID());
- if (process->m_async_listener_sp->GetEvent(event_sp, llvm::None)) {
+ if (m_async_listener_sp->GetEvent(event_sp, llvm::None)) {
const uint32_t event_type = event_sp->GetType();
- if (event_sp->BroadcasterIs(&process->m_async_broadcaster)) {
+ if (event_sp->BroadcasterIs(&m_async_broadcaster)) {
LLDB_LOGF(log,
- "ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64
+ "ProcessGDBRemote::%s(pid = %" PRIu64
") Got an event of type: %d...",
- __FUNCTION__, arg, process->GetID(), event_type);
+ __FUNCTION__, GetID(), event_type);
switch (event_type) {
case eBroadcastBitAsyncContinue: {
@@ -3627,39 +3625,39 @@ thread_result_t ProcessGDBRemote::AsyncThread(void *arg) {
(const char *)continue_packet->GetBytes();
const size_t continue_cstr_len = continue_packet->GetByteSize();
LLDB_LOGF(log,
- "ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64
+ "ProcessGDBRemote::%s(pid = %" PRIu64
") got eBroadcastBitAsyncContinue: %s",
- __FUNCTION__, arg, process->GetID(), continue_cstr);
+ __FUNCTION__, GetID(), continue_cstr);
if (::strstr(continue_cstr, "vAttach") == nullptr)
- process->SetPrivateState(eStateRunning);
+ SetPrivateState(eStateRunning);
StringExtractorGDBRemote response;
StateType stop_state =
- process->GetGDBRemote().SendContinuePacketAndWaitForResponse(
- *process, *process->GetUnixSignals(),
+ GetGDBRemote().SendContinuePacketAndWaitForResponse(
+ *this, *GetUnixSignals(),
llvm::StringRef(continue_cstr, continue_cstr_len),
- process->GetInterruptTimeout(), response);
+ GetInterruptTimeout(), response);
// We need to immediately clear the thread ID list so we are sure
// to get a valid list of threads. The thread ID list might be
// contained within the "response", or the stop reply packet that
// caused the stop. So clear it now before we give the stop reply
// packet to the process using the
- // process->SetLastStopPacket()...
- process->ClearThreadIDList();
+ // SetLastStopPacket()...
+ ClearThreadIDList();
switch (stop_state) {
case eStateStopped:
case eStateCrashed:
case eStateSuspended:
- process->SetLastStopPacket(response);
- process->SetPrivateState(stop_state);
+ SetLastStopPacket(response);
+ SetPrivateState(stop_state);
break;
case eStateExited: {
- process->SetLastStopPacket(response);
- process->ClearThreadIDList();
+ SetLastStopPacket(response);
+ ClearThreadIDList();
response.SetFilePos(1);
int exit_status = response.GetHexU8();
@@ -3674,7 +3672,7 @@ thread_result_t ProcessGDBRemote::AsyncThread(void *arg) {
extractor.GetHexByteString(desc_string);
}
}
- process->SetExitStatus(exit_status, desc_string.c_str());
+ SetExitStatus(exit_status, desc_string.c_str());
done = true;
break;
}
@@ -3685,20 +3683,20 @@ thread_result_t ProcessGDBRemote::AsyncThread(void *arg) {
// helpful error message about why the attach failed.
if (::strstr(continue_cstr, "vAttach") != nullptr &&
response.GetError() == 0x87) {
- process->SetExitStatus(-1, "cannot attach to process due to "
- "System Integrity Protection");
+ SetExitStatus(-1, "cannot attach to process due to "
+ "System Integrity Protection");
} else if (::strstr(continue_cstr, "vAttach") != nullptr &&
response.GetStatus().Fail()) {
- process->SetExitStatus(-1, response.GetStatus().AsCString());
+ SetExitStatus(-1, response.GetStatus().AsCString());
} else {
- process->SetExitStatus(-1, "lost connection");
+ SetExitStatus(-1, "lost connection");
}
done = true;
break;
}
default:
- process->SetPrivateState(stop_state);
+ SetPrivateState(stop_state);
break;
} // switch(stop_state)
} // if (continue_packet)
@@ -3707,49 +3705,47 @@ thread_result_t ProcessGDBRemote::AsyncThread(void *arg) {
case eBroadcastBitAsyncThreadShouldExit:
LLDB_LOGF(log,
- "ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64
+ "ProcessGDBRemote::%s(pid = %" PRIu64
") got eBroadcastBitAsyncThreadShouldExit...",
- __FUNCTION__, arg, process->GetID());
+ __FUNCTION__, GetID());
done = true;
break;
default:
LLDB_LOGF(log,
- "ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64
+ "ProcessGDBRemote::%s(pid = %" PRIu64
") got unknown event 0x%8.8x",
- __FUNCTION__, arg, process->GetID(), event_type);
+ __FUNCTION__, GetID(), event_type);
done = true;
break;
}
- } else if (event_sp->BroadcasterIs(&process->m_gdb_comm)) {
+ } else if (event_sp->BroadcasterIs(&m_gdb_comm)) {
switch (event_type) {
case Communication::eBroadcastBitReadThreadDidExit:
- process->SetExitStatus(-1, "lost connection");
+ SetExitStatus(-1, "lost connection");
done = true;
break;
default:
LLDB_LOGF(log,
- "ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64
+ "ProcessGDBRemote::%s(pid = %" PRIu64
") got unknown event 0x%8.8x",
- __FUNCTION__, arg, process->GetID(), event_type);
+ __FUNCTION__, GetID(), event_type);
done = true;
break;
}
}
} else {
LLDB_LOGF(log,
- "ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64
+ "ProcessGDBRemote::%s(pid = %" PRIu64
") listener.WaitForEvent (NULL, event_sp) => false",
- __FUNCTION__, arg, process->GetID());
+ __FUNCTION__, GetID());
done = true;
}
}
- LLDB_LOGF(log,
- "ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64
- ") thread exiting...",
- __FUNCTION__, arg, process->GetID());
+ LLDB_LOGF(log, "ProcessGDBRemote::%s(pid = %" PRIu64 ") thread exiting...",
+ __FUNCTION__, GetID());
return {};
}
diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
index dd907042608da..47b329eba731c 100644
--- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
+++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
@@ -342,7 +342,7 @@ class ProcessGDBRemote : public Process,
void StopAsyncThread();
- static lldb::thread_result_t AsyncThread(void *arg);
+ lldb::thread_result_t AsyncThread();
static bool
MonitorDebugserverProcess(std::weak_ptr<ProcessGDBRemote> process_wp,
diff --git a/lldb/source/Target/Process.cpp b/lldb/source/Target/Process.cpp
index c70bfcfc448de..cbb10a0ac8506 100644
--- a/lldb/source/Target/Process.cpp
+++ b/lldb/source/Target/Process.cpp
@@ -3509,12 +3509,13 @@ bool Process::StartPrivateStateThread(bool is_secondary_thread) {
"<lldb.process.internal-state(pid=%" PRIu64 ")>", GetID());
}
- // Create the private state thread, and start it running.
- PrivateStateThreadArgs *args_ptr =
- new PrivateStateThreadArgs(this, is_secondary_thread);
llvm::Expected<HostThread> private_state_thread =
- ThreadLauncher::LaunchThread(thread_name, Process::PrivateStateThread,
- (void *)args_ptr, 8 * 1024 * 1024);
+ ThreadLauncher::LaunchThread(
+ thread_name,
+ [this, is_secondary_thread] {
+ return RunPrivateStateThread(is_secondary_thread);
+ },
+ 8 * 1024 * 1024);
if (!private_state_thread) {
LLDB_LOG(GetLog(LLDBLog::Host), "failed to launch host thread: {}",
llvm::toString(private_state_thread.takeError()));
@@ -3729,14 +3730,6 @@ Status Process::HaltPrivate() {
return error;
}
-thread_result_t Process::PrivateStateThread(void *arg) {
- std::unique_ptr<PrivateStateThreadArgs> args_up(
- static_cast<PrivateStateThreadArgs *>(arg));
- thread_result_t result =
- args_up->process->RunPrivateStateThread(args_up->is_secondary_thread);
- return result;
-}
-
thread_result_t Process::RunPrivateStateThread(bool is_secondary_thread) {
bool control_only = true;
diff --git a/lldb/unittests/Host/CMakeLists.txt b/lldb/unittests/Host/CMakeLists.txt
index ae6afd592e547..bf14bf16e4e36 100644
--- a/lldb/unittests/Host/CMakeLists.txt
+++ b/lldb/unittests/Host/CMakeLists.txt
@@ -12,6 +12,7 @@ set (FILES
SocketAddressTest.cpp
SocketTest.cpp
SocketTestUtilities.cpp
+ ThreadLauncherTest.cpp
XMLTest.cpp
)
diff --git a/lldb/unittests/Host/ThreadLauncherTest.cpp b/lldb/unittests/Host/ThreadLauncherTest.cpp
new file mode 100644
index 0000000000000..a19351a59b8dd
--- /dev/null
+++ b/lldb/unittests/Host/ThreadLauncherTest.cpp
@@ -0,0 +1,29 @@
+//===-- ThreadLauncherTest.cpp --------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Host/ThreadLauncher.h"
+#include "llvm/Testing/Support/Error.h"
+#include "gtest/gtest.h"
+#include <future>
+
+using namespace lldb_private;
+
+TEST(ThreadLauncherTest, LaunchThread) {
+ std::promise<int> promise;
+ std::future<int> future = promise.get_future();
+ llvm::Expected<HostThread> thread =
+ ThreadLauncher::LaunchThread("test", [&promise] {
+ promise.set_value(47);
+ return (lldb::thread_result_t)47;
+ });
+ ASSERT_THAT_EXPECTED(thread, llvm::Succeeded());
+ EXPECT_EQ(future.get(), 47);
+ lldb::thread_result_t result;
+ thread->Join(&result);
+ EXPECT_EQ(result, (lldb::thread_result_t)47);
+}
More information about the lldb-commits
mailing list