Path: blob/main/contrib/llvm-project/lldb/source/Core/Communication.cpp
39587 views
//===-- Communication.cpp -------------------------------------------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//78#include "lldb/Core/Communication.h"910#include "lldb/Utility/Connection.h"11#include "lldb/Utility/LLDBLog.h"12#include "lldb/Utility/Log.h"13#include "lldb/Utility/Status.h"1415#include "llvm/Support/Compiler.h"1617#include <algorithm>18#include <cstring>19#include <memory>2021#include <cerrno>22#include <cinttypes>23#include <cstdio>2425using namespace lldb;26using namespace lldb_private;2728Communication::Communication()29: m_connection_sp(), m_write_mutex(), m_close_on_eof(true) {30}3132Communication::~Communication() {33Clear();34}3536void Communication::Clear() {37Disconnect(nullptr);38}3940ConnectionStatus Communication::Connect(const char *url, Status *error_ptr) {41Clear();4243LLDB_LOG(GetLog(LLDBLog::Communication),44"{0} Communication::Connect (url = {1})", this, url);4546lldb::ConnectionSP connection_sp(m_connection_sp);47if (connection_sp)48return connection_sp->Connect(url, error_ptr);49if (error_ptr)50error_ptr->SetErrorString("Invalid connection.");51return eConnectionStatusNoConnection;52}5354ConnectionStatus Communication::Disconnect(Status *error_ptr) {55LLDB_LOG(GetLog(LLDBLog::Communication), "{0} Communication::Disconnect ()",56this);5758lldb::ConnectionSP connection_sp(m_connection_sp);59if (connection_sp) {60ConnectionStatus status = connection_sp->Disconnect(error_ptr);61// We currently don't protect connection_sp with any mutex for multi-62// threaded environments. So lets not nuke our connection class without63// putting some multi-threaded protections in. We also probably don't want64// to pay for the overhead it might cause if every time we access the65// connection we have to take a lock.66//67// This unique pointer will cleanup after itself when this object goes68// away, so there is no need to currently have it destroy itself69// immediately upon disconnect.70// connection_sp.reset();71return status;72}73return eConnectionStatusNoConnection;74}7576bool Communication::IsConnected() const {77lldb::ConnectionSP connection_sp(m_connection_sp);78return (connection_sp ? connection_sp->IsConnected() : false);79}8081bool Communication::HasConnection() const {82return m_connection_sp.get() != nullptr;83}8485size_t Communication::Read(void *dst, size_t dst_len,86const Timeout<std::micro> &timeout,87ConnectionStatus &status, Status *error_ptr) {88Log *log = GetLog(LLDBLog::Communication);89LLDB_LOG(90log,91"this = {0}, dst = {1}, dst_len = {2}, timeout = {3}, connection = {4}",92this, dst, dst_len, timeout, m_connection_sp.get());9394return ReadFromConnection(dst, dst_len, timeout, status, error_ptr);95}9697size_t Communication::Write(const void *src, size_t src_len,98ConnectionStatus &status, Status *error_ptr) {99lldb::ConnectionSP connection_sp(m_connection_sp);100101std::lock_guard<std::mutex> guard(m_write_mutex);102LLDB_LOG(GetLog(LLDBLog::Communication),103"{0} Communication::Write (src = {1}, src_len = {2}"104") connection = {3}",105this, src, (uint64_t)src_len, connection_sp.get());106107if (connection_sp)108return connection_sp->Write(src, src_len, status, error_ptr);109110if (error_ptr)111error_ptr->SetErrorString("Invalid connection.");112status = eConnectionStatusNoConnection;113return 0;114}115116size_t Communication::WriteAll(const void *src, size_t src_len,117ConnectionStatus &status, Status *error_ptr) {118size_t total_written = 0;119do120total_written += Write(static_cast<const char *>(src) + total_written,121src_len - total_written, status, error_ptr);122while (status == eConnectionStatusSuccess && total_written < src_len);123return total_written;124}125126size_t Communication::ReadFromConnection(void *dst, size_t dst_len,127const Timeout<std::micro> &timeout,128ConnectionStatus &status,129Status *error_ptr) {130lldb::ConnectionSP connection_sp(m_connection_sp);131if (connection_sp)132return connection_sp->Read(dst, dst_len, timeout, status, error_ptr);133134if (error_ptr)135error_ptr->SetErrorString("Invalid connection.");136status = eConnectionStatusNoConnection;137return 0;138}139140void Communication::SetConnection(std::unique_ptr<Connection> connection) {141Disconnect(nullptr);142m_connection_sp = std::move(connection);143}144145std::string146Communication::ConnectionStatusAsString(lldb::ConnectionStatus status) {147switch (status) {148case eConnectionStatusSuccess:149return "success";150case eConnectionStatusError:151return "error";152case eConnectionStatusTimedOut:153return "timed out";154case eConnectionStatusNoConnection:155return "no connection";156case eConnectionStatusLostConnection:157return "lost connection";158case eConnectionStatusEndOfFile:159return "end of file";160case eConnectionStatusInterrupted:161return "interrupted";162}163164return "@" + std::to_string(status);165}166167168