1 //===-- SBCommunication.cpp -------------------------------------*- C++ -*-===// 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 #include "lldb/Utility/Log.h" 16 17 using namespace lldb; 18 using namespace lldb_private; 19 20 SBCommunication::SBCommunication() : m_opaque(NULL), m_opaque_owned(false) { 21 LLDB_RECORD_CONSTRUCTOR_NO_ARGS(SBCommunication); 22 } 23 24 SBCommunication::SBCommunication(const char *broadcaster_name) 25 : m_opaque(new Communication(broadcaster_name)), m_opaque_owned(true) { 26 LLDB_RECORD_CONSTRUCTOR(SBCommunication, (const char *), broadcaster_name); 27 28 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 29 30 if (log) 31 log->Printf("SBCommunication::SBCommunication (broadcaster_name=\"%s\") => " 32 "SBCommunication(%p)", 33 broadcaster_name, static_cast<void *>(m_opaque)); 34 } 35 36 SBCommunication::~SBCommunication() { 37 if (m_opaque && m_opaque_owned) 38 delete m_opaque; 39 m_opaque = NULL; 40 m_opaque_owned = false; 41 } 42 43 bool SBCommunication::IsValid() const { 44 LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBCommunication, IsValid); 45 46 return m_opaque != NULL; 47 } 48 49 bool SBCommunication::GetCloseOnEOF() { 50 LLDB_RECORD_METHOD_NO_ARGS(bool, SBCommunication, GetCloseOnEOF); 51 52 if (m_opaque) 53 return m_opaque->GetCloseOnEOF(); 54 return false; 55 } 56 57 void SBCommunication::SetCloseOnEOF(bool b) { 58 LLDB_RECORD_METHOD(void, SBCommunication, SetCloseOnEOF, (bool), b); 59 60 if (m_opaque) 61 m_opaque->SetCloseOnEOF(b); 62 } 63 64 ConnectionStatus SBCommunication::Connect(const char *url) { 65 LLDB_RECORD_METHOD(lldb::ConnectionStatus, SBCommunication, Connect, 66 (const char *), url); 67 68 if (m_opaque) { 69 if (!m_opaque->HasConnection()) 70 m_opaque->SetConnection(Host::CreateDefaultConnection(url).release()); 71 return m_opaque->Connect(url, NULL); 72 } 73 return eConnectionStatusNoConnection; 74 } 75 76 ConnectionStatus SBCommunication::AdoptFileDesriptor(int fd, bool owns_fd) { 77 LLDB_RECORD_METHOD(lldb::ConnectionStatus, SBCommunication, 78 AdoptFileDesriptor, (int, bool), fd, owns_fd); 79 80 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 81 82 ConnectionStatus status = eConnectionStatusNoConnection; 83 if (m_opaque) { 84 if (m_opaque->HasConnection()) { 85 if (m_opaque->IsConnected()) 86 m_opaque->Disconnect(); 87 } 88 m_opaque->SetConnection(new ConnectionFileDescriptor(fd, owns_fd)); 89 if (m_opaque->IsConnected()) 90 status = eConnectionStatusSuccess; 91 else 92 status = eConnectionStatusLostConnection; 93 } 94 95 if (log) 96 log->Printf( 97 "SBCommunication(%p)::AdoptFileDescriptor (fd=%d, ownd_fd=%i) => %s", 98 static_cast<void *>(m_opaque), fd, owns_fd, 99 Communication::ConnectionStatusAsCString(status)); 100 101 return status; 102 } 103 104 ConnectionStatus SBCommunication::Disconnect() { 105 LLDB_RECORD_METHOD_NO_ARGS(lldb::ConnectionStatus, SBCommunication, 106 Disconnect); 107 108 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 109 110 ConnectionStatus status = eConnectionStatusNoConnection; 111 if (m_opaque) 112 status = m_opaque->Disconnect(); 113 114 if (log) 115 log->Printf("SBCommunication(%p)::Disconnect () => %s", 116 static_cast<void *>(m_opaque), 117 Communication::ConnectionStatusAsCString(status)); 118 119 return status; 120 } 121 122 bool SBCommunication::IsConnected() const { 123 LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBCommunication, IsConnected); 124 125 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 126 bool result = false; 127 if (m_opaque) 128 result = m_opaque->IsConnected(); 129 130 if (log) 131 log->Printf("SBCommunication(%p)::IsConnected () => %i", 132 static_cast<void *>(m_opaque), result); 133 134 return false; 135 } 136 137 size_t SBCommunication::Read(void *dst, size_t dst_len, uint32_t timeout_usec, 138 ConnectionStatus &status) { 139 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 140 if (log) 141 log->Printf("SBCommunication(%p)::Read (dst=%p, dst_len=%" PRIu64 142 ", timeout_usec=%u, &status)...", 143 static_cast<void *>(m_opaque), static_cast<void *>(dst), 144 static_cast<uint64_t>(dst_len), timeout_usec); 145 size_t bytes_read = 0; 146 Timeout<std::micro> timeout = timeout_usec == UINT32_MAX 147 ? Timeout<std::micro>(llvm::None) 148 : std::chrono::microseconds(timeout_usec); 149 if (m_opaque) 150 bytes_read = m_opaque->Read(dst, dst_len, timeout, status, NULL); 151 else 152 status = eConnectionStatusNoConnection; 153 154 if (log) 155 log->Printf("SBCommunication(%p)::Read (dst=%p, dst_len=%" PRIu64 156 ", timeout_usec=%u, &status=%s) => %" PRIu64, 157 static_cast<void *>(m_opaque), static_cast<void *>(dst), 158 static_cast<uint64_t>(dst_len), timeout_usec, 159 Communication::ConnectionStatusAsCString(status), 160 static_cast<uint64_t>(bytes_read)); 161 return bytes_read; 162 } 163 164 size_t SBCommunication::Write(const void *src, size_t src_len, 165 ConnectionStatus &status) { 166 size_t bytes_written = 0; 167 if (m_opaque) 168 bytes_written = m_opaque->Write(src, src_len, status, NULL); 169 else 170 status = eConnectionStatusNoConnection; 171 172 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 173 if (log) 174 log->Printf("SBCommunication(%p)::Write (src=%p, src_len=%" PRIu64 175 ", &status=%s) => %" PRIu64, 176 static_cast<void *>(m_opaque), static_cast<const void *>(src), 177 static_cast<uint64_t>(src_len), 178 Communication::ConnectionStatusAsCString(status), 179 static_cast<uint64_t>(bytes_written)); 180 181 return 0; 182 } 183 184 bool SBCommunication::ReadThreadStart() { 185 LLDB_RECORD_METHOD_NO_ARGS(bool, SBCommunication, ReadThreadStart); 186 187 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 188 189 bool success = false; 190 if (m_opaque) 191 success = m_opaque->StartReadThread(); 192 193 if (log) 194 log->Printf("SBCommunication(%p)::ReadThreadStart () => %i", 195 static_cast<void *>(m_opaque), success); 196 197 return success; 198 } 199 200 bool SBCommunication::ReadThreadStop() { 201 LLDB_RECORD_METHOD_NO_ARGS(bool, SBCommunication, ReadThreadStop); 202 203 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 204 if (log) 205 log->Printf("SBCommunication(%p)::ReadThreadStop ()...", 206 static_cast<void *>(m_opaque)); 207 208 bool success = false; 209 if (m_opaque) 210 success = m_opaque->StopReadThread(); 211 212 if (log) 213 log->Printf("SBCommunication(%p)::ReadThreadStop () => %i", 214 static_cast<void *>(m_opaque), success); 215 216 return success; 217 } 218 219 bool SBCommunication::ReadThreadIsRunning() { 220 LLDB_RECORD_METHOD_NO_ARGS(bool, SBCommunication, ReadThreadIsRunning); 221 222 bool result = false; 223 if (m_opaque) 224 result = m_opaque->ReadThreadIsRunning(); 225 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 226 if (log) 227 log->Printf("SBCommunication(%p)::ReadThreadIsRunning () => %i", 228 static_cast<void *>(m_opaque), result); 229 return result; 230 } 231 232 bool SBCommunication::SetReadThreadBytesReceivedCallback( 233 ReadThreadBytesReceived callback, void *callback_baton) { 234 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 235 236 bool result = false; 237 if (m_opaque) { 238 m_opaque->SetReadThreadBytesReceivedCallback(callback, callback_baton); 239 result = true; 240 } 241 242 if (log) 243 log->Printf("SBCommunication(%p)::SetReadThreadBytesReceivedCallback " 244 "(callback=%p, baton=%p) => %i", 245 static_cast<void *>(m_opaque), 246 reinterpret_cast<void *>(reinterpret_cast<intptr_t>(callback)), 247 static_cast<void *>(callback_baton), result); 248 249 return result; 250 } 251 252 SBBroadcaster SBCommunication::GetBroadcaster() { 253 LLDB_RECORD_METHOD_NO_ARGS(lldb::SBBroadcaster, SBCommunication, 254 GetBroadcaster); 255 256 SBBroadcaster broadcaster(m_opaque, false); 257 258 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 259 260 if (log) 261 log->Printf("SBCommunication(%p)::GetBroadcaster () => SBBroadcaster (%p)", 262 static_cast<void *>(m_opaque), 263 static_cast<void *>(broadcaster.get())); 264 265 return LLDB_RECORD_RESULT(broadcaster); 266 } 267 268 const char *SBCommunication::GetBroadcasterClass() { 269 LLDB_RECORD_STATIC_METHOD_NO_ARGS(const char *, SBCommunication, 270 GetBroadcasterClass); 271 272 return Communication::GetStaticBroadcasterClass().AsCString(); 273 } 274 275 // 276 // void 277 // SBCommunication::CreateIfNeeded () 278 //{ 279 // if (m_opaque == NULL) 280 // { 281 // static uint32_t g_broadcaster_num; 282 // char broadcaster_name[256]; 283 // ::snprintf (name, broadcaster_name, "%p SBCommunication", this); 284 // m_opaque = new Communication (broadcaster_name); 285 // m_opaque_owned = true; 286 // } 287 // assert (m_opaque); 288 //} 289 // 290 // 291