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