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 "lldb/API/SBBroadcaster.h" 11 #include "lldb/Core/ThreadedCommunication.h" 12 #include "lldb/Host/ConnectionFileDescriptor.h" 13 #include "lldb/Host/Host.h" 14 #include "lldb/Utility/Instrumentation.h" 15 16 using namespace lldb; 17 using namespace lldb_private; 18 19 SBCommunication::SBCommunication() { LLDB_INSTRUMENT_VA(this); } 20 21 SBCommunication::SBCommunication(const char *broadcaster_name) 22 : m_opaque(new ThreadedCommunication(broadcaster_name)), 23 m_opaque_owned(true) { 24 LLDB_INSTRUMENT_VA(this, broadcaster_name); 25 } 26 27 SBCommunication::~SBCommunication() { 28 if (m_opaque && m_opaque_owned) 29 delete m_opaque; 30 m_opaque = nullptr; 31 m_opaque_owned = false; 32 } 33 34 bool SBCommunication::IsValid() const { 35 LLDB_INSTRUMENT_VA(this); 36 return this->operator bool(); 37 } 38 SBCommunication::operator bool() const { 39 LLDB_INSTRUMENT_VA(this); 40 41 return m_opaque != nullptr; 42 } 43 44 bool SBCommunication::GetCloseOnEOF() { 45 LLDB_INSTRUMENT_VA(this); 46 47 if (m_opaque) 48 return m_opaque->GetCloseOnEOF(); 49 return false; 50 } 51 52 void SBCommunication::SetCloseOnEOF(bool b) { 53 LLDB_INSTRUMENT_VA(this, b); 54 55 if (m_opaque) 56 m_opaque->SetCloseOnEOF(b); 57 } 58 59 ConnectionStatus SBCommunication::Connect(const char *url) { 60 LLDB_INSTRUMENT_VA(this, url); 61 62 if (m_opaque) { 63 if (!m_opaque->HasConnection()) 64 m_opaque->SetConnection(Host::CreateDefaultConnection(url)); 65 return m_opaque->Connect(url, nullptr); 66 } 67 return eConnectionStatusNoConnection; 68 } 69 70 ConnectionStatus SBCommunication::AdoptFileDesriptor(int fd, bool owns_fd) { 71 LLDB_INSTRUMENT_VA(this, fd, owns_fd); 72 73 ConnectionStatus status = eConnectionStatusNoConnection; 74 if (m_opaque) { 75 if (m_opaque->HasConnection()) { 76 if (m_opaque->IsConnected()) 77 m_opaque->Disconnect(); 78 } 79 m_opaque->SetConnection( 80 std::make_unique<ConnectionFileDescriptor>(fd, owns_fd)); 81 if (m_opaque->IsConnected()) 82 status = eConnectionStatusSuccess; 83 else 84 status = eConnectionStatusLostConnection; 85 } 86 return status; 87 } 88 89 ConnectionStatus SBCommunication::Disconnect() { 90 LLDB_INSTRUMENT_VA(this); 91 92 ConnectionStatus status = eConnectionStatusNoConnection; 93 if (m_opaque) 94 status = m_opaque->Disconnect(); 95 return status; 96 } 97 98 bool SBCommunication::IsConnected() const { 99 LLDB_INSTRUMENT_VA(this); 100 101 return m_opaque ? m_opaque->IsConnected() : false; 102 } 103 104 size_t SBCommunication::Read(void *dst, size_t dst_len, uint32_t timeout_usec, 105 ConnectionStatus &status) { 106 LLDB_INSTRUMENT_VA(this, dst, dst_len, timeout_usec, status); 107 108 size_t bytes_read = 0; 109 Timeout<std::micro> timeout = timeout_usec == UINT32_MAX 110 ? Timeout<std::micro>(std::nullopt) 111 : std::chrono::microseconds(timeout_usec); 112 if (m_opaque) 113 bytes_read = m_opaque->Read(dst, dst_len, timeout, status, nullptr); 114 else 115 status = eConnectionStatusNoConnection; 116 117 return bytes_read; 118 } 119 120 size_t SBCommunication::Write(const void *src, size_t src_len, 121 ConnectionStatus &status) { 122 LLDB_INSTRUMENT_VA(this, src, src_len, status); 123 124 size_t bytes_written = 0; 125 if (m_opaque) 126 bytes_written = m_opaque->Write(src, src_len, status, nullptr); 127 else 128 status = eConnectionStatusNoConnection; 129 130 return bytes_written; 131 } 132 133 bool SBCommunication::ReadThreadStart() { 134 LLDB_INSTRUMENT_VA(this); 135 136 return m_opaque ? m_opaque->StartReadThread() : false; 137 } 138 139 bool SBCommunication::ReadThreadStop() { 140 LLDB_INSTRUMENT_VA(this); 141 142 return m_opaque ? m_opaque->StopReadThread() : false; 143 } 144 145 bool SBCommunication::ReadThreadIsRunning() { 146 LLDB_INSTRUMENT_VA(this); 147 148 return m_opaque ? m_opaque->ReadThreadIsRunning() : false; 149 } 150 151 bool SBCommunication::SetReadThreadBytesReceivedCallback( 152 ReadThreadBytesReceived callback, void *callback_baton) { 153 LLDB_INSTRUMENT_VA(this, callback, callback_baton); 154 155 bool result = false; 156 if (m_opaque) { 157 m_opaque->SetReadThreadBytesReceivedCallback(callback, callback_baton); 158 result = true; 159 } 160 return result; 161 } 162 163 SBBroadcaster SBCommunication::GetBroadcaster() { 164 LLDB_INSTRUMENT_VA(this); 165 166 SBBroadcaster broadcaster(m_opaque, false); 167 return broadcaster; 168 } 169 170 const char *SBCommunication::GetBroadcasterClass() { 171 LLDB_INSTRUMENT(); 172 173 return ThreadedCommunication::GetStaticBroadcasterClass().AsCString(); 174 } 175