Go to the documentation of this file.
21 #include "llvm/ADT/None.h"
22 #include "llvm/ADT/Optional.h"
23 #include "llvm/Support/Compiler.h"
38 static ConstString class_name(
"lldb.communication");
42 Communication::Communication(
const char *name)
44 m_read_thread_enabled(false), m_read_thread_did_exit(false), m_bytes(),
45 m_bytes_mutex(), m_write_mutex(), m_synchronize_mutex(),
46 m_callback(nullptr), m_callback_baton(nullptr), m_close_on_eof(true)
51 "{0} Communication::Communication (name = {1})",
this, name);
54 SetEventName(eBroadcastBitReadThreadGotBytes,
"got bytes");
55 SetEventName(eBroadcastBitReadThreadDidExit,
"read thread did exit");
56 SetEventName(eBroadcastBitReadThreadShouldExit,
"read thread should exit");
57 SetEventName(eBroadcastBitPacketAvailable,
"packet available");
58 SetEventName(eBroadcastBitNoMorePendingInput,
"no more pending input");
65 "{0} Communication::~Communication (name = {1})",
this,
80 "{0} Communication::Connect (url = {1})",
this, url);
84 return connection_sp->Connect(url, error_ptr);
95 "Disconnecting while the read thread is running is racy!");
116 return (connection_sp ? connection_sp->IsConnected() :
false);
129 "this = {0}, dst = {1}, dst_len = {2}, timeout = {3}, connection = {4}",
135 if (cached_bytes > 0 || (timeout && timeout->count() == 0)) {
148 listener_sp->StartListeningForEvents(
149 this, eBroadcastBitReadThreadGotBytes | eBroadcastBitReadThreadDidExit);
151 while (listener_sp->GetEvent(event_sp, timeout)) {
152 const uint32_t event_type = event_sp->GetType();
153 if (event_type & eBroadcastBitReadThreadGotBytes) {
157 if (event_type & eBroadcastBitReadThreadDidExit) {
177 "{0} Communication::Write (src = {1}, src_len = {2}"
178 ") connection = {3}",
179 this, src, (uint64_t)src_len, connection_sp.get());
182 return connection_sp->Write(src, src_len, status, error_ptr);
192 size_t total_written = 0;
194 total_written +=
Write(
static_cast<const char *
>(src) + total_written,
195 src_len - total_written, status, error_ptr);
197 return total_written;
208 "{0} Communication::StartReadThread ()",
this);
216 thread_name, [
this] {
return ReadThread(); });
221 *error_ptr =
Status(maybe_thread.takeError());
239 "{0} Communication::StopReadThread ()",
this);
248 return error.Success();
256 return error.Success();
267 const size_t len = std::min<size_t>(dst_len,
m_bytes.size());
269 ::memcpy(dst,
m_bytes.c_str(), len);
281 "{0} Communication::AppendBytesToCache (src = {1}, src_len = {2}, "
283 this, bytes, (uint64_t)len, broadcast);
284 if ((bytes ==
nullptr || len == 0) &&
290 }
else if (bytes !=
nullptr && len > 0) {
292 m_bytes.append((
const char *)bytes, len);
304 return connection_sp->Read(dst, dst_len, timeout, status, error_ptr);
317 LLDB_LOG(log,
"Communication({0}) thread starting...",
this);
324 bool disconnect =
false;
327 buf,
sizeof(buf), std::chrono::seconds(5), status, &
error);
368 LLDB_LOG(log,
"Communication({0}) thread exiting...",
this);
401 ListenerSP listener_sp(
403 listener_sp->StartListeningForEvents(
this, eBroadcastBitNoMorePendingInput);
414 listener_sp->GetEvent(event_sp, llvm::None);
433 return "no connection";
435 return "lost connection";
437 return "end of file";
439 return "interrupted";
442 return "@" + std::to_string(status);
const char * toString(AppleArm64ExceptionClass EC)
void CheckInWithManager()
void SynchronizeWithReadThread()
Wait for the read thread to process all outstanding data.
bool ReadThreadIsRunning()
Checks if there is a currently running read thread.
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.
ReadThreadBytesReceived m_callback
static std::string ConnectionStatusAsString(lldb::ConnectionStatus status)
size_t GetCachedBytes(void *dst, size_t dst_len)
Get any available bytes from our data cache.
std::mutex m_write_mutex
Don't let multiple threads write at the same time...
void SetEventName(uint32_t event_mask, const char *name)
Set the name for an event bit.
static void ReadThreadBytesReceived(void *baton, const void *src, size_t src_len)
lldb::ConnectionSP m_connection_sp
The connection that is current in use by this communications class.
@ eConnectionStatusNoConnection
No connection.
@ eConnectionStatusEndOfFile
End-of-file encountered.
@ eErrorTypePOSIX
POSIX error codes.
~Communication() override
Destructor.
void SetConnection(std::unique_ptr< Connection > connection)
Sets the connection that it to be used by this class.
size_t WriteAll(const void *src, size_t src_len, lldb::ConnectionStatus &status, Status *error_ptr)
Repeatedly attempt writing until either src_len bytes are written or a permanent failure occurs.
HostThread m_read_thread
The read thread handle in case we need to cancel the thread.
static llvm::raw_ostream & error(Stream &strm)
size_t ReadFromConnection(void *dst, size_t dst_len, const Timeout< std::micro > &timeout, lldb::ConnectionStatus &status, Status *error_ptr)
std::atomic< bool > m_read_thread_did_exit
lldb::thread_result_t ReadThread()
The read thread function.
void BroadcastEventIfUnique(lldb::EventSP &event_sp)
virtual bool StartReadThread(Status *error_ptr=nullptr)
Starts a read thread whose sole purpose it to read bytes from the current connection.
@ eConnectionStatusTimedOut
Request timed out.
ConnectionStatus
Connection Status Types.
void SetReadThreadBytesReceivedCallback(ReadThreadBytesReceived callback, void *callback_baton)
@ eConnectionStatusInterrupted
Interrupted read.
virtual bool StopReadThread(Status *error_ptr=nullptr)
Stops the read thread by cancelling it.
string(SUBSTRING ${p} 10 -1 pStripped) if($
size_t Write(const void *src, size_t src_len, lldb::ConnectionStatus &status, Status *error_ptr)
The actual write function that attempts to write to the communications protocol.
std::mutex m_synchronize_mutex
void BroadcastEvent(lldb::EventSP &event_sp)
Broadcast an event which has no associated data.
lldb::ConnectionStatus Disconnect(Status *error_ptr=nullptr)
Disconnect the communications connection if one is currently connected.
Status Join(lldb::thread_result_t *result)
bool HasConnection() const
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.
@ eConnectionStatusError
Check GetError() for details.
void SetErrorString(llvm::StringRef err_str)
Set the current error string to err_str.
bool IsConnected() const
Check if the connection is valid.
bool GetCloseOnEOF() const
#define LLDB_LOG(log,...)
The LLDB_LOG* macros defined below are the way to emit log messages.
@ eConnectionStatusSuccess
Success.
ConstString GetBroadcasterName()
Get the NULL terminated C string name of this Broadcaster object.
A class that represents a running process on the host machine.
void Clear()
Clear the object state.
@ eConnectionStatusLostConnection
Lost connection while connected to a valid connection.
static lldb::ListenerSP MakeListener(const char *name)
std::atomic< bool > m_read_thread_enabled
Log * GetLog(Cat mask)
Retrieve the Log object for the channel associated with the given log enum.
virtual bool JoinReadThread(Status *error_ptr=nullptr)
std::string m_bytes
A buffer to cache bytes read in the ReadThread function.
std::recursive_mutex m_bytes_mutex
A mutex to protect multi-threaded access to the cached bytes.
lldb::ConnectionStatus Connect(const char *url, Status *error_ptr)
Connect using the current connection by passing url to its connect function.