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 16 using namespace lldb; 17 using namespace lldb_private; 18 19 SBCommunication::SBCommunication() : m_opaque(nullptr), m_opaque_owned(false) { 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).release()); 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(new ConnectionFileDescriptor(fd, owns_fd)); 83 if (m_opaque->IsConnected()) 84 status = eConnectionStatusSuccess; 85 else 86 status = eConnectionStatusLostConnection; 87 } 88 return status; 89 } 90 91 ConnectionStatus SBCommunication::Disconnect() { 92 LLDB_RECORD_METHOD_NO_ARGS(lldb::ConnectionStatus, SBCommunication, 93 Disconnect); 94 95 ConnectionStatus status = eConnectionStatusNoConnection; 96 if (m_opaque) 97 status = m_opaque->Disconnect(); 98 return status; 99 } 100 101 bool SBCommunication::IsConnected() const { 102 LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBCommunication, IsConnected); 103 104 return m_opaque ? m_opaque->IsConnected() : false; 105 } 106 107 size_t SBCommunication::Read(void *dst, size_t dst_len, uint32_t timeout_usec, 108 ConnectionStatus &status) { 109 LLDB_RECORD_DUMMY(size_t, SBCommunication, Read, 110 (void *, size_t, uint32_t, lldb::ConnectionStatus &), dst, 111 dst_len, timeout_usec, status); 112 113 size_t bytes_read = 0; 114 Timeout<std::micro> timeout = timeout_usec == UINT32_MAX 115 ? Timeout<std::micro>(llvm::None) 116 : std::chrono::microseconds(timeout_usec); 117 if (m_opaque) 118 bytes_read = m_opaque->Read(dst, dst_len, timeout, status, nullptr); 119 else 120 status = eConnectionStatusNoConnection; 121 122 return bytes_read; 123 } 124 125 size_t SBCommunication::Write(const void *src, size_t src_len, 126 ConnectionStatus &status) { 127 LLDB_RECORD_DUMMY(size_t, SBCommunication, Write, 128 (const void *, size_t, lldb::ConnectionStatus &), src, 129 src_len, status); 130 131 size_t bytes_written = 0; 132 if (m_opaque) 133 bytes_written = m_opaque->Write(src, src_len, status, nullptr); 134 else 135 status = eConnectionStatusNoConnection; 136 137 return bytes_written; 138 } 139 140 bool SBCommunication::ReadThreadStart() { 141 LLDB_RECORD_METHOD_NO_ARGS(bool, SBCommunication, ReadThreadStart); 142 143 return m_opaque ? m_opaque->StartReadThread() : false; 144 } 145 146 bool SBCommunication::ReadThreadStop() { 147 LLDB_RECORD_METHOD_NO_ARGS(bool, SBCommunication, ReadThreadStop); 148 149 return m_opaque ? m_opaque->StopReadThread() : false; 150 } 151 152 bool SBCommunication::ReadThreadIsRunning() { 153 LLDB_RECORD_METHOD_NO_ARGS(bool, SBCommunication, ReadThreadIsRunning); 154 155 return m_opaque ? m_opaque->ReadThreadIsRunning() : false; 156 } 157 158 bool SBCommunication::SetReadThreadBytesReceivedCallback( 159 ReadThreadBytesReceived callback, void *callback_baton) { 160 LLDB_RECORD_DUMMY(bool, SBCommunication, SetReadThreadBytesReceivedCallback, 161 (lldb::SBCommunication::ReadThreadBytesReceived, void *), 162 callback, callback_baton); 163 164 bool result = false; 165 if (m_opaque) { 166 m_opaque->SetReadThreadBytesReceivedCallback(callback, callback_baton); 167 result = true; 168 } 169 return result; 170 } 171 172 SBBroadcaster SBCommunication::GetBroadcaster() { 173 LLDB_RECORD_METHOD_NO_ARGS(lldb::SBBroadcaster, SBCommunication, 174 GetBroadcaster); 175 176 SBBroadcaster broadcaster(m_opaque, false); 177 return LLDB_RECORD_RESULT(broadcaster); 178 } 179 180 const char *SBCommunication::GetBroadcasterClass() { 181 LLDB_RECORD_STATIC_METHOD_NO_ARGS(const char *, SBCommunication, 182 GetBroadcasterClass); 183 184 return Communication::GetStaticBroadcasterClass().AsCString(); 185 } 186 187 namespace lldb_private { 188 namespace repro { 189 190 template <> 191 void RegisterMethods<SBCommunication>(Registry &R) { 192 LLDB_REGISTER_CONSTRUCTOR(SBCommunication, ()); 193 LLDB_REGISTER_CONSTRUCTOR(SBCommunication, (const char *)); 194 LLDB_REGISTER_METHOD_CONST(bool, SBCommunication, IsValid, ()); 195 LLDB_REGISTER_METHOD_CONST(bool, SBCommunication, operator bool, ()); 196 LLDB_REGISTER_METHOD(bool, SBCommunication, GetCloseOnEOF, ()); 197 LLDB_REGISTER_METHOD(void, SBCommunication, SetCloseOnEOF, (bool)); 198 LLDB_REGISTER_METHOD(lldb::ConnectionStatus, SBCommunication, Connect, 199 (const char *)); 200 LLDB_REGISTER_METHOD(lldb::ConnectionStatus, SBCommunication, 201 AdoptFileDesriptor, (int, bool)); 202 LLDB_REGISTER_METHOD(lldb::ConnectionStatus, SBCommunication, Disconnect, 203 ()); 204 LLDB_REGISTER_METHOD_CONST(bool, SBCommunication, IsConnected, ()); 205 LLDB_REGISTER_METHOD(bool, SBCommunication, ReadThreadStart, ()); 206 LLDB_REGISTER_METHOD(bool, SBCommunication, ReadThreadStop, ()); 207 LLDB_REGISTER_METHOD(bool, SBCommunication, ReadThreadIsRunning, ()); 208 LLDB_REGISTER_METHOD(lldb::SBBroadcaster, SBCommunication, GetBroadcaster, 209 ()); 210 LLDB_REGISTER_STATIC_METHOD(const char *, SBCommunication, 211 GetBroadcasterClass, ()); 212 } 213 214 } 215 } 216