1254721Semaste//===-- Communication.cpp ---------------------------------------*- C++ -*-===// 2254721Semaste// 3254721Semaste// The LLVM Compiler Infrastructure 4254721Semaste// 5254721Semaste// This file is distributed under the University of Illinois Open Source 6254721Semaste// License. See LICENSE.TXT for details. 7254721Semaste// 8254721Semaste//===----------------------------------------------------------------------===// 9254721Semaste 10254721Semaste// C Includes 11254721Semaste// C++ Includes 12254721Semaste// Other libraries and framework includes 13254721Semaste// Project includes 14254721Semaste#include "lldb/lldb-private-log.h" 15254721Semaste#include "lldb/Core/Communication.h" 16254721Semaste#include "lldb/Core/Connection.h" 17254721Semaste#include "lldb/Core/Log.h" 18254721Semaste#include "lldb/Core/Timer.h" 19254721Semaste#include "lldb/Core/Event.h" 20254721Semaste#include "lldb/Host/Host.h" 21254721Semaste#include <string.h> 22254721Semaste 23254721Semasteusing namespace lldb; 24254721Semasteusing namespace lldb_private; 25254721Semaste 26254721SemasteConstString & 27254721SemasteCommunication::GetStaticBroadcasterClass () 28254721Semaste{ 29254721Semaste static ConstString class_name ("lldb.communication"); 30254721Semaste return class_name; 31254721Semaste} 32254721Semaste 33254721Semaste//---------------------------------------------------------------------- 34254721Semaste// Constructor 35254721Semaste//---------------------------------------------------------------------- 36254721SemasteCommunication::Communication(const char *name) : 37254721Semaste Broadcaster (NULL, name), 38254721Semaste m_connection_sp (), 39254721Semaste m_read_thread (LLDB_INVALID_HOST_THREAD), 40254721Semaste m_read_thread_enabled (false), 41254721Semaste m_bytes(), 42254721Semaste m_bytes_mutex (Mutex::eMutexTypeRecursive), 43254721Semaste m_write_mutex (Mutex::eMutexTypeNormal), 44254721Semaste m_callback (NULL), 45254721Semaste m_callback_baton (NULL), 46254721Semaste m_close_on_eof (true) 47254721Semaste 48254721Semaste{ 49254721Semaste lldb_private::LogIfAnyCategoriesSet (LIBLLDB_LOG_OBJECT | LIBLLDB_LOG_COMMUNICATION, 50254721Semaste "%p Communication::Communication (name = %s)", 51254721Semaste this, name); 52254721Semaste 53254721Semaste SetEventName (eBroadcastBitDisconnected, "disconnected"); 54254721Semaste SetEventName (eBroadcastBitReadThreadGotBytes, "got bytes"); 55254721Semaste SetEventName (eBroadcastBitReadThreadDidExit, "read thread did exit"); 56254721Semaste SetEventName (eBroadcastBitReadThreadShouldExit, "read thread should exit"); 57254721Semaste SetEventName (eBroadcastBitPacketAvailable, "packet available"); 58254721Semaste 59254721Semaste CheckInWithManager(); 60254721Semaste} 61254721Semaste 62254721Semaste//---------------------------------------------------------------------- 63254721Semaste// Destructor 64254721Semaste//---------------------------------------------------------------------- 65254721SemasteCommunication::~Communication() 66254721Semaste{ 67254721Semaste lldb_private::LogIfAnyCategoriesSet (LIBLLDB_LOG_OBJECT | LIBLLDB_LOG_COMMUNICATION, 68254721Semaste "%p Communication::~Communication (name = %s)", 69254721Semaste this, m_broadcaster_name.AsCString("")); 70254721Semaste Clear(); 71254721Semaste} 72254721Semaste 73254721Semastevoid 74254721SemasteCommunication::Clear() 75254721Semaste{ 76254721Semaste SetReadThreadBytesReceivedCallback (NULL, NULL); 77254721Semaste Disconnect (NULL); 78254721Semaste StopReadThread (NULL); 79254721Semaste} 80254721Semaste 81254721SemasteConnectionStatus 82254721SemasteCommunication::Connect (const char *url, Error *error_ptr) 83254721Semaste{ 84254721Semaste Clear(); 85254721Semaste 86254721Semaste lldb_private::LogIfAnyCategoriesSet (LIBLLDB_LOG_COMMUNICATION, "%p Communication::Connect (url = %s)", this, url); 87254721Semaste 88254721Semaste lldb::ConnectionSP connection_sp (m_connection_sp); 89254721Semaste if (connection_sp.get()) 90254721Semaste return connection_sp->Connect (url, error_ptr); 91254721Semaste if (error_ptr) 92254721Semaste error_ptr->SetErrorString("Invalid connection."); 93254721Semaste return eConnectionStatusNoConnection; 94254721Semaste} 95254721Semaste 96254721SemasteConnectionStatus 97254721SemasteCommunication::Disconnect (Error *error_ptr) 98254721Semaste{ 99254721Semaste lldb_private::LogIfAnyCategoriesSet (LIBLLDB_LOG_COMMUNICATION, "%p Communication::Disconnect ()", this); 100254721Semaste 101254721Semaste lldb::ConnectionSP connection_sp (m_connection_sp); 102254721Semaste if (connection_sp.get()) 103254721Semaste { 104254721Semaste ConnectionStatus status = connection_sp->Disconnect (error_ptr); 105254721Semaste // We currently don't protect connection_sp with any mutex for 106254721Semaste // multi-threaded environments. So lets not nuke our connection class 107254721Semaste // without putting some multi-threaded protections in. We also probably 108254721Semaste // don't want to pay for the overhead it might cause if every time we 109254721Semaste // access the connection we have to take a lock. 110254721Semaste // 111254721Semaste // This unique pointer will cleanup after itself when this object goes away, 112254721Semaste // so there is no need to currently have it destroy itself immediately 113254721Semaste // upon disconnnect. 114254721Semaste //connection_sp.reset(); 115254721Semaste return status; 116254721Semaste } 117254721Semaste return eConnectionStatusNoConnection; 118254721Semaste} 119254721Semaste 120254721Semastebool 121254721SemasteCommunication::IsConnected () const 122254721Semaste{ 123254721Semaste lldb::ConnectionSP connection_sp (m_connection_sp); 124254721Semaste if (connection_sp.get()) 125254721Semaste return connection_sp->IsConnected (); 126254721Semaste return false; 127254721Semaste} 128254721Semaste 129254721Semastebool 130254721SemasteCommunication::HasConnection () const 131254721Semaste{ 132254721Semaste return m_connection_sp.get() != NULL; 133254721Semaste} 134254721Semaste 135254721Semastesize_t 136254721SemasteCommunication::Read (void *dst, size_t dst_len, uint32_t timeout_usec, ConnectionStatus &status, Error *error_ptr) 137254721Semaste{ 138254721Semaste lldb_private::LogIfAnyCategoriesSet (LIBLLDB_LOG_COMMUNICATION, 139254721Semaste "%p Communication::Read (dst = %p, dst_len = %" PRIu64 ", timeout = %u usec) connection = %p", 140254721Semaste this, 141254721Semaste dst, 142254721Semaste (uint64_t)dst_len, 143254721Semaste timeout_usec, 144254721Semaste m_connection_sp.get()); 145254721Semaste 146254721Semaste if (m_read_thread_enabled) 147254721Semaste { 148254721Semaste // We have a dedicated read thread that is getting data for us 149254721Semaste size_t cached_bytes = GetCachedBytes (dst, dst_len); 150254721Semaste if (cached_bytes > 0 || timeout_usec == 0) 151254721Semaste { 152254721Semaste status = eConnectionStatusSuccess; 153254721Semaste return cached_bytes; 154254721Semaste } 155254721Semaste 156254721Semaste if (m_connection_sp.get() == NULL) 157254721Semaste { 158254721Semaste if (error_ptr) 159254721Semaste error_ptr->SetErrorString("Invalid connection."); 160254721Semaste status = eConnectionStatusNoConnection; 161254721Semaste return 0; 162254721Semaste } 163254721Semaste // Set the timeout appropriately 164254721Semaste TimeValue timeout_time; 165254721Semaste if (timeout_usec != UINT32_MAX) 166254721Semaste { 167254721Semaste timeout_time = TimeValue::Now(); 168254721Semaste timeout_time.OffsetWithMicroSeconds (timeout_usec); 169254721Semaste } 170254721Semaste 171254721Semaste Listener listener ("Communication::Read"); 172254721Semaste listener.StartListeningForEvents (this, eBroadcastBitReadThreadGotBytes | eBroadcastBitReadThreadDidExit); 173254721Semaste EventSP event_sp; 174254721Semaste while (listener.WaitForEvent (timeout_time.IsValid() ? &timeout_time : NULL, event_sp)) 175254721Semaste { 176254721Semaste const uint32_t event_type = event_sp->GetType(); 177254721Semaste if (event_type & eBroadcastBitReadThreadGotBytes) 178254721Semaste { 179254721Semaste return GetCachedBytes (dst, dst_len); 180254721Semaste } 181254721Semaste 182254721Semaste if (event_type & eBroadcastBitReadThreadDidExit) 183254721Semaste { 184254721Semaste Disconnect (NULL); 185254721Semaste break; 186254721Semaste } 187254721Semaste } 188254721Semaste return 0; 189254721Semaste } 190254721Semaste 191254721Semaste // We aren't using a read thread, just read the data synchronously in this 192254721Semaste // thread. 193254721Semaste lldb::ConnectionSP connection_sp (m_connection_sp); 194254721Semaste if (connection_sp.get()) 195254721Semaste { 196254721Semaste return connection_sp->Read (dst, dst_len, timeout_usec, status, error_ptr); 197254721Semaste } 198254721Semaste 199254721Semaste if (error_ptr) 200254721Semaste error_ptr->SetErrorString("Invalid connection."); 201254721Semaste status = eConnectionStatusNoConnection; 202254721Semaste return 0; 203254721Semaste} 204254721Semaste 205254721Semaste 206254721Semastesize_t 207254721SemasteCommunication::Write (const void *src, size_t src_len, ConnectionStatus &status, Error *error_ptr) 208254721Semaste{ 209254721Semaste lldb::ConnectionSP connection_sp (m_connection_sp); 210254721Semaste 211254721Semaste Mutex::Locker locker(m_write_mutex); 212254721Semaste lldb_private::LogIfAnyCategoriesSet (LIBLLDB_LOG_COMMUNICATION, 213254721Semaste "%p Communication::Write (src = %p, src_len = %" PRIu64 ") connection = %p", 214254721Semaste this, 215254721Semaste src, 216254721Semaste (uint64_t)src_len, 217254721Semaste connection_sp.get()); 218254721Semaste 219254721Semaste if (connection_sp.get()) 220254721Semaste return connection_sp->Write (src, src_len, status, error_ptr); 221254721Semaste 222254721Semaste if (error_ptr) 223254721Semaste error_ptr->SetErrorString("Invalid connection."); 224254721Semaste status = eConnectionStatusNoConnection; 225254721Semaste return 0; 226254721Semaste} 227254721Semaste 228254721Semaste 229254721Semastebool 230254721SemasteCommunication::StartReadThread (Error *error_ptr) 231254721Semaste{ 232254721Semaste if (error_ptr) 233254721Semaste error_ptr->Clear(); 234254721Semaste 235254721Semaste if (IS_VALID_LLDB_HOST_THREAD(m_read_thread)) 236254721Semaste return true; 237254721Semaste 238254721Semaste lldb_private::LogIfAnyCategoriesSet (LIBLLDB_LOG_COMMUNICATION, 239254721Semaste "%p Communication::StartReadThread ()", this); 240254721Semaste 241254721Semaste 242254721Semaste char thread_name[1024]; 243254721Semaste snprintf(thread_name, sizeof(thread_name), "<lldb.comm.%s>", m_broadcaster_name.AsCString()); 244254721Semaste 245254721Semaste m_read_thread_enabled = true; 246254721Semaste m_read_thread = Host::ThreadCreate (thread_name, Communication::ReadThread, this, error_ptr); 247254721Semaste if (!IS_VALID_LLDB_HOST_THREAD(m_read_thread)) 248254721Semaste m_read_thread_enabled = false; 249254721Semaste return m_read_thread_enabled; 250254721Semaste} 251254721Semaste 252254721Semastebool 253254721SemasteCommunication::StopReadThread (Error *error_ptr) 254254721Semaste{ 255254721Semaste if (!IS_VALID_LLDB_HOST_THREAD(m_read_thread)) 256254721Semaste return true; 257254721Semaste 258254721Semaste lldb_private::LogIfAnyCategoriesSet (LIBLLDB_LOG_COMMUNICATION, 259254721Semaste "%p Communication::StopReadThread ()", this); 260254721Semaste 261254721Semaste m_read_thread_enabled = false; 262254721Semaste 263254721Semaste BroadcastEvent (eBroadcastBitReadThreadShouldExit, NULL); 264254721Semaste 265254721Semaste //Host::ThreadCancel (m_read_thread, error_ptr); 266254721Semaste 267254721Semaste bool status = Host::ThreadJoin (m_read_thread, NULL, error_ptr); 268254721Semaste m_read_thread = LLDB_INVALID_HOST_THREAD; 269254721Semaste return status; 270254721Semaste} 271254721Semaste 272254721Semaste 273254721Semastesize_t 274254721SemasteCommunication::GetCachedBytes (void *dst, size_t dst_len) 275254721Semaste{ 276254721Semaste Mutex::Locker locker(m_bytes_mutex); 277254721Semaste if (m_bytes.size() > 0) 278254721Semaste { 279254721Semaste // If DST is NULL and we have a thread, then return the number 280254721Semaste // of bytes that are available so the caller can call again 281254721Semaste if (dst == NULL) 282254721Semaste return m_bytes.size(); 283254721Semaste 284254721Semaste const size_t len = std::min<size_t>(dst_len, m_bytes.size()); 285254721Semaste 286254721Semaste ::memcpy (dst, m_bytes.c_str(), len); 287254721Semaste m_bytes.erase(m_bytes.begin(), m_bytes.begin() + len); 288254721Semaste 289254721Semaste return len; 290254721Semaste } 291254721Semaste return 0; 292254721Semaste} 293254721Semaste 294254721Semastevoid 295254721SemasteCommunication::AppendBytesToCache (const uint8_t * bytes, size_t len, bool broadcast, ConnectionStatus status) 296254721Semaste{ 297254721Semaste lldb_private::LogIfAnyCategoriesSet (LIBLLDB_LOG_COMMUNICATION, 298254721Semaste "%p Communication::AppendBytesToCache (src = %p, src_len = %" PRIu64 ", broadcast = %i)", 299254721Semaste this, bytes, (uint64_t)len, broadcast); 300254721Semaste if ((bytes == NULL || len == 0) 301254721Semaste && (status != lldb::eConnectionStatusEndOfFile)) 302254721Semaste return; 303254721Semaste if (m_callback) 304254721Semaste { 305254721Semaste // If the user registered a callback, then call it and do not broadcast 306254721Semaste m_callback (m_callback_baton, bytes, len); 307254721Semaste } 308254721Semaste else if (bytes != NULL && len > 0) 309254721Semaste { 310254721Semaste Mutex::Locker locker(m_bytes_mutex); 311254721Semaste m_bytes.append ((const char *)bytes, len); 312254721Semaste if (broadcast) 313254721Semaste BroadcastEventIfUnique (eBroadcastBitReadThreadGotBytes); 314254721Semaste } 315254721Semaste} 316254721Semaste 317254721Semastesize_t 318254721SemasteCommunication::ReadFromConnection (void *dst, 319254721Semaste size_t dst_len, 320254721Semaste uint32_t timeout_usec, 321254721Semaste ConnectionStatus &status, 322254721Semaste Error *error_ptr) 323254721Semaste{ 324254721Semaste lldb::ConnectionSP connection_sp (m_connection_sp); 325254721Semaste if (connection_sp.get()) 326254721Semaste return connection_sp->Read (dst, dst_len, timeout_usec, status, error_ptr); 327254721Semaste return 0; 328254721Semaste} 329254721Semaste 330254721Semastebool 331254721SemasteCommunication::ReadThreadIsRunning () 332254721Semaste{ 333254721Semaste return m_read_thread_enabled; 334254721Semaste} 335254721Semaste 336254721Semastevoid * 337254721SemasteCommunication::ReadThread (void *p) 338254721Semaste{ 339254721Semaste Communication *comm = (Communication *)p; 340254721Semaste 341254721Semaste Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_COMMUNICATION)); 342254721Semaste 343254721Semaste if (log) 344254721Semaste log->Printf ("%p Communication::ReadThread () thread starting...", p); 345254721Semaste 346254721Semaste uint8_t buf[1024]; 347254721Semaste 348254721Semaste Error error; 349254721Semaste ConnectionStatus status = eConnectionStatusSuccess; 350254721Semaste bool done = false; 351254721Semaste while (!done && comm->m_read_thread_enabled) 352254721Semaste { 353254721Semaste size_t bytes_read = comm->ReadFromConnection (buf, sizeof(buf), 5 * TimeValue::MicroSecPerSec, status, &error); 354254721Semaste if (bytes_read > 0) 355254721Semaste comm->AppendBytesToCache (buf, bytes_read, true, status); 356254721Semaste else if ((bytes_read == 0) 357254721Semaste && status == eConnectionStatusEndOfFile) 358254721Semaste { 359254721Semaste if (comm->GetCloseOnEOF ()) 360254721Semaste comm->Disconnect (); 361254721Semaste comm->AppendBytesToCache (buf, bytes_read, true, status); 362254721Semaste } 363254721Semaste 364254721Semaste switch (status) 365254721Semaste { 366254721Semaste case eConnectionStatusSuccess: 367254721Semaste break; 368254721Semaste 369254721Semaste case eConnectionStatusEndOfFile: 370254721Semaste if (comm->GetCloseOnEOF()) 371254721Semaste done = true; 372254721Semaste break; 373254721Semaste case eConnectionStatusNoConnection: // No connection 374254721Semaste case eConnectionStatusLostConnection: // Lost connection while connected to a valid connection 375254721Semaste done = true; 376254721Semaste // Fall through... 377254721Semaste case eConnectionStatusError: // Check GetError() for details 378254721Semaste case eConnectionStatusTimedOut: // Request timed out 379254721Semaste if (log) 380254721Semaste error.LogIfError (log, 381254721Semaste "%p Communication::ReadFromConnection () => status = %s", 382254721Semaste p, 383254721Semaste Communication::ConnectionStatusAsCString (status)); 384254721Semaste break; 385254721Semaste } 386254721Semaste } 387254721Semaste log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_COMMUNICATION); 388254721Semaste if (log) 389254721Semaste log->Printf ("%p Communication::ReadThread () thread exiting...", p); 390254721Semaste 391254721Semaste // Let clients know that this thread is exiting 392254721Semaste comm->BroadcastEvent (eBroadcastBitReadThreadDidExit); 393254721Semaste return NULL; 394254721Semaste} 395254721Semaste 396254721Semastevoid 397254721SemasteCommunication::SetReadThreadBytesReceivedCallback 398254721Semaste( 399254721Semaste ReadThreadBytesReceived callback, 400254721Semaste void *callback_baton 401254721Semaste) 402254721Semaste{ 403254721Semaste m_callback = callback; 404254721Semaste m_callback_baton = callback_baton; 405254721Semaste} 406254721Semaste 407254721Semastevoid 408254721SemasteCommunication::SetConnection (Connection *connection) 409254721Semaste{ 410254721Semaste Disconnect (NULL); 411254721Semaste StopReadThread(NULL); 412254721Semaste m_connection_sp.reset(connection); 413254721Semaste} 414254721Semaste 415254721Semasteconst char * 416254721SemasteCommunication::ConnectionStatusAsCString (lldb::ConnectionStatus status) 417254721Semaste{ 418254721Semaste switch (status) 419254721Semaste { 420254721Semaste case eConnectionStatusSuccess: return "success"; 421254721Semaste case eConnectionStatusError: return "error"; 422254721Semaste case eConnectionStatusTimedOut: return "timed out"; 423254721Semaste case eConnectionStatusNoConnection: return "no connection"; 424254721Semaste case eConnectionStatusLostConnection: return "lost connection"; 425254721Semaste case eConnectionStatusEndOfFile: return "end of file"; 426254721Semaste } 427254721Semaste 428254721Semaste static char unknown_state_string[64]; 429254721Semaste snprintf(unknown_state_string, sizeof (unknown_state_string), "ConnectionStatus = %i", status); 430254721Semaste return unknown_state_string; 431254721Semaste} 432