124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//===-- Communication.cpp ---------------------------------------*- C++ -*-===// 224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// 324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// The LLVM Compiler Infrastructure 424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// 524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// This file is distributed under the University of Illinois Open Source 624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// License. See LICENSE.TXT for details. 724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// 824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//===----------------------------------------------------------------------===// 924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 1024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// C Includes 1124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// C++ Includes 1224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Other libraries and framework includes 1324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Project includes 1424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/lldb-private-log.h" 1524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Core/Communication.h" 1624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Core/Connection.h" 1724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Core/Log.h" 1824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Core/Timer.h" 1924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Core/Event.h" 20cd548034fa23113e995b8463d14f910ba2f7298cGreg Clayton#include "lldb/Host/Host.h" 21a408326b499c3ffdfed2378738598c4ad0cf745fEli Friedman#include <string.h> 2224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 2324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerusing namespace lldb; 2424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerusing namespace lldb_private; 2524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 265a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim InghamConstString & 275a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim InghamCommunication::GetStaticBroadcasterClass () 285a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham{ 295a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham static ConstString class_name ("lldb.communication"); 305a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham return class_name; 315a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham} 325a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham 3324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//---------------------------------------------------------------------- 3424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Constructor 3524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//---------------------------------------------------------------------- 36eecb0f3b5021e37311f9588f14bcab38a35b8e9aGreg ClaytonCommunication::Communication(const char *name) : 375a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham Broadcaster (NULL, name), 38427f290ff96f3ab9f2cf3a1af7001d2c560424c7Greg Clayton m_connection_sp (), 390a164a1664bce107a4049b838485863320c8292aEli Friedman m_read_thread (LLDB_INVALID_HOST_THREAD), 4024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner m_read_thread_enabled (false), 4124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner m_bytes(), 4224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner m_bytes_mutex (Mutex::eMutexTypeRecursive), 43db2bab463047edba4b01da1fcaf70f15e778095eGreg Clayton m_write_mutex (Mutex::eMutexTypeNormal), 4424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner m_callback (NULL), 459ac497bc11512d221b3962e4f883eeac07db188aCaroline Tice m_callback_baton (NULL), 46eecb0f3b5021e37311f9588f14bcab38a35b8e9aGreg Clayton m_close_on_eof (true) 4724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 4824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 4924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner lldb_private::LogIfAnyCategoriesSet (LIBLLDB_LOG_OBJECT | LIBLLDB_LOG_COMMUNICATION, 5024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner "%p Communication::Communication (name = %s)", 5124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner this, name); 52ff39f746ebaa3710c44ba49bd9b0a6cf05f60a3fGreg Clayton 53ff39f746ebaa3710c44ba49bd9b0a6cf05f60a3fGreg Clayton SetEventName (eBroadcastBitDisconnected, "disconnected"); 54ff39f746ebaa3710c44ba49bd9b0a6cf05f60a3fGreg Clayton SetEventName (eBroadcastBitReadThreadGotBytes, "got bytes"); 55ff39f746ebaa3710c44ba49bd9b0a6cf05f60a3fGreg Clayton SetEventName (eBroadcastBitReadThreadDidExit, "read thread did exit"); 56ff39f746ebaa3710c44ba49bd9b0a6cf05f60a3fGreg Clayton SetEventName (eBroadcastBitReadThreadShouldExit, "read thread should exit"); 57ff39f746ebaa3710c44ba49bd9b0a6cf05f60a3fGreg Clayton SetEventName (eBroadcastBitPacketAvailable, "packet available"); 585a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham 595a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham CheckInWithManager(); 6024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 6124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 6224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//---------------------------------------------------------------------- 6324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Destructor 6424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//---------------------------------------------------------------------- 6524943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerCommunication::~Communication() 6624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 6724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner lldb_private::LogIfAnyCategoriesSet (LIBLLDB_LOG_OBJECT | LIBLLDB_LOG_COMMUNICATION, 6824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner "%p Communication::~Communication (name = %s)", 6924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner this, m_broadcaster_name.AsCString("")); 7024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner Clear(); 7124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 7224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 7324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid 7424943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerCommunication::Clear() 7524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 76b3558281b767607590d56ae74d15c3cfa55819d9Greg Clayton SetReadThreadBytesReceivedCallback (NULL, NULL); 7724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner Disconnect (NULL); 78db9d6f47ab38e25c3efcbfa05780bf9a127fd259Greg Clayton StopReadThread (NULL); 7924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 8024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 8124943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerConnectionStatus 8224943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerCommunication::Connect (const char *url, Error *error_ptr) 8324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 8424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner Clear(); 8524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 8624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner lldb_private::LogIfAnyCategoriesSet (LIBLLDB_LOG_COMMUNICATION, "%p Communication::Connect (url = %s)", this, url); 8724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 88427f290ff96f3ab9f2cf3a1af7001d2c560424c7Greg Clayton lldb::ConnectionSP connection_sp (m_connection_sp); 89427f290ff96f3ab9f2cf3a1af7001d2c560424c7Greg Clayton if (connection_sp.get()) 90427f290ff96f3ab9f2cf3a1af7001d2c560424c7Greg Clayton return connection_sp->Connect (url, error_ptr); 9124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (error_ptr) 9224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner error_ptr->SetErrorString("Invalid connection."); 9324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return eConnectionStatusNoConnection; 9424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 9524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 9624943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerConnectionStatus 9724943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerCommunication::Disconnect (Error *error_ptr) 9824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 9924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner lldb_private::LogIfAnyCategoriesSet (LIBLLDB_LOG_COMMUNICATION, "%p Communication::Disconnect ()", this); 10024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 101427f290ff96f3ab9f2cf3a1af7001d2c560424c7Greg Clayton lldb::ConnectionSP connection_sp (m_connection_sp); 102427f290ff96f3ab9f2cf3a1af7001d2c560424c7Greg Clayton if (connection_sp.get()) 10324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 104427f290ff96f3ab9f2cf3a1af7001d2c560424c7Greg Clayton ConnectionStatus status = connection_sp->Disconnect (error_ptr); 105427f290ff96f3ab9f2cf3a1af7001d2c560424c7Greg Clayton // We currently don't protect connection_sp with any mutex for 106b89274fed17a85aeb81968685af781f24db30dedGreg Clayton // multi-threaded environments. So lets not nuke our connection class 107b89274fed17a85aeb81968685af781f24db30dedGreg Clayton // without putting some multi-threaded protections in. We also probably 108b89274fed17a85aeb81968685af781f24db30dedGreg Clayton // don't want to pay for the overhead it might cause if every time we 109b89274fed17a85aeb81968685af781f24db30dedGreg Clayton // access the connection we have to take a lock. 110b89274fed17a85aeb81968685af781f24db30dedGreg Clayton // 11181a96aa6242f7b559770f5dc62316253cb8cb0d4Greg Clayton // This unique pointer will cleanup after itself when this object goes away, 112b89274fed17a85aeb81968685af781f24db30dedGreg Clayton // so there is no need to currently have it destroy itself immediately 113b89274fed17a85aeb81968685af781f24db30dedGreg Clayton // upon disconnnect. 114427f290ff96f3ab9f2cf3a1af7001d2c560424c7Greg Clayton //connection_sp.reset(); 11524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return status; 11624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 11724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return eConnectionStatusNoConnection; 11824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 11924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 12024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerbool 12124943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerCommunication::IsConnected () const 12224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 123427f290ff96f3ab9f2cf3a1af7001d2c560424c7Greg Clayton lldb::ConnectionSP connection_sp (m_connection_sp); 124427f290ff96f3ab9f2cf3a1af7001d2c560424c7Greg Clayton if (connection_sp.get()) 125427f290ff96f3ab9f2cf3a1af7001d2c560424c7Greg Clayton return connection_sp->IsConnected (); 12624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return false; 12724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 12824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 12924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerbool 13024943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerCommunication::HasConnection () const 13124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 132427f290ff96f3ab9f2cf3a1af7001d2c560424c7Greg Clayton return m_connection_sp.get() != NULL; 13324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 13424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 13524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnersize_t 13624943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerCommunication::Read (void *dst, size_t dst_len, uint32_t timeout_usec, ConnectionStatus &status, Error *error_ptr) 13724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 13824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner lldb_private::LogIfAnyCategoriesSet (LIBLLDB_LOG_COMMUNICATION, 1395f35a4be95aed0e5b2cb36f7d785bcbfc67284aeDaniel Malea "%p Communication::Read (dst = %p, dst_len = %" PRIu64 ", timeout = %u usec) connection = %p", 140427f290ff96f3ab9f2cf3a1af7001d2c560424c7Greg Clayton this, 141427f290ff96f3ab9f2cf3a1af7001d2c560424c7Greg Clayton dst, 142851e30ec6a1b1d2c154bb7d69ed0d05b5fd14705Greg Clayton (uint64_t)dst_len, 143427f290ff96f3ab9f2cf3a1af7001d2c560424c7Greg Clayton timeout_usec, 144427f290ff96f3ab9f2cf3a1af7001d2c560424c7Greg Clayton m_connection_sp.get()); 14524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 146421bc91323c5d7bd9b60c519a0066cbeac5a85a2Stephen Wilson if (m_read_thread_enabled) 14724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 14824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // We have a dedicated read thread that is getting data for us 14924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner size_t cached_bytes = GetCachedBytes (dst, dst_len); 15024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (cached_bytes > 0 || timeout_usec == 0) 15124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 15224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner status = eConnectionStatusSuccess; 15324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return cached_bytes; 15424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 15524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 156427f290ff96f3ab9f2cf3a1af7001d2c560424c7Greg Clayton if (m_connection_sp.get() == NULL) 15724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 15824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (error_ptr) 15924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner error_ptr->SetErrorString("Invalid connection."); 16024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner status = eConnectionStatusNoConnection; 16124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return 0; 16224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 16324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Set the timeout appropriately 16424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner TimeValue timeout_time; 16524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (timeout_usec != UINT32_MAX) 16624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 16724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner timeout_time = TimeValue::Now(); 16824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner timeout_time.OffsetWithMicroSeconds (timeout_usec); 16924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 17024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 17124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner Listener listener ("Communication::Read"); 17224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner listener.StartListeningForEvents (this, eBroadcastBitReadThreadGotBytes | eBroadcastBitReadThreadDidExit); 17324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner EventSP event_sp; 17424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner while (listener.WaitForEvent (timeout_time.IsValid() ? &timeout_time : NULL, event_sp)) 17524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 17624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner const uint32_t event_type = event_sp->GetType(); 17724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (event_type & eBroadcastBitReadThreadGotBytes) 17824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 17924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return GetCachedBytes (dst, dst_len); 18024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 18124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 18224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (event_type & eBroadcastBitReadThreadDidExit) 18324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 18424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner Disconnect (NULL); 18524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner break; 18624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 18724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 18824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return 0; 18924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 19024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 19124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // We aren't using a read thread, just read the data synchronously in this 19224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // thread. 193427f290ff96f3ab9f2cf3a1af7001d2c560424c7Greg Clayton lldb::ConnectionSP connection_sp (m_connection_sp); 194427f290ff96f3ab9f2cf3a1af7001d2c560424c7Greg Clayton if (connection_sp.get()) 19524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 19663afdb07641f04aa7b60d895120b056124d3469bGreg Clayton return connection_sp->Read (dst, dst_len, timeout_usec, status, error_ptr); 19724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 19824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 19924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (error_ptr) 20024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner error_ptr->SetErrorString("Invalid connection."); 20124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner status = eConnectionStatusNoConnection; 20224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return 0; 20324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 20424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 20524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 20624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnersize_t 20724943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerCommunication::Write (const void *src, size_t src_len, ConnectionStatus &status, Error *error_ptr) 20824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 209427f290ff96f3ab9f2cf3a1af7001d2c560424c7Greg Clayton lldb::ConnectionSP connection_sp (m_connection_sp); 210427f290ff96f3ab9f2cf3a1af7001d2c560424c7Greg Clayton 211bf41e19c78f0c84671d21eadec3954ab6db550c1Jason Molenda Mutex::Locker locker(m_write_mutex); 21224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner lldb_private::LogIfAnyCategoriesSet (LIBLLDB_LOG_COMMUNICATION, 2135f35a4be95aed0e5b2cb36f7d785bcbfc67284aeDaniel Malea "%p Communication::Write (src = %p, src_len = %" PRIu64 ") connection = %p", 214427f290ff96f3ab9f2cf3a1af7001d2c560424c7Greg Clayton this, 215427f290ff96f3ab9f2cf3a1af7001d2c560424c7Greg Clayton src, 216851e30ec6a1b1d2c154bb7d69ed0d05b5fd14705Greg Clayton (uint64_t)src_len, 217427f290ff96f3ab9f2cf3a1af7001d2c560424c7Greg Clayton connection_sp.get()); 21824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 219427f290ff96f3ab9f2cf3a1af7001d2c560424c7Greg Clayton if (connection_sp.get()) 220427f290ff96f3ab9f2cf3a1af7001d2c560424c7Greg Clayton return connection_sp->Write (src, src_len, status, error_ptr); 22124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 22224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (error_ptr) 22324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner error_ptr->SetErrorString("Invalid connection."); 22424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner status = eConnectionStatusNoConnection; 22524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return 0; 22624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 22724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 22824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 22924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerbool 23024943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerCommunication::StartReadThread (Error *error_ptr) 23124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 23258e26e0935138225477fd61283215ceff2068899Greg Clayton if (error_ptr) 23358e26e0935138225477fd61283215ceff2068899Greg Clayton error_ptr->Clear(); 23458e26e0935138225477fd61283215ceff2068899Greg Clayton 23509c81efd010d1c9ac8821bad00cdfc9747fcae79Greg Clayton if (IS_VALID_LLDB_HOST_THREAD(m_read_thread)) 23624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return true; 23724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 23824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner lldb_private::LogIfAnyCategoriesSet (LIBLLDB_LOG_COMMUNICATION, 23924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner "%p Communication::StartReadThread ()", this); 24024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 24124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 24224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner char thread_name[1024]; 24324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner snprintf(thread_name, sizeof(thread_name), "<lldb.comm.%s>", m_broadcaster_name.AsCString()); 24424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 24503b1d1c71f4a5e5af365ce053977c08fec24fe48Greg Clayton m_read_thread_enabled = true; 24624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner m_read_thread = Host::ThreadCreate (thread_name, Communication::ReadThread, this, error_ptr); 24709c81efd010d1c9ac8821bad00cdfc9747fcae79Greg Clayton if (!IS_VALID_LLDB_HOST_THREAD(m_read_thread)) 24803b1d1c71f4a5e5af365ce053977c08fec24fe48Greg Clayton m_read_thread_enabled = false; 2490cae3ece74333568dbcef7e2c0f71894d7e0f374Greg Clayton return m_read_thread_enabled; 25024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 25124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 25224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerbool 25324943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerCommunication::StopReadThread (Error *error_ptr) 25424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 25509c81efd010d1c9ac8821bad00cdfc9747fcae79Greg Clayton if (!IS_VALID_LLDB_HOST_THREAD(m_read_thread)) 25624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return true; 25724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 25824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner lldb_private::LogIfAnyCategoriesSet (LIBLLDB_LOG_COMMUNICATION, 25924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner "%p Communication::StopReadThread ()", this); 26024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 26124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner m_read_thread_enabled = false; 26224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 26324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner BroadcastEvent (eBroadcastBitReadThreadShouldExit, NULL); 26424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 265db9d6f47ab38e25c3efcbfa05780bf9a127fd259Greg Clayton //Host::ThreadCancel (m_read_thread, error_ptr); 26624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 267421bc91323c5d7bd9b60c519a0066cbeac5a85a2Stephen Wilson bool status = Host::ThreadJoin (m_read_thread, NULL, error_ptr); 2680cae3ece74333568dbcef7e2c0f71894d7e0f374Greg Clayton m_read_thread = LLDB_INVALID_HOST_THREAD; 269421bc91323c5d7bd9b60c519a0066cbeac5a85a2Stephen Wilson return status; 27024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 27124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 27224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 27324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnersize_t 27424943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerCommunication::GetCachedBytes (void *dst, size_t dst_len) 27524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 27624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner Mutex::Locker locker(m_bytes_mutex); 27724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (m_bytes.size() > 0) 27824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 27924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // If DST is NULL and we have a thread, then return the number 28024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // of bytes that are available so the caller can call again 28124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (dst == NULL) 28224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return m_bytes.size(); 28324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 28424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner const size_t len = std::min<size_t>(dst_len, m_bytes.size()); 28524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 28653d68e749f0715691a95f23e9490d97e484b15daGreg Clayton ::memcpy (dst, m_bytes.c_str(), len); 28724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner m_bytes.erase(m_bytes.begin(), m_bytes.begin() + len); 28824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 28924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return len; 29024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 29124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return 0; 29224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 29324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 29424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid 295c4f55fee15b66ea53da092ca50400ac5d8b0692dCaroline TiceCommunication::AppendBytesToCache (const uint8_t * bytes, size_t len, bool broadcast, ConnectionStatus status) 29624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 29724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner lldb_private::LogIfAnyCategoriesSet (LIBLLDB_LOG_COMMUNICATION, 2985f35a4be95aed0e5b2cb36f7d785bcbfc67284aeDaniel Malea "%p Communication::AppendBytesToCache (src = %p, src_len = %" PRIu64 ", broadcast = %i)", 299851e30ec6a1b1d2c154bb7d69ed0d05b5fd14705Greg Clayton this, bytes, (uint64_t)len, broadcast); 300242db729a2b6f77f873be012ac31b30bd819f951Caroline Tice if ((bytes == NULL || len == 0) 301242db729a2b6f77f873be012ac31b30bd819f951Caroline Tice && (status != lldb::eConnectionStatusEndOfFile)) 30224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return; 30324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (m_callback) 30424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 30524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // If the user registered a callback, then call it and do not broadcast 30624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner m_callback (m_callback_baton, bytes, len); 30724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 308b3558281b767607590d56ae74d15c3cfa55819d9Greg Clayton else if (bytes != NULL && len > 0) 30924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 31024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner Mutex::Locker locker(m_bytes_mutex); 31124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner m_bytes.append ((const char *)bytes, len); 31224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (broadcast) 31324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner BroadcastEventIfUnique (eBroadcastBitReadThreadGotBytes); 31424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 31524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 31624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 31724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnersize_t 31863afdb07641f04aa7b60d895120b056124d3469bGreg ClaytonCommunication::ReadFromConnection (void *dst, 31963afdb07641f04aa7b60d895120b056124d3469bGreg Clayton size_t dst_len, 32063afdb07641f04aa7b60d895120b056124d3469bGreg Clayton uint32_t timeout_usec, 32163afdb07641f04aa7b60d895120b056124d3469bGreg Clayton ConnectionStatus &status, 32263afdb07641f04aa7b60d895120b056124d3469bGreg Clayton Error *error_ptr) 32324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 324427f290ff96f3ab9f2cf3a1af7001d2c560424c7Greg Clayton lldb::ConnectionSP connection_sp (m_connection_sp); 325427f290ff96f3ab9f2cf3a1af7001d2c560424c7Greg Clayton if (connection_sp.get()) 32663afdb07641f04aa7b60d895120b056124d3469bGreg Clayton return connection_sp->Read (dst, dst_len, timeout_usec, status, error_ptr); 32724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return 0; 32824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 32924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 3309ac497bc11512d221b3962e4f883eeac07db188aCaroline Ticebool 33124943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerCommunication::ReadThreadIsRunning () 33224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 333421bc91323c5d7bd9b60c519a0066cbeac5a85a2Stephen Wilson return m_read_thread_enabled; 33424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 33524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 33624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid * 33724943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerCommunication::ReadThread (void *p) 33824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 33924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner Communication *comm = (Communication *)p; 34024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 341952e9dc874944fcdbbb224f3ec4fc2c859376f64Greg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_COMMUNICATION)); 34224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 34324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (log) 34424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner log->Printf ("%p Communication::ReadThread () thread starting...", p); 34524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 34624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner uint8_t buf[1024]; 34724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 34824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner Error error; 34924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner ConnectionStatus status = eConnectionStatusSuccess; 35024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner bool done = false; 35124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner while (!done && comm->m_read_thread_enabled) 35224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 35320fe30ca112121e963dc5ed0547b46bca72f9620Peter Collingbourne size_t bytes_read = comm->ReadFromConnection (buf, sizeof(buf), 5 * TimeValue::MicroSecPerSec, status, &error); 35463afdb07641f04aa7b60d895120b056124d3469bGreg Clayton if (bytes_read > 0) 35563afdb07641f04aa7b60d895120b056124d3469bGreg Clayton comm->AppendBytesToCache (buf, bytes_read, true, status); 35663afdb07641f04aa7b60d895120b056124d3469bGreg Clayton else if ((bytes_read == 0) 35763afdb07641f04aa7b60d895120b056124d3469bGreg Clayton && status == eConnectionStatusEndOfFile) 35824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 35963afdb07641f04aa7b60d895120b056124d3469bGreg Clayton if (comm->GetCloseOnEOF ()) 36063afdb07641f04aa7b60d895120b056124d3469bGreg Clayton comm->Disconnect (); 36163afdb07641f04aa7b60d895120b056124d3469bGreg Clayton comm->AppendBytesToCache (buf, bytes_read, true, status); 36224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 36324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 36424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner switch (status) 36524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 36624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner case eConnectionStatusSuccess: 36724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner break; 36824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 369bd91d9a8c309f9bfd36987ad877ad07f7353b425Greg Clayton case eConnectionStatusEndOfFile: 370242db729a2b6f77f873be012ac31b30bd819f951Caroline Tice if (comm->GetCloseOnEOF()) 371242db729a2b6f77f873be012ac31b30bd819f951Caroline Tice done = true; 372242db729a2b6f77f873be012ac31b30bd819f951Caroline Tice break; 37324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner case eConnectionStatusNoConnection: // No connection 37424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner case eConnectionStatusLostConnection: // Lost connection while connected to a valid connection 37524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner done = true; 37624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Fall through... 37724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner case eConnectionStatusError: // Check GetError() for details 37824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner case eConnectionStatusTimedOut: // Request timed out 379e005f2ce03c489ebde9110678a29cbfe8488d5b4Greg Clayton if (log) 380952e9dc874944fcdbbb224f3ec4fc2c859376f64Greg Clayton error.LogIfError (log, 381952e9dc874944fcdbbb224f3ec4fc2c859376f64Greg Clayton "%p Communication::ReadFromConnection () => status = %s", 382952e9dc874944fcdbbb224f3ec4fc2c859376f64Greg Clayton p, 383952e9dc874944fcdbbb224f3ec4fc2c859376f64Greg Clayton Communication::ConnectionStatusAsCString (status)); 38424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner break; 38524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 38624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 387926060e198137f8a64face70455324a8cd4362a5Caroline Tice log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_COMMUNICATION); 38824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (log) 38924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner log->Printf ("%p Communication::ReadThread () thread exiting...", p); 39024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 39124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Let clients know that this thread is exiting 39224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner comm->BroadcastEvent (eBroadcastBitReadThreadDidExit); 39324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return NULL; 39424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 39524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 39624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid 39724943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerCommunication::SetReadThreadBytesReceivedCallback 39824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner( 39924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner ReadThreadBytesReceived callback, 40024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner void *callback_baton 40124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner) 40224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 40324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner m_callback = callback; 40424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner m_callback_baton = callback_baton; 40524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 40624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 40724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid 40824943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerCommunication::SetConnection (Connection *connection) 40924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 41024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner Disconnect (NULL); 411db9d6f47ab38e25c3efcbfa05780bf9a127fd259Greg Clayton StopReadThread(NULL); 412427f290ff96f3ab9f2cf3a1af7001d2c560424c7Greg Clayton m_connection_sp.reset(connection); 41324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 4147826c8894803dc729f29789ebc038956a94d3e7aCaroline Tice 4157826c8894803dc729f29789ebc038956a94d3e7aCaroline Ticeconst char * 4167826c8894803dc729f29789ebc038956a94d3e7aCaroline TiceCommunication::ConnectionStatusAsCString (lldb::ConnectionStatus status) 4177826c8894803dc729f29789ebc038956a94d3e7aCaroline Tice{ 4187826c8894803dc729f29789ebc038956a94d3e7aCaroline Tice switch (status) 4197826c8894803dc729f29789ebc038956a94d3e7aCaroline Tice { 4207826c8894803dc729f29789ebc038956a94d3e7aCaroline Tice case eConnectionStatusSuccess: return "success"; 4217826c8894803dc729f29789ebc038956a94d3e7aCaroline Tice case eConnectionStatusError: return "error"; 4227826c8894803dc729f29789ebc038956a94d3e7aCaroline Tice case eConnectionStatusTimedOut: return "timed out"; 4237826c8894803dc729f29789ebc038956a94d3e7aCaroline Tice case eConnectionStatusNoConnection: return "no connection"; 4247826c8894803dc729f29789ebc038956a94d3e7aCaroline Tice case eConnectionStatusLostConnection: return "lost connection"; 4254fdf7602bedd8be648f3c549074cf13d90a05f03Greg Clayton case eConnectionStatusEndOfFile: return "end of file"; 4267826c8894803dc729f29789ebc038956a94d3e7aCaroline Tice } 4277826c8894803dc729f29789ebc038956a94d3e7aCaroline Tice 4287826c8894803dc729f29789ebc038956a94d3e7aCaroline Tice static char unknown_state_string[64]; 4297826c8894803dc729f29789ebc038956a94d3e7aCaroline Tice snprintf(unknown_state_string, sizeof (unknown_state_string), "ConnectionStatus = %i", status); 4307826c8894803dc729f29789ebc038956a94d3e7aCaroline Tice return unknown_state_string; 4317826c8894803dc729f29789ebc038956a94d3e7aCaroline Tice} 432