Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/lldb/source/Core/Communication.cpp
39587 views
1
//===-- Communication.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/Core/Communication.h"
10
11
#include "lldb/Utility/Connection.h"
12
#include "lldb/Utility/LLDBLog.h"
13
#include "lldb/Utility/Log.h"
14
#include "lldb/Utility/Status.h"
15
16
#include "llvm/Support/Compiler.h"
17
18
#include <algorithm>
19
#include <cstring>
20
#include <memory>
21
22
#include <cerrno>
23
#include <cinttypes>
24
#include <cstdio>
25
26
using namespace lldb;
27
using namespace lldb_private;
28
29
Communication::Communication()
30
: m_connection_sp(), m_write_mutex(), m_close_on_eof(true) {
31
}
32
33
Communication::~Communication() {
34
Clear();
35
}
36
37
void Communication::Clear() {
38
Disconnect(nullptr);
39
}
40
41
ConnectionStatus Communication::Connect(const char *url, Status *error_ptr) {
42
Clear();
43
44
LLDB_LOG(GetLog(LLDBLog::Communication),
45
"{0} Communication::Connect (url = {1})", this, url);
46
47
lldb::ConnectionSP connection_sp(m_connection_sp);
48
if (connection_sp)
49
return connection_sp->Connect(url, error_ptr);
50
if (error_ptr)
51
error_ptr->SetErrorString("Invalid connection.");
52
return eConnectionStatusNoConnection;
53
}
54
55
ConnectionStatus Communication::Disconnect(Status *error_ptr) {
56
LLDB_LOG(GetLog(LLDBLog::Communication), "{0} Communication::Disconnect ()",
57
this);
58
59
lldb::ConnectionSP connection_sp(m_connection_sp);
60
if (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.
67
//
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();
72
return status;
73
}
74
return eConnectionStatusNoConnection;
75
}
76
77
bool Communication::IsConnected() const {
78
lldb::ConnectionSP connection_sp(m_connection_sp);
79
return (connection_sp ? connection_sp->IsConnected() : false);
80
}
81
82
bool Communication::HasConnection() const {
83
return m_connection_sp.get() != nullptr;
84
}
85
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);
90
LLDB_LOG(
91
log,
92
"this = {0}, dst = {1}, dst_len = {2}, timeout = {3}, connection = {4}",
93
this, dst, dst_len, timeout, m_connection_sp.get());
94
95
return ReadFromConnection(dst, dst_len, timeout, status, error_ptr);
96
}
97
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);
101
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());
107
108
if (connection_sp)
109
return connection_sp->Write(src, src_len, status, error_ptr);
110
111
if (error_ptr)
112
error_ptr->SetErrorString("Invalid connection.");
113
status = eConnectionStatusNoConnection;
114
return 0;
115
}
116
117
size_t Communication::WriteAll(const void *src, size_t src_len,
118
ConnectionStatus &status, Status *error_ptr) {
119
size_t total_written = 0;
120
do
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;
125
}
126
127
size_t Communication::ReadFromConnection(void *dst, size_t dst_len,
128
const Timeout<std::micro> &timeout,
129
ConnectionStatus &status,
130
Status *error_ptr) {
131
lldb::ConnectionSP connection_sp(m_connection_sp);
132
if (connection_sp)
133
return connection_sp->Read(dst, dst_len, timeout, status, error_ptr);
134
135
if (error_ptr)
136
error_ptr->SetErrorString("Invalid connection.");
137
status = eConnectionStatusNoConnection;
138
return 0;
139
}
140
141
void Communication::SetConnection(std::unique_ptr<Connection> connection) {
142
Disconnect(nullptr);
143
m_connection_sp = std::move(connection);
144
}
145
146
std::string
147
Communication::ConnectionStatusAsString(lldb::ConnectionStatus status) {
148
switch (status) {
149
case eConnectionStatusSuccess:
150
return "success";
151
case eConnectionStatusError:
152
return "error";
153
case eConnectionStatusTimedOut:
154
return "timed out";
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";
163
}
164
165
return "@" + std::to_string(status);
166
}
167
168