1 //===-- SBCommunication.cpp -----------------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "lldb/API/SBCommunication.h" 10 #include "SBReproducerPrivate.h" 11 #include "lldb/API/SBBroadcaster.h" 12 #include "lldb/Core/Communication.h" 13 #include "lldb/Host/ConnectionFileDescriptor.h" 14 #include "lldb/Host/Host.h" 15 16 using namespace lldb; 17 using namespace lldb_private; 18 19 SBCommunication::SBCommunication() { 20 LLDB_RECORD_CONSTRUCTOR_NO_ARGS(SBCommunication); 21 } 22 23 SBCommunication::SBCommunication(const char *broadcaster_name) 24 : m_opaque(new Communication(broadcaster_name)), m_opaque_owned(true) { 25 LLDB_RECORD_CONSTRUCTOR(SBCommunication, (const char *), broadcaster_name); 26 } 27 28 SBCommunication::~SBCommunication() { 29 if (m_opaque && m_opaque_owned) 30 delete m_opaque; 31 m_opaque = nullptr; 32 m_opaque_owned = false; 33 } 34 35 bool SBCommunication::IsValid() const { 36 LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBCommunication, IsValid); 37 return this->operator bool(); 38 } 39 SBCommunication::operator bool() const { 40 LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBCommunication, operator bool); 41 42 return m_opaque != nullptr; 43 } 44 45 bool SBCommunication::GetCloseOnEOF() { 46 LLDB_RECORD_METHOD_NO_ARGS(bool, SBCommunication, GetCloseOnEOF); 47 48 if (m_opaque) 49 return m_opaque->GetCloseOnEOF(); 50 return false; 51 } 52 53 void SBCommunication::SetCloseOnEOF(bool b) { 54 LLDB_RECORD_METHOD(void, SBCommunication, SetCloseOnEOF, (bool), b); 55 56 if (m_opaque) 57 m_opaque->SetCloseOnEOF(b); 58 } 59 60 ConnectionStatus SBCommunication::Connect(const char *url) { 61 LLDB_RECORD_METHOD(lldb::ConnectionStatus, SBCommunication, Connect, 62 (const char *), url); 63 64 if (m_opaque) { 65 if (!m_opaque->HasConnection()) 66 m_opaque->SetConnection(Host::CreateDefaultConnection(url)); 67 return m_opaque->Connect(url, nullptr); 68 } 69 return eConnectionStatusNoConnection; 70 } 71 72 ConnectionStatus SBCommunication::AdoptFileDesriptor(int fd, bool owns_fd) { 73 LLDB_RECORD_METHOD(lldb::ConnectionStatus, SBCommunication, 74 AdoptFileDesriptor, (int, bool), fd, owns_fd); 75 76 ConnectionStatus status = eConnectionStatusNoConnection; 77 if (m_opaque) { 78 if (m_opaque->HasConnection()) { 79 if (m_opaque->IsConnected()) 80 m_opaque->Disconnect(); 81 } 82 m_opaque->SetConnection( 83 std::make_unique<ConnectionFileDescriptor>(fd, owns_fd)); 84 if (m_opaque->IsConnected()) 85 status = eConnectionStatusSuccess; 86 else 87 status = eConnectionStatusLostConnection; 88 } 89 return status; 90 } 91 92 ConnectionStatus SBCommunication::Disconnect() { 93 LLDB_RECORD_METHOD_NO_ARGS(lldb::ConnectionStatus, SBCommunication, 94 Disconnect); 95 96 ConnectionStatus status = eConnectionStatusNoConnection; 97 if (m_opaque) 98 status = m_opaque->Disconnect(); 99 return status; 100 } 101 102 bool SBCommunication::IsConnected() const { 103 LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBCommunication, IsConnected); 104 105 return m_opaque ? m_opaque->IsConnected() : false; 106 } 107 108 size_t SBCommunication::Read(void *dst, size_t dst_len, uint32_t timeout_usec, 109 ConnectionStatus &status) { 110 LLDB_RECORD_DUMMY(size_t, SBCommunication, Read, 111 (void *, size_t, uint32_t, lldb::ConnectionStatus &), dst, 112 dst_len, timeout_usec, status); 113 114 size_t bytes_read = 0; 115 Timeout<std::micro> timeout = timeout_usec == UINT32_MAX 116 ? Timeout<std::micro>(llvm::None) 117 : std::chrono::microseconds(timeout_usec); 118 if (m_opaque) 119 bytes_read = m_opaque->Read(dst, dst_len, timeout, status, nullptr); 120 else 121 status = eConnectionStatusNoConnection; 122 123 return bytes_read; 124 } 125 126 size_t SBCommunication::Write(const void *src, size_t src_len, 127 ConnectionStatus &status) { 128 LLDB_RECORD_DUMMY(size_t, SBCommunication, Write, 129 (const void *, size_t, lldb::ConnectionStatus &), src, 130 src_len, status); 131 132 size_t bytes_written = 0; 133 if (m_opaque) 134 bytes_written = m_opaque->Write(src, src_len, status, nullptr); 135 else 136 status = eConnectionStatusNoConnection; 137 138 return bytes_written; 139 } 140 141 bool SBCommunication::ReadThreadStart() { 142 LLDB_RECORD_METHOD_NO_ARGS(bool, SBCommunication, ReadThreadStart); 143 144 return m_opaque ? m_opaque->StartReadThread() : false; 145 } 146 147 bool SBCommunication::ReadThreadStop() { 148 LLDB_RECORD_METHOD_NO_ARGS(bool, SBCommunication, ReadThreadStop); 149 150 return m_opaque ? m_opaque->StopReadThread() : false; 151 } 152 153 bool SBCommunication::ReadThreadIsRunning() { 154 LLDB_RECORD_METHOD_NO_ARGS(bool, SBCommunication, ReadThreadIsRunning); 155 156 return m_opaque ? m_opaque->ReadThreadIsRunning() : false; 157 } 158 159 bool SBCommunication::SetReadThreadBytesReceivedCallback( 160 ReadThreadBytesReceived callback, void *callback_baton) { 161 LLDB_RECORD_DUMMY(bool, SBCommunication, SetReadThreadBytesReceivedCallback, 162 (lldb::SBCommunication::ReadThreadBytesReceived, void *), 163 callback, callback_baton); 164 165 bool result = false; 166 if (m_opaque) { 167 m_opaque->SetReadThreadBytesReceivedCallback(callback, callback_baton); 168 result = true; 169 } 170 return result; 171 } 172 173 SBBroadcaster SBCommunication::GetBroadcaster() { 174 LLDB_RECORD_METHOD_NO_ARGS(lldb::SBBroadcaster, SBCommunication, 175 GetBroadcaster); 176 177 SBBroadcaster broadcaster(m_opaque, false); 178 return LLDB_RECORD_RESULT(broadcaster); 179 } 180 181 const char *SBCommunication::GetBroadcasterClass() { 182 LLDB_RECORD_STATIC_METHOD_NO_ARGS(const char *, SBCommunication, 183 GetBroadcasterClass); 184 185 return Communication::GetStaticBroadcasterClass().AsCString(); 186 } 187 188 namespace lldb_private { 189 namespace repro { 190 191 template <> 192 void RegisterMethods<SBCommunication>(Registry &R) { 193 LLDB_REGISTER_CONSTRUCTOR(SBCommunication, ()); 194 LLDB_REGISTER_CONSTRUCTOR(SBCommunication, (const char *)); 195 LLDB_REGISTER_METHOD_CONST(bool, SBCommunication, IsValid, ()); 196 LLDB_REGISTER_METHOD_CONST(bool, SBCommunication, operator bool, ()); 197 LLDB_REGISTER_METHOD(bool, SBCommunication, GetCloseOnEOF, ()); 198 LLDB_REGISTER_METHOD(void, SBCommunication, SetCloseOnEOF, (bool)); 199 LLDB_REGISTER_METHOD(lldb::ConnectionStatus, SBCommunication, Connect, 200 (const char *)); 201 LLDB_REGISTER_METHOD(lldb::ConnectionStatus, SBCommunication, 202 AdoptFileDesriptor, (int, bool)); 203 LLDB_REGISTER_METHOD(lldb::ConnectionStatus, SBCommunication, Disconnect, 204 ()); 205 LLDB_REGISTER_METHOD_CONST(bool, SBCommunication, IsConnected, ()); 206 LLDB_REGISTER_METHOD(bool, SBCommunication, ReadThreadStart, ()); 207 LLDB_REGISTER_METHOD(bool, SBCommunication, ReadThreadStop, ()); 208 LLDB_REGISTER_METHOD(bool, SBCommunication, ReadThreadIsRunning, ()); 209 LLDB_REGISTER_METHOD(lldb::SBBroadcaster, SBCommunication, GetBroadcaster, 210 ()); 211 LLDB_REGISTER_STATIC_METHOD(const char *, SBCommunication, 212 GetBroadcasterClass, ()); 213 } 214 215 } 216 } 217