mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-01-05 07:32:36 +00:00
Change LaunchThread interface to return an expected.
Change the interface to return an expected, instead of taking a Status pointer. Differential revision: https://reviews.llvm.org/D64163 llvm-svn: 365226
This commit is contained in:
parent
6e6d229e5e
commit
f39c2e188d
@ -1,5 +1,4 @@
|
||||
//===-- ThreadLauncher.h -----------------------------------------*- C++
|
||||
//-*-===//
|
||||
//===-- ThreadLauncher.h ----------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
@ -11,18 +10,18 @@
|
||||
#define lldb_Host_ThreadLauncher_h_
|
||||
|
||||
#include "lldb/Host/HostThread.h"
|
||||
#include "lldb/Utility/Status.h"
|
||||
#include "lldb/lldb-types.h"
|
||||
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/Support/Error.h"
|
||||
|
||||
namespace lldb_private {
|
||||
|
||||
class ThreadLauncher {
|
||||
public:
|
||||
static HostThread
|
||||
static llvm::Expected<HostThread>
|
||||
LaunchThread(llvm::StringRef name, lldb::thread_func_t thread_function,
|
||||
lldb::thread_arg_t thread_arg, Status *error_ptr,
|
||||
lldb::thread_arg_t thread_arg,
|
||||
size_t min_stack_byte_size = 0); // Minimum stack size in bytes,
|
||||
// set stack size to zero for
|
||||
// default platform thread stack
|
||||
|
@ -107,10 +107,17 @@ lldb::thread_t SBHostOS::ThreadCreate(const char *name,
|
||||
LLDB_RECORD_DUMMY(lldb::thread_t, SBHostOS, ThreadCreate,
|
||||
(lldb::thread_func_t, void *, SBError *), name,
|
||||
thread_function, thread_arg, error_ptr);
|
||||
HostThread thread(
|
||||
ThreadLauncher::LaunchThread(name, thread_function, thread_arg,
|
||||
error_ptr ? error_ptr->get() : nullptr));
|
||||
return thread.Release();
|
||||
llvm::Expected<HostThread> thread =
|
||||
ThreadLauncher::LaunchThread(name, thread_function, thread_arg);
|
||||
if (!thread) {
|
||||
if (error_ptr)
|
||||
error_ptr->SetError(Status(thread.takeError()));
|
||||
else
|
||||
llvm::consumeError(thread.takeError());
|
||||
return LLDB_INVALID_HOST_THREAD;
|
||||
}
|
||||
|
||||
return thread->Release();
|
||||
}
|
||||
|
||||
void SBHostOS::ThreadCreated(const char *name) {
|
||||
|
@ -204,10 +204,23 @@ bool Communication::StartReadThread(Status *error_ptr) {
|
||||
|
||||
m_read_thread_enabled = true;
|
||||
m_read_thread_did_exit = false;
|
||||
m_read_thread = ThreadLauncher::LaunchThread(
|
||||
thread_name, Communication::ReadThread, this, error_ptr);
|
||||
auto maybe_thread = ThreadLauncher::LaunchThread(
|
||||
thread_name, Communication::ReadThread, this);
|
||||
if (maybe_thread) {
|
||||
m_read_thread = *maybe_thread;
|
||||
} else {
|
||||
if (error_ptr)
|
||||
*error_ptr = Status(maybe_thread.takeError());
|
||||
else {
|
||||
LLDB_LOG(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST),
|
||||
"failed to launch host thread: {}",
|
||||
llvm::toString(maybe_thread.takeError()));
|
||||
}
|
||||
}
|
||||
|
||||
if (!m_read_thread.IsJoinable())
|
||||
m_read_thread_enabled = false;
|
||||
|
||||
return m_read_thread_enabled;
|
||||
}
|
||||
|
||||
|
@ -1642,8 +1642,17 @@ bool Debugger::StartEventHandlerThread() {
|
||||
full_name.AsCString() : "dbg.evt-handler";
|
||||
|
||||
// Use larger 8MB stack for this thread
|
||||
m_event_handler_thread = ThreadLauncher::LaunchThread(thread_name,
|
||||
EventHandlerThread, this, nullptr, g_debugger_event_thread_stack_bytes);
|
||||
llvm::Expected<HostThread> event_handler_thread =
|
||||
ThreadLauncher::LaunchThread(thread_name, EventHandlerThread, this,
|
||||
g_debugger_event_thread_stack_bytes);
|
||||
|
||||
if (event_handler_thread) {
|
||||
m_event_handler_thread = *event_handler_thread;
|
||||
} else {
|
||||
LLDB_LOG(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST),
|
||||
"failed to launch host thread: {}",
|
||||
llvm::toString(event_handler_thread.takeError()));
|
||||
}
|
||||
|
||||
// Make sure DefaultEventHandler() is running and listening to events
|
||||
// before we return from this function. We are only listening for events of
|
||||
@ -1674,10 +1683,18 @@ lldb::thread_result_t Debugger::IOHandlerThread(lldb::thread_arg_t arg) {
|
||||
bool Debugger::HasIOHandlerThread() { return m_io_handler_thread.IsJoinable(); }
|
||||
|
||||
bool Debugger::StartIOHandlerThread() {
|
||||
if (!m_io_handler_thread.IsJoinable())
|
||||
m_io_handler_thread = ThreadLauncher::LaunchThread(
|
||||
"lldb.debugger.io-handler", IOHandlerThread, this, nullptr,
|
||||
if (!m_io_handler_thread.IsJoinable()) {
|
||||
llvm::Expected<HostThread> io_handler_thread = ThreadLauncher::LaunchThread(
|
||||
"lldb.debugger.io-handler", IOHandlerThread, this,
|
||||
8 * 1024 * 1024); // Use larger 8MB stack for this thread
|
||||
if (io_handler_thread) {
|
||||
m_io_handler_thread = *io_handler_thread;
|
||||
} else {
|
||||
LLDB_LOG(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST),
|
||||
"failed to launch host thread: {}",
|
||||
llvm::toString(io_handler_thread.takeError()));
|
||||
}
|
||||
}
|
||||
return m_io_handler_thread.IsJoinable();
|
||||
}
|
||||
|
||||
|
@ -8,6 +8,7 @@
|
||||
|
||||
#include "lldb/Host/TaskPool.h"
|
||||
#include "lldb/Host/ThreadLauncher.h"
|
||||
#include "lldb/Utility/Log.h"
|
||||
|
||||
#include <cstdint>
|
||||
#include <queue>
|
||||
@ -65,9 +66,16 @@ void TaskPoolImpl::AddTask(std::function<void()> &&task_fn) {
|
||||
// Note that this detach call needs to happen with the m_tasks_mutex held.
|
||||
// This prevents the thread from exiting prematurely and triggering a linux
|
||||
// libc bug (https://sourceware.org/bugzilla/show_bug.cgi?id=19951).
|
||||
lldb_private::ThreadLauncher::LaunchThread("task-pool.worker", WorkerPtr,
|
||||
this, nullptr, min_stack_size)
|
||||
.Release();
|
||||
llvm::Expected<HostThread> host_thread =
|
||||
lldb_private::ThreadLauncher::LaunchThread(
|
||||
"task-pool.worker", WorkerPtr, this, min_stack_size);
|
||||
if (host_thread) {
|
||||
host_thread->Release();
|
||||
} else {
|
||||
LLDB_LOG(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST),
|
||||
"failed to launch host thread: {}",
|
||||
llvm::toString(host_thread.takeError()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -20,15 +20,9 @@
|
||||
using namespace lldb;
|
||||
using namespace lldb_private;
|
||||
|
||||
HostThread ThreadLauncher::LaunchThread(llvm::StringRef name,
|
||||
lldb::thread_func_t thread_function,
|
||||
lldb::thread_arg_t thread_arg,
|
||||
Status *error_ptr,
|
||||
size_t min_stack_byte_size) {
|
||||
Status error;
|
||||
if (error_ptr)
|
||||
error_ptr->Clear();
|
||||
|
||||
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);
|
||||
@ -38,7 +32,7 @@ HostThread ThreadLauncher::LaunchThread(llvm::StringRef name,
|
||||
0, (unsigned)min_stack_byte_size,
|
||||
HostNativeThread::ThreadCreateTrampoline, info_ptr, 0, NULL);
|
||||
if (thread == (lldb::thread_t)(-1L))
|
||||
error.SetError(::GetLastError(), eErrorTypeWin32);
|
||||
return llvm::errorCodeToError(::GetLastError());
|
||||
#else
|
||||
|
||||
// ASAN instrumentation adds a lot of bookkeeping overhead on stack frames.
|
||||
@ -73,12 +67,10 @@ HostThread ThreadLauncher::LaunchThread(llvm::StringRef name,
|
||||
if (destroy_attr)
|
||||
::pthread_attr_destroy(&thread_attr);
|
||||
|
||||
error.SetError(err, eErrorTypePOSIX);
|
||||
if (err)
|
||||
return llvm::errorCodeToError(
|
||||
std::error_code(err, std::generic_category()));
|
||||
#endif
|
||||
if (error_ptr)
|
||||
*error_ptr = error;
|
||||
if (!error.Success())
|
||||
thread = LLDB_INVALID_HOST_THREAD;
|
||||
|
||||
return HostThread(thread);
|
||||
}
|
||||
|
@ -313,13 +313,16 @@ LaunchInNewTerminalWithAppleScript(const char *exe_path,
|
||||
// in a shell and the shell will fork/exec a couple of times before we get
|
||||
// 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.
|
||||
HostThread accept_thread = ThreadLauncher::LaunchThread(
|
||||
unix_socket_name, AcceptPIDFromInferior, connect_url, &lldb_error);
|
||||
llvm::Expected<HostThread> accept_thread = ThreadLauncher::LaunchThread(
|
||||
unix_socket_name, AcceptPIDFromInferior, connect_url);
|
||||
|
||||
if (!accept_thread)
|
||||
return Status(accept_thread.takeError());
|
||||
|
||||
[applescript executeAndReturnError:nil];
|
||||
|
||||
thread_result_t accept_thread_result = NULL;
|
||||
lldb_error = accept_thread.Join(&accept_thread_result);
|
||||
lldb_error = accept_thread->Join(&accept_thread_result);
|
||||
if (lldb_error.Success() && accept_thread_result) {
|
||||
pid = (intptr_t)accept_thread_result;
|
||||
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include "lldb/Target/RegisterContext.h"
|
||||
#include "lldb/Target/Target.h"
|
||||
#include "lldb/Target/Thread.h"
|
||||
#include "lldb/Utility/Log.h"
|
||||
#include "lldb/Utility/State.h"
|
||||
#include "lldb/Utility/StringExtractor.h"
|
||||
#include "lldb/Utility/UUID.h"
|
||||
@ -739,8 +740,15 @@ bool ProcessKDP::StartAsyncThread() {
|
||||
if (m_async_thread.IsJoinable())
|
||||
return true;
|
||||
|
||||
m_async_thread = ThreadLauncher::LaunchThread(
|
||||
"<lldb.process.kdp-remote.async>", ProcessKDP::AsyncThread, this, NULL);
|
||||
llvm::Expected<HostThread> async_thread = ThreadLauncher::LaunchThread(
|
||||
"<lldb.process.kdp-remote.async>", ProcessKDP::AsyncThread, this);
|
||||
if (!async_thread) {
|
||||
LLDB_LOG(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST),
|
||||
"failed to launch host thread: {}",
|
||||
llvm::toString(async_thread.takeError()));
|
||||
return false;
|
||||
}
|
||||
m_async_thread = *async_thread;
|
||||
return m_async_thread.IsJoinable();
|
||||
}
|
||||
|
||||
|
@ -888,22 +888,23 @@ GDBRemoteCommunication::CheckForPacket(const uint8_t *src, size_t src_len,
|
||||
|
||||
Status GDBRemoteCommunication::StartListenThread(const char *hostname,
|
||||
uint16_t port) {
|
||||
Status error;
|
||||
if (m_listen_thread.IsJoinable()) {
|
||||
error.SetErrorString("listen thread already running");
|
||||
} else {
|
||||
char listen_url[512];
|
||||
if (hostname && hostname[0])
|
||||
snprintf(listen_url, sizeof(listen_url), "listen://%s:%i", hostname,
|
||||
port);
|
||||
else
|
||||
snprintf(listen_url, sizeof(listen_url), "listen://%i", port);
|
||||
m_listen_url = listen_url;
|
||||
SetConnection(new ConnectionFileDescriptor());
|
||||
m_listen_thread = ThreadLauncher::LaunchThread(
|
||||
listen_url, GDBRemoteCommunication::ListenThread, this, &error);
|
||||
}
|
||||
return error;
|
||||
if (m_listen_thread.IsJoinable())
|
||||
return Status("listen thread already running");
|
||||
|
||||
char listen_url[512];
|
||||
if (hostname && hostname[0])
|
||||
snprintf(listen_url, sizeof(listen_url), "listen://%s:%i", hostname, port);
|
||||
else
|
||||
snprintf(listen_url, sizeof(listen_url), "listen://%i", port);
|
||||
m_listen_url = listen_url;
|
||||
SetConnection(new ConnectionFileDescriptor());
|
||||
llvm::Expected<HostThread> listen_thread = ThreadLauncher::LaunchThread(
|
||||
listen_url, GDBRemoteCommunication::ListenThread, this);
|
||||
if (!listen_thread)
|
||||
return Status(listen_thread.takeError());
|
||||
m_listen_thread = *listen_thread;
|
||||
|
||||
return Status();
|
||||
}
|
||||
|
||||
bool GDBRemoteCommunication::JoinListenThread() {
|
||||
|
@ -203,9 +203,16 @@ bool GDBRemoteCommunicationReplayServer::StartAsyncThread() {
|
||||
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(
|
||||
llvm::Expected<HostThread> async_thread = ThreadLauncher::LaunchThread(
|
||||
"<lldb.gdb-replay.async>",
|
||||
GDBRemoteCommunicationReplayServer::AsyncThread, this, nullptr);
|
||||
GDBRemoteCommunicationReplayServer::AsyncThread, this);
|
||||
if (!async_thread) {
|
||||
LLDB_LOG(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST),
|
||||
"failed to launch host thread: {}",
|
||||
llvm::toString(async_thread.takeError()));
|
||||
return false;
|
||||
}
|
||||
m_async_thread = *async_thread;
|
||||
}
|
||||
|
||||
// Wait for handshake.
|
||||
|
@ -3700,9 +3700,15 @@ bool ProcessGDBRemote::StartAsyncThread() {
|
||||
// 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,
|
||||
nullptr);
|
||||
llvm::Expected<HostThread> async_thread = ThreadLauncher::LaunchThread(
|
||||
"<lldb.process.gdb-remote.async>", ProcessGDBRemote::AsyncThread, this);
|
||||
if (!async_thread) {
|
||||
LLDB_LOG(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST),
|
||||
"failed to launch host thread: {}",
|
||||
llvm::toString(async_thread.takeError()));
|
||||
return false;
|
||||
}
|
||||
m_async_thread = *async_thread;
|
||||
} else if (log)
|
||||
log->Printf("ProcessGDBRemote::%s () - Called when Async thread was "
|
||||
"already running.",
|
||||
|
@ -3588,14 +3588,20 @@ bool Process::StartPrivateStateThread(bool is_secondary_thread) {
|
||||
// Create the private state thread, and start it running.
|
||||
PrivateStateThreadArgs *args_ptr =
|
||||
new PrivateStateThreadArgs(this, is_secondary_thread);
|
||||
m_private_state_thread =
|
||||
llvm::Expected<HostThread> private_state_thread =
|
||||
ThreadLauncher::LaunchThread(thread_name, Process::PrivateStateThread,
|
||||
(void *)args_ptr, nullptr, 8 * 1024 * 1024);
|
||||
if (m_private_state_thread.IsJoinable()) {
|
||||
ResumePrivateStateThread();
|
||||
return true;
|
||||
} else
|
||||
(void *)args_ptr, 8 * 1024 * 1024);
|
||||
if (!private_state_thread) {
|
||||
LLDB_LOG(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST),
|
||||
"failed to launch host thread: {}",
|
||||
llvm::toString(private_state_thread.takeError()));
|
||||
return false;
|
||||
}
|
||||
|
||||
assert(private_state_thread->IsJoinable());
|
||||
m_private_state_thread = *private_state_thread;
|
||||
ResumePrivateStateThread();
|
||||
return true;
|
||||
}
|
||||
|
||||
void Process::PausePrivateStateThread() {
|
||||
|
Loading…
Reference in New Issue
Block a user