1 //===-- SBCommunication.cpp -------------------------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "lldb/API/SBCommunication.h" 11 #include "lldb/API/SBBroadcaster.h" 12 #include "lldb/Core/Communication.h" 13 #include "lldb/Core/Log.h" 14 #include "lldb/Host/ConnectionFileDescriptor.h" 15 16 using namespace lldb; 17 using namespace lldb_private; 18 19 SBCommunication::SBCommunication() : m_opaque(NULL), m_opaque_owned(false) {} 20 21 SBCommunication::SBCommunication(const char *broadcaster_name) 22 : m_opaque(new Communication(broadcaster_name)), m_opaque_owned(true) { 23 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 24 25 if (log) 26 log->Printf("SBCommunication::SBCommunication (broadcaster_name=\"%s\") => " 27 "SBCommunication(%p)", 28 broadcaster_name, static_cast<void *>(m_opaque)); 29 } 30 31 SBCommunication::~SBCommunication() { 32 if (m_opaque && m_opaque_owned) 33 delete m_opaque; 34 m_opaque = NULL; 35 m_opaque_owned = false; 36 } 37 38 bool SBCommunication::IsValid() const { return m_opaque != NULL; } 39 40 bool SBCommunication::GetCloseOnEOF() { 41 if (m_opaque) 42 return m_opaque->GetCloseOnEOF(); 43 return false; 44 } 45 46 void SBCommunication::SetCloseOnEOF(bool b) { 47 if (m_opaque) 48 m_opaque->SetCloseOnEOF(b); 49 } 50 51 ConnectionStatus SBCommunication::Connect(const char *url) { 52 if (m_opaque) { 53 if (!m_opaque->HasConnection()) 54 m_opaque->SetConnection(Connection::CreateDefaultConnection(url)); 55 return m_opaque->Connect(url, NULL); 56 } 57 return eConnectionStatusNoConnection; 58 } 59 60 ConnectionStatus SBCommunication::AdoptFileDesriptor(int fd, bool owns_fd) { 61 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 62 63 ConnectionStatus status = eConnectionStatusNoConnection; 64 if (m_opaque) { 65 if (m_opaque->HasConnection()) { 66 if (m_opaque->IsConnected()) 67 m_opaque->Disconnect(); 68 } 69 m_opaque->SetConnection(new ConnectionFileDescriptor(fd, owns_fd)); 70 if (m_opaque->IsConnected()) 71 status = eConnectionStatusSuccess; 72 else 73 status = eConnectionStatusLostConnection; 74 } 75 76 if (log) 77 log->Printf( 78 "SBCommunication(%p)::AdoptFileDescriptor (fd=%d, ownd_fd=%i) => %s", 79 static_cast<void *>(m_opaque), fd, owns_fd, 80 Communication::ConnectionStatusAsCString(status)); 81 82 return status; 83 } 84 85 ConnectionStatus SBCommunication::Disconnect() { 86 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 87 88 ConnectionStatus status = eConnectionStatusNoConnection; 89 if (m_opaque) 90 status = m_opaque->Disconnect(); 91 92 if (log) 93 log->Printf("SBCommunication(%p)::Disconnect () => %s", 94 static_cast<void *>(m_opaque), 95 Communication::ConnectionStatusAsCString(status)); 96 97 return status; 98 } 99 100 bool SBCommunication::IsConnected() const { 101 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 102 bool result = false; 103 if (m_opaque) 104 result = m_opaque->IsConnected(); 105 106 if (log) 107 log->Printf("SBCommunication(%p)::IsConnected () => %i", 108 static_cast<void *>(m_opaque), result); 109 110 return false; 111 } 112 113 size_t SBCommunication::Read(void *dst, size_t dst_len, uint32_t timeout_usec, 114 ConnectionStatus &status) { 115 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 116 if (log) 117 log->Printf("SBCommunication(%p)::Read (dst=%p, dst_len=%" PRIu64 118 ", timeout_usec=%u, &status)...", 119 static_cast<void *>(m_opaque), static_cast<void *>(dst), 120 static_cast<uint64_t>(dst_len), timeout_usec); 121 size_t bytes_read = 0; 122 Timeout<std::micro> timeout = timeout_usec == UINT32_MAX 123 ? Timeout<std::micro>(llvm::None) 124 : std::chrono::microseconds(timeout_usec); 125 if (m_opaque) 126 bytes_read = m_opaque->Read(dst, dst_len, timeout, status, NULL); 127 else 128 status = eConnectionStatusNoConnection; 129 130 if (log) 131 log->Printf("SBCommunication(%p)::Read (dst=%p, dst_len=%" PRIu64 132 ", timeout_usec=%u, &status=%s) => %" PRIu64, 133 static_cast<void *>(m_opaque), static_cast<void *>(dst), 134 static_cast<uint64_t>(dst_len), timeout_usec, 135 Communication::ConnectionStatusAsCString(status), 136 static_cast<uint64_t>(bytes_read)); 137 return bytes_read; 138 } 139 140 size_t SBCommunication::Write(const void *src, size_t src_len, 141 ConnectionStatus &status) { 142 size_t bytes_written = 0; 143 if (m_opaque) 144 bytes_written = m_opaque->Write(src, src_len, status, NULL); 145 else 146 status = eConnectionStatusNoConnection; 147 148 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 149 if (log) 150 log->Printf("SBCommunication(%p)::Write (src=%p, src_len=%" PRIu64 151 ", &status=%s) => %" PRIu64, 152 static_cast<void *>(m_opaque), static_cast<const void *>(src), 153 static_cast<uint64_t>(src_len), 154 Communication::ConnectionStatusAsCString(status), 155 static_cast<uint64_t>(bytes_written)); 156 157 return 0; 158 } 159 160 bool SBCommunication::ReadThreadStart() { 161 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 162 163 bool success = false; 164 if (m_opaque) 165 success = m_opaque->StartReadThread(); 166 167 if (log) 168 log->Printf("SBCommunication(%p)::ReadThreadStart () => %i", 169 static_cast<void *>(m_opaque), success); 170 171 return success; 172 } 173 174 bool SBCommunication::ReadThreadStop() { 175 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 176 if (log) 177 log->Printf("SBCommunication(%p)::ReadThreadStop ()...", 178 static_cast<void *>(m_opaque)); 179 180 bool success = false; 181 if (m_opaque) 182 success = m_opaque->StopReadThread(); 183 184 if (log) 185 log->Printf("SBCommunication(%p)::ReadThreadStop () => %i", 186 static_cast<void *>(m_opaque), success); 187 188 return success; 189 } 190 191 bool SBCommunication::ReadThreadIsRunning() { 192 bool result = false; 193 if (m_opaque) 194 result = m_opaque->ReadThreadIsRunning(); 195 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 196 if (log) 197 log->Printf("SBCommunication(%p)::ReadThreadIsRunning () => %i", 198 static_cast<void *>(m_opaque), result); 199 return result; 200 } 201 202 bool SBCommunication::SetReadThreadBytesReceivedCallback( 203 ReadThreadBytesReceived callback, void *callback_baton) { 204 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 205 206 bool result = false; 207 if (m_opaque) { 208 m_opaque->SetReadThreadBytesReceivedCallback(callback, callback_baton); 209 result = true; 210 } 211 212 if (log) 213 log->Printf("SBCommunication(%p)::SetReadThreadBytesReceivedCallback " 214 "(callback=%p, baton=%p) => %i", 215 static_cast<void *>(m_opaque), 216 reinterpret_cast<void *>(reinterpret_cast<intptr_t>(callback)), 217 static_cast<void *>(callback_baton), result); 218 219 return result; 220 } 221 222 SBBroadcaster SBCommunication::GetBroadcaster() { 223 SBBroadcaster broadcaster(m_opaque, false); 224 225 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 226 227 if (log) 228 log->Printf("SBCommunication(%p)::GetBroadcaster () => SBBroadcaster (%p)", 229 static_cast<void *>(m_opaque), 230 static_cast<void *>(broadcaster.get())); 231 232 return broadcaster; 233 } 234 235 const char *SBCommunication::GetBroadcasterClass() { 236 return Communication::GetStaticBroadcasterClass().AsCString(); 237 } 238 239 // 240 // void 241 // SBCommunication::CreateIfNeeded () 242 //{ 243 // if (m_opaque == NULL) 244 // { 245 // static uint32_t g_broadcaster_num; 246 // char broadcaster_name[256]; 247 // ::snprintf (name, broadcaster_name, "%p SBCommunication", this); 248 // m_opaque = new Communication (broadcaster_name); 249 // m_opaque_owned = true; 250 // } 251 // assert (m_opaque); 252 //} 253 // 254 // 255