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 
SBCommunication()19 SBCommunication::SBCommunication() { LLDB_INSTRUMENT_VA(this); }
20 
SBCommunication(const char * broadcaster_name)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 
~SBCommunication()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 
IsValid() const34 bool SBCommunication::IsValid() const {
35   LLDB_INSTRUMENT_VA(this);
36   return this->operator bool();
37 }
operator bool() const38 SBCommunication::operator bool() const {
39   LLDB_INSTRUMENT_VA(this);
40 
41   return m_opaque != nullptr;
42 }
43 
GetCloseOnEOF()44 bool SBCommunication::GetCloseOnEOF() {
45   LLDB_INSTRUMENT_VA(this);
46 
47   if (m_opaque)
48     return m_opaque->GetCloseOnEOF();
49   return false;
50 }
51 
SetCloseOnEOF(bool b)52 void SBCommunication::SetCloseOnEOF(bool b) {
53   LLDB_INSTRUMENT_VA(this, b);
54 
55   if (m_opaque)
56     m_opaque->SetCloseOnEOF(b);
57 }
58 
Connect(const char * url)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 
AdoptFileDesriptor(int fd,bool owns_fd)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 
Disconnect()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 
IsConnected() const98 bool SBCommunication::IsConnected() const {
99   LLDB_INSTRUMENT_VA(this);
100 
101   return m_opaque ? m_opaque->IsConnected() : false;
102 }
103 
Read(void * dst,size_t dst_len,uint32_t timeout_usec,ConnectionStatus & status)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 
Write(const void * src,size_t src_len,ConnectionStatus & status)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 
ReadThreadStart()133 bool SBCommunication::ReadThreadStart() {
134   LLDB_INSTRUMENT_VA(this);
135 
136   return m_opaque ? m_opaque->StartReadThread() : false;
137 }
138 
ReadThreadStop()139 bool SBCommunication::ReadThreadStop() {
140   LLDB_INSTRUMENT_VA(this);
141 
142   return m_opaque ? m_opaque->StopReadThread() : false;
143 }
144 
ReadThreadIsRunning()145 bool SBCommunication::ReadThreadIsRunning() {
146   LLDB_INSTRUMENT_VA(this);
147 
148   return m_opaque ? m_opaque->ReadThreadIsRunning() : false;
149 }
150 
SetReadThreadBytesReceivedCallback(ReadThreadBytesReceived callback,void * callback_baton)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 
GetBroadcaster()163 SBBroadcaster SBCommunication::GetBroadcaster() {
164   LLDB_INSTRUMENT_VA(this);
165 
166   SBBroadcaster broadcaster(m_opaque, false);
167   return broadcaster;
168 }
169 
GetBroadcasterClass()170 const char *SBCommunication::GetBroadcasterClass() {
171   LLDB_INSTRUMENT();
172 
173   return ThreadedCommunication::GetStaticBroadcasterClass().AsCString();
174 }
175