1 //===-- Communication.cpp -------------------------------------------------===//
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
7 //===----------------------------------------------------------------------===//
9 #include "lldb/Core/Communication.h"
11 #include "lldb/Utility/Connection.h"
12 #include "lldb/Utility/LLDBLog.h"
13 #include "lldb/Utility/Log.h"
14 #include "lldb/Utility/Status.h"
16 #include "llvm/Support/Compiler.h"
27 using namespace lldb_private
;
29 Communication::Communication()
30 : m_connection_sp(), m_write_mutex(), m_close_on_eof(true) {
33 Communication::~Communication() {
37 void Communication::Clear() {
41 ConnectionStatus
Communication::Connect(const char *url
, Status
*error_ptr
) {
44 LLDB_LOG(GetLog(LLDBLog::Communication
),
45 "{0} Communication::Connect (url = {1})", this, url
);
47 lldb::ConnectionSP
connection_sp(m_connection_sp
);
49 return connection_sp
->Connect(url
, error_ptr
);
51 *error_ptr
= Status::FromErrorString("Invalid connection.");
52 return eConnectionStatusNoConnection
;
55 ConnectionStatus
Communication::Disconnect(Status
*error_ptr
) {
56 LLDB_LOG(GetLog(LLDBLog::Communication
), "{0} Communication::Disconnect ()",
59 lldb::ConnectionSP
connection_sp(m_connection_sp
);
61 ConnectionStatus status
= connection_sp
->Disconnect(error_ptr
);
62 // We currently don't protect connection_sp with any mutex for multi-
63 // threaded environments. So lets not nuke our connection class without
64 // putting some multi-threaded protections in. We also probably don't want
65 // to pay for the overhead it might cause if every time we access the
66 // connection we have to take a lock.
68 // This unique pointer will cleanup after itself when this object goes
69 // away, so there is no need to currently have it destroy itself
70 // immediately upon disconnect.
71 // connection_sp.reset();
74 return eConnectionStatusNoConnection
;
77 bool Communication::IsConnected() const {
78 lldb::ConnectionSP
connection_sp(m_connection_sp
);
79 return (connection_sp
? connection_sp
->IsConnected() : false);
82 bool Communication::HasConnection() const {
83 return m_connection_sp
.get() != nullptr;
86 size_t Communication::Read(void *dst
, size_t dst_len
,
87 const Timeout
<std::micro
> &timeout
,
88 ConnectionStatus
&status
, Status
*error_ptr
) {
89 Log
*log
= GetLog(LLDBLog::Communication
);
92 "this = {0}, dst = {1}, dst_len = {2}, timeout = {3}, connection = {4}",
93 this, dst
, dst_len
, timeout
, m_connection_sp
.get());
95 return ReadFromConnection(dst
, dst_len
, timeout
, status
, error_ptr
);
98 size_t Communication::Write(const void *src
, size_t src_len
,
99 ConnectionStatus
&status
, Status
*error_ptr
) {
100 lldb::ConnectionSP
connection_sp(m_connection_sp
);
102 std::lock_guard
<std::mutex
> guard(m_write_mutex
);
103 LLDB_LOG(GetLog(LLDBLog::Communication
),
104 "{0} Communication::Write (src = {1}, src_len = {2}"
105 ") connection = {3}",
106 this, src
, (uint64_t)src_len
, connection_sp
.get());
109 return connection_sp
->Write(src
, src_len
, status
, error_ptr
);
112 *error_ptr
= Status::FromErrorString("Invalid connection.");
113 status
= eConnectionStatusNoConnection
;
117 size_t Communication::WriteAll(const void *src
, size_t src_len
,
118 ConnectionStatus
&status
, Status
*error_ptr
) {
119 size_t total_written
= 0;
121 total_written
+= Write(static_cast<const char *>(src
) + total_written
,
122 src_len
- total_written
, status
, error_ptr
);
123 while (status
== eConnectionStatusSuccess
&& total_written
< src_len
);
124 return total_written
;
127 size_t Communication::ReadFromConnection(void *dst
, size_t dst_len
,
128 const Timeout
<std::micro
> &timeout
,
129 ConnectionStatus
&status
,
131 lldb::ConnectionSP
connection_sp(m_connection_sp
);
133 return connection_sp
->Read(dst
, dst_len
, timeout
, status
, error_ptr
);
136 *error_ptr
= Status::FromErrorString("Invalid connection.");
137 status
= eConnectionStatusNoConnection
;
141 void Communication::SetConnection(std::unique_ptr
<Connection
> connection
) {
143 m_connection_sp
= std::move(connection
);
147 Communication::ConnectionStatusAsString(lldb::ConnectionStatus status
) {
149 case eConnectionStatusSuccess
:
151 case eConnectionStatusError
:
153 case eConnectionStatusTimedOut
:
155 case eConnectionStatusNoConnection
:
156 return "no connection";
157 case eConnectionStatusLostConnection
:
158 return "lost connection";
159 case eConnectionStatusEndOfFile
:
160 return "end of file";
161 case eConnectionStatusInterrupted
:
162 return "interrupted";
165 return "@" + std::to_string(status
);