brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.3 KiB · 950186c Raw
167 lines · cpp
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-exception6//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 26using namespace lldb;27using namespace lldb_private;28 29Communication::Communication()30    : m_connection_sp(), m_write_mutex(), m_close_on_eof(true) {31}32 33Communication::~Communication() {34  Clear();35}36 37void Communication::Clear() {38  Disconnect(nullptr);39}40 41ConnectionStatus 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 = Status::FromErrorString("Invalid connection.");52  return eConnectionStatusNoConnection;53}54 55ConnectionStatus 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 without64    // putting some multi-threaded protections in. We also probably don't want65    // to pay for the overhead it might cause if every time we access the66    // connection we have to take a lock.67    //68    // This unique pointer will cleanup after itself when this object goes69    // away, so there is no need to currently have it destroy itself70    // immediately upon disconnect.71    // connection_sp.reset();72    return status;73  }74  return eConnectionStatusNoConnection;75}76 77bool Communication::IsConnected() const {78  lldb::ConnectionSP connection_sp(m_connection_sp);79  return (connection_sp ? connection_sp->IsConnected() : false);80}81 82bool Communication::HasConnection() const {83  return m_connection_sp.get() != nullptr;84}85 86size_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 98size_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 = Status::FromErrorString("Invalid connection.");113  status = eConnectionStatusNoConnection;114  return 0;115}116 117size_t Communication::WriteAll(const void *src, size_t src_len,118                               ConnectionStatus &status, Status *error_ptr) {119  size_t total_written = 0;120  do121    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 127size_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 = Status::FromErrorString("Invalid connection.");137  status = eConnectionStatusNoConnection;138  return 0;139}140 141void Communication::SetConnection(std::unique_ptr<Connection> connection) {142  Disconnect(nullptr);143  m_connection_sp = std::move(connection);144}145 146std::string147Communication::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