20#include "llvm/Support/Compiler.h"
35 static ConstString class_name(
"lldb.communication");
41 m_read_thread_did_exit(false), m_bytes(), m_bytes_mutex(),
42 m_synchronize_mutex(), m_callback(nullptr), m_callback_baton(nullptr) {
44 "{0} ThreadedCommunication::ThreadedCommunication (name = {1})",
48 SetEventName(eBroadcastBitReadThreadGotBytes,
"got bytes");
49 SetEventName(eBroadcastBitReadThreadDidExit,
"read thread did exit");
50 SetEventName(eBroadcastBitReadThreadShouldExit,
"read thread should exit");
51 SetEventName(eBroadcastBitPacketAvailable,
"packet available");
52 SetEventName(eBroadcastBitNoMorePendingInput,
"no more pending input");
59 "{0} ThreadedCommunication::~ThreadedCommunication (name = {1})",
71 "Disconnecting while the read thread is running is racy!");
82 "this = {0}, dst = {1}, dst_len = {2}, timeout = {3}, connection = {4}",
88 if (cached_bytes > 0) {
92 if (timeout && timeout->count() == 0) {
107 ListenerSP listener_sp(
109 listener_sp->StartListeningForEvents(
110 this, eBroadcastBitReadThreadGotBytes | eBroadcastBitReadThreadDidExit);
115 if (cached_bytes > 0) {
124 event_sp = std::make_shared<Event>(eBroadcastBitReadThreadDidExit);
126 if (!listener_sp->GetEvent(event_sp, timeout)) {
133 const uint32_t event_type = event_sp->GetType();
134 if (event_type & eBroadcastBitReadThreadGotBytes) {
138 if (event_type & eBroadcastBitReadThreadDidExit) {
149 llvm_unreachable(
"Got unexpected event type!");
165 "{0} ThreadedCommunication::StartReadThread ()",
this);
167 const std::string thread_name =
173 thread_name, [
this] {
return ReadThread(); });
178 *error_ptr =
Status(maybe_thread.takeError());
181 llvm::toString(maybe_thread.takeError()));
196 "{0} ThreadedCommunication::StopReadThread ()",
this);
205 return error.Success();
213 return error.Success();
224 const size_t len = std::min<size_t>(dst_len,
m_bytes.size());
226 ::memcpy(dst,
m_bytes.c_str(), len);
238 "{0} ThreadedCommunication::AppendBytesToCache (src = {1}, src_len "
241 this, bytes, (uint64_t)len, broadcast);
242 if ((bytes ==
nullptr || len == 0) &&
248 }
else if (bytes !=
nullptr && len > 0) {
250 m_bytes.append((
const char *)bytes, len);
263 LLDB_LOG(log,
"Communication({0}) thread starting...",
this);
270 bool disconnect =
false;
273 buf,
sizeof(buf), std::chrono::seconds(5), status, &
error);
315 LLDB_LOG(log,
"Communication({0}) thread exiting...",
this);
352 "ThreadedCommunication::SyncronizeWithReadThread"));
353 listener_sp->StartListeningForEvents(
this, eBroadcastBitNoMorePendingInput);
364 listener_sp->GetEvent(event_sp, std::nullopt);
368 std::unique_ptr<Connection> connection) {
static llvm::raw_ostream & error(Stream &strm)
#define LLDB_LOG(log,...)
The LLDB_LOG* macros defined below are the way to emit log messages.
static void ReadThreadBytesReceived(void *baton, const void *src, size_t src_len)
An event broadcasting class.
ConstString GetBroadcasterName()
Get the NULL terminated C string name of this Broadcaster object.
void SetEventName(uint32_t event_mask, const char *name)
Set the name for an event bit.
void BroadcastEventIfUnique(lldb::EventSP &event_sp)
void BroadcastEvent(lldb::EventSP &event_sp)
Broadcast an event which has no associated data.
void CheckInWithManager()
An abstract communications class.
size_t ReadFromConnection(void *dst, size_t dst_len, const Timeout< std::micro > &timeout, lldb::ConnectionStatus &status, Status *error_ptr)
bool GetCloseOnEOF() const
virtual size_t Read(void *dst, size_t dst_len, const Timeout< std::micro > &timeout, lldb::ConnectionStatus &status, Status *error_ptr)
Read bytes from the current connection.
lldb::ConnectionSP m_connection_sp
The connection that is current in use by this communications class.
virtual void SetConnection(std::unique_ptr< Connection > connection)
Sets the connection that it to be used by this class.
virtual lldb::ConnectionStatus Disconnect(Status *error_ptr=nullptr)
Disconnect the communications connection if one is currently connected.
static std::string ConnectionStatusAsString(lldb::ConnectionStatus status)
A uniqued constant string class.
Status Join(lldb::thread_result_t *result)
static lldb::ListenerSP MakeListener(const char *name)
void Clear()
Clear the object state.
void SetErrorString(llvm::StringRef err_str)
Set the current error string to err_str.
static llvm::Expected< HostThread > LaunchThread(llvm::StringRef name, std::function< lldb::thread_result_t()> thread_function, size_t min_stack_byte_size=0)
virtual void AppendBytesToCache(const uint8_t *src, size_t src_len, bool broadcast, lldb::ConnectionStatus status)
Append new bytes that get read from the read thread into the internal object byte cache.
size_t Read(void *dst, size_t dst_len, const Timeout< std::micro > &timeout, lldb::ConnectionStatus &status, Status *error_ptr) override
Read bytes from the current connection.
static ConstString & GetStaticBroadcasterClass()
void SetConnection(std::unique_ptr< Connection > connection) override
Sets the connection that it to be used by this class.
ThreadedCommunication(const char *broadcaster_name)
Construct the ThreadedCommunication object with the specified name for the Broadcaster that this obje...
std::recursive_mutex m_bytes_mutex
A mutex to protect multi-threaded access to the cached bytes.
HostThread m_read_thread
The read thread handle in case we need to cancel the thread.
~ThreadedCommunication() override
Destructor.
virtual bool StopReadThread(Status *error_ptr=nullptr)
Stops the read thread by cancelling it.
void SynchronizeWithReadThread()
Wait for the read thread to process all outstanding data.
std::atomic< bool > m_read_thread_did_exit
lldb::ConnectionStatus m_pass_status
Connection status passthrough from read thread.
lldb::ConnectionStatus Disconnect(Status *error_ptr=nullptr) override
Disconnect the communications connection if one is currently connected.
ReadThreadBytesReceived m_callback
Status m_pass_error
Error passthrough from read thread.
virtual bool StartReadThread(Status *error_ptr=nullptr)
Starts a read thread whose sole purpose it to read bytes from the current connection.
std::atomic< bool > m_read_thread_enabled
virtual bool JoinReadThread(Status *error_ptr=nullptr)
std::string m_bytes
A buffer to cache bytes read in the ReadThread function.
size_t GetCachedBytes(void *dst, size_t dst_len)
Get any available bytes from our data cache.
bool ReadThreadIsRunning()
Checks if there is a currently running read thread.
lldb::thread_result_t ReadThread()
The read thread function.
std::mutex m_synchronize_mutex
void SetReadThreadBytesReceivedCallback(ReadThreadBytesReceived callback, void *callback_baton)
A class that represents a running process on the host machine.
Log * GetLog(Cat mask)
Retrieve the Log object for the channel associated with the given log enum.
ConnectionStatus
Connection Status Types.
@ eConnectionStatusError
Check GetError() for details.
@ eConnectionStatusInterrupted
Interrupted read.
@ eConnectionStatusTimedOut
Request timed out.
@ eConnectionStatusEndOfFile
End-of-file encountered.
@ eConnectionStatusSuccess
Success.
@ eConnectionStatusLostConnection
Lost connection while connected to a valid connection.
@ eConnectionStatusNoConnection
No connection.
@ eErrorTypePOSIX
POSIX error codes.