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(NULL), 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 = NULL;
32   m_opaque_owned = false;
33 }
34 
35 bool SBCommunication::IsValid() const {
36   LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBCommunication, IsValid);
37 
38   return m_opaque != NULL;
39 }
40 
41 bool SBCommunication::GetCloseOnEOF() {
42   LLDB_RECORD_METHOD_NO_ARGS(bool, SBCommunication, GetCloseOnEOF);
43 
44   if (m_opaque)
45     return m_opaque->GetCloseOnEOF();
46   return false;
47 }
48 
49 void SBCommunication::SetCloseOnEOF(bool b) {
50   LLDB_RECORD_METHOD(void, SBCommunication, SetCloseOnEOF, (bool), b);
51 
52   if (m_opaque)
53     m_opaque->SetCloseOnEOF(b);
54 }
55 
56 ConnectionStatus SBCommunication::Connect(const char *url) {
57   LLDB_RECORD_METHOD(lldb::ConnectionStatus, SBCommunication, Connect,
58                      (const char *), url);
59 
60   if (m_opaque) {
61     if (!m_opaque->HasConnection())
62       m_opaque->SetConnection(Host::CreateDefaultConnection(url).release());
63     return m_opaque->Connect(url, NULL);
64   }
65   return eConnectionStatusNoConnection;
66 }
67 
68 ConnectionStatus SBCommunication::AdoptFileDesriptor(int fd, bool owns_fd) {
69   LLDB_RECORD_METHOD(lldb::ConnectionStatus, SBCommunication,
70                      AdoptFileDesriptor, (int, bool), fd, owns_fd);
71 
72   ConnectionStatus status = eConnectionStatusNoConnection;
73   if (m_opaque) {
74     if (m_opaque->HasConnection()) {
75       if (m_opaque->IsConnected())
76         m_opaque->Disconnect();
77     }
78     m_opaque->SetConnection(new ConnectionFileDescriptor(fd, owns_fd));
79     if (m_opaque->IsConnected())
80       status = eConnectionStatusSuccess;
81     else
82       status = eConnectionStatusLostConnection;
83   }
84   return status;
85 }
86 
87 ConnectionStatus SBCommunication::Disconnect() {
88   LLDB_RECORD_METHOD_NO_ARGS(lldb::ConnectionStatus, SBCommunication,
89                              Disconnect);
90 
91   ConnectionStatus status = eConnectionStatusNoConnection;
92   if (m_opaque)
93     status = m_opaque->Disconnect();
94   return status;
95 }
96 
97 bool SBCommunication::IsConnected() const {
98   LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBCommunication, IsConnected);
99 
100   return m_opaque ? m_opaque->IsConnected() : false;
101 }
102 
103 size_t SBCommunication::Read(void *dst, size_t dst_len, uint32_t timeout_usec,
104                              ConnectionStatus &status) {
105   LLDB_RECORD_DUMMY(size_t, SBCommunication, Read,
106                     (void *, size_t, uint32_t, lldb::ConnectionStatus &), dst,
107                     dst_len, timeout_usec, status);
108 
109   size_t bytes_read = 0;
110   Timeout<std::micro> timeout = timeout_usec == UINT32_MAX
111                                     ? Timeout<std::micro>(llvm::None)
112                                     : std::chrono::microseconds(timeout_usec);
113   if (m_opaque)
114     bytes_read = m_opaque->Read(dst, dst_len, timeout, status, NULL);
115   else
116     status = eConnectionStatusNoConnection;
117 
118   return bytes_read;
119 }
120 
121 size_t SBCommunication::Write(const void *src, size_t src_len,
122                               ConnectionStatus &status) {
123   LLDB_RECORD_DUMMY(size_t, SBCommunication, Write,
124                     (const void *, size_t, lldb::ConnectionStatus &), src,
125                     src_len, status);
126 
127   size_t bytes_written = 0;
128   if (m_opaque)
129     bytes_written = m_opaque->Write(src, src_len, status, NULL);
130   else
131     status = eConnectionStatusNoConnection;
132 
133   return bytes_written;
134 }
135 
136 bool SBCommunication::ReadThreadStart() {
137   LLDB_RECORD_METHOD_NO_ARGS(bool, SBCommunication, ReadThreadStart);
138 
139   return m_opaque ? m_opaque->StartReadThread() : false;
140 }
141 
142 bool SBCommunication::ReadThreadStop() {
143   LLDB_RECORD_METHOD_NO_ARGS(bool, SBCommunication, ReadThreadStop);
144 
145   return m_opaque ? m_opaque->StopReadThread() : false;
146 }
147 
148 bool SBCommunication::ReadThreadIsRunning() {
149   LLDB_RECORD_METHOD_NO_ARGS(bool, SBCommunication, ReadThreadIsRunning);
150 
151   return m_opaque ? m_opaque->ReadThreadIsRunning() : false;
152 }
153 
154 bool SBCommunication::SetReadThreadBytesReceivedCallback(
155     ReadThreadBytesReceived callback, void *callback_baton) {
156   LLDB_RECORD_DUMMY(bool, SBCommunication, SetReadThreadBytesReceivedCallback,
157                     (lldb::SBCommunication::ReadThreadBytesReceived, void *),
158                     callback, callback_baton);
159 
160   bool result = false;
161   if (m_opaque) {
162     m_opaque->SetReadThreadBytesReceivedCallback(callback, callback_baton);
163     result = true;
164   }
165   return result;
166 }
167 
168 SBBroadcaster SBCommunication::GetBroadcaster() {
169   LLDB_RECORD_METHOD_NO_ARGS(lldb::SBBroadcaster, SBCommunication,
170                              GetBroadcaster);
171 
172   SBBroadcaster broadcaster(m_opaque, false);
173   return LLDB_RECORD_RESULT(broadcaster);
174 }
175 
176 const char *SBCommunication::GetBroadcasterClass() {
177   LLDB_RECORD_STATIC_METHOD_NO_ARGS(const char *, SBCommunication,
178                                     GetBroadcasterClass);
179 
180   return Communication::GetStaticBroadcasterClass().AsCString();
181 }
182