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, error_ptr: 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>(args&: fd, args&: 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, error_ptr: 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, error_ptr: 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 | |