Communication.cpp revision db2bab463047edba4b01da1fcaf70f15e778095e
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" 20a408326b499c3ffdfed2378738598c4ad0cf745fEli Friedman#include <string.h> 2124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 2224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerusing namespace lldb; 2324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerusing namespace lldb_private; 2424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 2524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//---------------------------------------------------------------------- 2624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Constructor 2724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//---------------------------------------------------------------------- 28eecb0f3b5021e37311f9588f14bcab38a35b8e9aGreg ClaytonCommunication::Communication(const char *name) : 2924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner Broadcaster (name), 30427f290ff96f3ab9f2cf3a1af7001d2c560424c7Greg Clayton m_connection_sp (), 310a164a1664bce107a4049b838485863320c8292aEli Friedman m_read_thread (LLDB_INVALID_HOST_THREAD), 3224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner m_read_thread_enabled (false), 3324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner m_bytes(), 3424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner m_bytes_mutex (Mutex::eMutexTypeRecursive), 35db2bab463047edba4b01da1fcaf70f15e778095eGreg Clayton m_write_mutex (Mutex::eMutexTypeNormal), 3624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner m_callback (NULL), 379ac497bc11512d221b3962e4f883eeac07db188aCaroline Tice m_callback_baton (NULL), 38eecb0f3b5021e37311f9588f14bcab38a35b8e9aGreg Clayton m_close_on_eof (true) 3924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 4024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 4124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner lldb_private::LogIfAnyCategoriesSet (LIBLLDB_LOG_OBJECT | LIBLLDB_LOG_COMMUNICATION, 4224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner "%p Communication::Communication (name = %s)", 4324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner this, name); 4424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 4524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 4624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//---------------------------------------------------------------------- 4724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Destructor 4824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//---------------------------------------------------------------------- 4924943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerCommunication::~Communication() 5024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 5124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner lldb_private::LogIfAnyCategoriesSet (LIBLLDB_LOG_OBJECT | LIBLLDB_LOG_COMMUNICATION, 5224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner "%p Communication::~Communication (name = %s)", 5324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner this, m_broadcaster_name.AsCString("")); 5424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner Clear(); 5524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 5624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 5724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid 5824943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerCommunication::Clear() 5924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 6024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner StopReadThread (NULL); 6124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner Disconnect (NULL); 6224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 6324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 6424943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerConnectionStatus 6524943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerCommunication::BytesAvailable (uint32_t timeout_usec, Error *error_ptr) 6624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 6724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner lldb_private::LogIfAnyCategoriesSet (LIBLLDB_LOG_COMMUNICATION, "%p Communication::BytesAvailable (timeout_usec = %u)", this, timeout_usec); 6824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 69427f290ff96f3ab9f2cf3a1af7001d2c560424c7Greg Clayton lldb::ConnectionSP connection_sp (m_connection_sp); 70427f290ff96f3ab9f2cf3a1af7001d2c560424c7Greg Clayton if (connection_sp.get()) 71427f290ff96f3ab9f2cf3a1af7001d2c560424c7Greg Clayton return connection_sp->BytesAvailable (timeout_usec, error_ptr); 7224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (error_ptr) 7324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner error_ptr->SetErrorString("Invalid connection."); 7424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return eConnectionStatusNoConnection; 7524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 7624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 7724943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerConnectionStatus 7824943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerCommunication::Connect (const char *url, Error *error_ptr) 7924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 8024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner Clear(); 8124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 8224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner lldb_private::LogIfAnyCategoriesSet (LIBLLDB_LOG_COMMUNICATION, "%p Communication::Connect (url = %s)", this, url); 8324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 84427f290ff96f3ab9f2cf3a1af7001d2c560424c7Greg Clayton lldb::ConnectionSP connection_sp (m_connection_sp); 85427f290ff96f3ab9f2cf3a1af7001d2c560424c7Greg Clayton if (connection_sp.get()) 86427f290ff96f3ab9f2cf3a1af7001d2c560424c7Greg Clayton return connection_sp->Connect (url, error_ptr); 8724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (error_ptr) 8824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner error_ptr->SetErrorString("Invalid connection."); 8924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return eConnectionStatusNoConnection; 9024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 9124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 9224943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerConnectionStatus 9324943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerCommunication::Disconnect (Error *error_ptr) 9424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 9524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner lldb_private::LogIfAnyCategoriesSet (LIBLLDB_LOG_COMMUNICATION, "%p Communication::Disconnect ()", this); 9624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 97427f290ff96f3ab9f2cf3a1af7001d2c560424c7Greg Clayton lldb::ConnectionSP connection_sp (m_connection_sp); 98427f290ff96f3ab9f2cf3a1af7001d2c560424c7Greg Clayton if (connection_sp.get()) 9924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 100427f290ff96f3ab9f2cf3a1af7001d2c560424c7Greg Clayton ConnectionStatus status = connection_sp->Disconnect (error_ptr); 101427f290ff96f3ab9f2cf3a1af7001d2c560424c7Greg Clayton // We currently don't protect connection_sp with any mutex for 102b89274fed17a85aeb81968685af781f24db30dedGreg Clayton // multi-threaded environments. So lets not nuke our connection class 103b89274fed17a85aeb81968685af781f24db30dedGreg Clayton // without putting some multi-threaded protections in. We also probably 104b89274fed17a85aeb81968685af781f24db30dedGreg Clayton // don't want to pay for the overhead it might cause if every time we 105b89274fed17a85aeb81968685af781f24db30dedGreg Clayton // access the connection we have to take a lock. 106b89274fed17a85aeb81968685af781f24db30dedGreg Clayton // 107b89274fed17a85aeb81968685af781f24db30dedGreg Clayton // This auto_ptr will cleanup after itself when this object goes away, 108b89274fed17a85aeb81968685af781f24db30dedGreg Clayton // so there is no need to currently have it destroy itself immediately 109b89274fed17a85aeb81968685af781f24db30dedGreg Clayton // upon disconnnect. 110427f290ff96f3ab9f2cf3a1af7001d2c560424c7Greg Clayton //connection_sp.reset(); 11124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return status; 11224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 11324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return eConnectionStatusNoConnection; 11424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 11524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 11624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerbool 11724943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerCommunication::IsConnected () const 11824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 119427f290ff96f3ab9f2cf3a1af7001d2c560424c7Greg Clayton lldb::ConnectionSP connection_sp (m_connection_sp); 120427f290ff96f3ab9f2cf3a1af7001d2c560424c7Greg Clayton if (connection_sp.get()) 121427f290ff96f3ab9f2cf3a1af7001d2c560424c7Greg Clayton return connection_sp->IsConnected (); 12224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return false; 12324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 12424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 12524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerbool 12624943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerCommunication::HasConnection () const 12724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 128427f290ff96f3ab9f2cf3a1af7001d2c560424c7Greg Clayton return m_connection_sp.get() != NULL; 12924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 13024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 13124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnersize_t 13224943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerCommunication::Read (void *dst, size_t dst_len, uint32_t timeout_usec, ConnectionStatus &status, Error *error_ptr) 13324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 13424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner lldb_private::LogIfAnyCategoriesSet (LIBLLDB_LOG_COMMUNICATION, 135427f290ff96f3ab9f2cf3a1af7001d2c560424c7Greg Clayton "%p Communication::Read (dst = %p, dst_len = %zu, timeout_usec = %u) connection = %p", 136427f290ff96f3ab9f2cf3a1af7001d2c560424c7Greg Clayton this, 137427f290ff96f3ab9f2cf3a1af7001d2c560424c7Greg Clayton dst, 138427f290ff96f3ab9f2cf3a1af7001d2c560424c7Greg Clayton dst_len, 139427f290ff96f3ab9f2cf3a1af7001d2c560424c7Greg Clayton timeout_usec, 140427f290ff96f3ab9f2cf3a1af7001d2c560424c7Greg Clayton m_connection_sp.get()); 14124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 142421bc91323c5d7bd9b60c519a0066cbeac5a85a2Stephen Wilson if (m_read_thread_enabled) 14324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 14424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // We have a dedicated read thread that is getting data for us 14524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner size_t cached_bytes = GetCachedBytes (dst, dst_len); 14624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (cached_bytes > 0 || timeout_usec == 0) 14724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 14824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner status = eConnectionStatusSuccess; 14924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return cached_bytes; 15024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 15124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 152427f290ff96f3ab9f2cf3a1af7001d2c560424c7Greg Clayton if (m_connection_sp.get() == NULL) 15324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 15424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (error_ptr) 15524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner error_ptr->SetErrorString("Invalid connection."); 15624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner status = eConnectionStatusNoConnection; 15724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return 0; 15824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 15924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Set the timeout appropriately 16024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner TimeValue timeout_time; 16124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (timeout_usec != UINT32_MAX) 16224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 16324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner timeout_time = TimeValue::Now(); 16424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner timeout_time.OffsetWithMicroSeconds (timeout_usec); 16524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 16624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 16724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner Listener listener ("Communication::Read"); 16824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner listener.StartListeningForEvents (this, eBroadcastBitReadThreadGotBytes | eBroadcastBitReadThreadDidExit); 16924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner EventSP event_sp; 17024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner while (listener.WaitForEvent (timeout_time.IsValid() ? &timeout_time : NULL, event_sp)) 17124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 17224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner const uint32_t event_type = event_sp->GetType(); 17324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (event_type & eBroadcastBitReadThreadGotBytes) 17424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 17524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return GetCachedBytes (dst, dst_len); 17624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 17724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 17824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (event_type & eBroadcastBitReadThreadDidExit) 17924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 18024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner Disconnect (NULL); 18124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner break; 18224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 18324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 18424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return 0; 18524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 18624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 18724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // We aren't using a read thread, just read the data synchronously in this 18824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // thread. 189427f290ff96f3ab9f2cf3a1af7001d2c560424c7Greg Clayton lldb::ConnectionSP connection_sp (m_connection_sp); 190427f290ff96f3ab9f2cf3a1af7001d2c560424c7Greg Clayton if (connection_sp.get()) 19124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 192427f290ff96f3ab9f2cf3a1af7001d2c560424c7Greg Clayton status = connection_sp->BytesAvailable (timeout_usec, error_ptr); 19324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (status == eConnectionStatusSuccess) 194427f290ff96f3ab9f2cf3a1af7001d2c560424c7Greg Clayton return connection_sp->Read (dst, dst_len, status, error_ptr); 19524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 19624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 19724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (error_ptr) 19824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner error_ptr->SetErrorString("Invalid connection."); 19924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner status = eConnectionStatusNoConnection; 20024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return 0; 20124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 20224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 20324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 20424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnersize_t 20524943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerCommunication::Write (const void *src, size_t src_len, ConnectionStatus &status, Error *error_ptr) 20624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 207427f290ff96f3ab9f2cf3a1af7001d2c560424c7Greg Clayton lldb::ConnectionSP connection_sp (m_connection_sp); 208427f290ff96f3ab9f2cf3a1af7001d2c560424c7Greg Clayton 209db2bab463047edba4b01da1fcaf70f15e778095eGreg Clayton Mutex::Locker (m_write_mutex); 21024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner lldb_private::LogIfAnyCategoriesSet (LIBLLDB_LOG_COMMUNICATION, 211427f290ff96f3ab9f2cf3a1af7001d2c560424c7Greg Clayton "%p Communication::Write (src = %p, src_len = %zu) connection = %p", 212427f290ff96f3ab9f2cf3a1af7001d2c560424c7Greg Clayton this, 213427f290ff96f3ab9f2cf3a1af7001d2c560424c7Greg Clayton src, 214427f290ff96f3ab9f2cf3a1af7001d2c560424c7Greg Clayton src_len, 215427f290ff96f3ab9f2cf3a1af7001d2c560424c7Greg Clayton connection_sp.get()); 21624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 217427f290ff96f3ab9f2cf3a1af7001d2c560424c7Greg Clayton if (connection_sp.get()) 218427f290ff96f3ab9f2cf3a1af7001d2c560424c7Greg Clayton return connection_sp->Write (src, src_len, status, error_ptr); 21924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 22024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (error_ptr) 22124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner error_ptr->SetErrorString("Invalid connection."); 22224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner status = eConnectionStatusNoConnection; 22324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return 0; 22424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 22524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 22624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 22724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerbool 22824943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerCommunication::StartReadThread (Error *error_ptr) 22924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 23024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (m_read_thread != LLDB_INVALID_HOST_THREAD) 23124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return true; 23224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 23324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner lldb_private::LogIfAnyCategoriesSet (LIBLLDB_LOG_COMMUNICATION, 23424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner "%p Communication::StartReadThread ()", this); 23524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 23624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 23724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner char thread_name[1024]; 23824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner snprintf(thread_name, sizeof(thread_name), "<lldb.comm.%s>", m_broadcaster_name.AsCString()); 23924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 24003b1d1c71f4a5e5af365ce053977c08fec24fe48Greg Clayton m_read_thread_enabled = true; 24124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner m_read_thread = Host::ThreadCreate (thread_name, Communication::ReadThread, this, error_ptr); 24203b1d1c71f4a5e5af365ce053977c08fec24fe48Greg Clayton if (m_read_thread == LLDB_INVALID_HOST_THREAD) 24303b1d1c71f4a5e5af365ce053977c08fec24fe48Greg Clayton m_read_thread_enabled = false; 2440cae3ece74333568dbcef7e2c0f71894d7e0f374Greg Clayton return m_read_thread_enabled; 24524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 24624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 24724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerbool 24824943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerCommunication::StopReadThread (Error *error_ptr) 24924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 2500a164a1664bce107a4049b838485863320c8292aEli Friedman if (m_read_thread == LLDB_INVALID_HOST_THREAD) 25124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return true; 25224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 25324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner lldb_private::LogIfAnyCategoriesSet (LIBLLDB_LOG_COMMUNICATION, 25424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner "%p Communication::StopReadThread ()", this); 25524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 25624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner m_read_thread_enabled = false; 25724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 25824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner BroadcastEvent (eBroadcastBitReadThreadShouldExit, NULL); 25924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 26024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner Host::ThreadCancel (m_read_thread, error_ptr); 26124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 262421bc91323c5d7bd9b60c519a0066cbeac5a85a2Stephen Wilson bool status = Host::ThreadJoin (m_read_thread, NULL, error_ptr); 2630cae3ece74333568dbcef7e2c0f71894d7e0f374Greg Clayton m_read_thread = LLDB_INVALID_HOST_THREAD; 264421bc91323c5d7bd9b60c519a0066cbeac5a85a2Stephen Wilson return status; 26524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 26624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 26724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 26824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnersize_t 26924943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerCommunication::GetCachedBytes (void *dst, size_t dst_len) 27024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 27124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner Mutex::Locker locker(m_bytes_mutex); 27224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (m_bytes.size() > 0) 27324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 27424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // If DST is NULL and we have a thread, then return the number 27524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // of bytes that are available so the caller can call again 27624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (dst == NULL) 27724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return m_bytes.size(); 27824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 27924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner const size_t len = std::min<size_t>(dst_len, m_bytes.size()); 28024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 28153d68e749f0715691a95f23e9490d97e484b15daGreg Clayton ::memcpy (dst, m_bytes.c_str(), len); 28224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner m_bytes.erase(m_bytes.begin(), m_bytes.begin() + len); 28324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 28424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return len; 28524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 28624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return 0; 28724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 28824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 28924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid 290c4f55fee15b66ea53da092ca50400ac5d8b0692dCaroline TiceCommunication::AppendBytesToCache (const uint8_t * bytes, size_t len, bool broadcast, ConnectionStatus status) 29124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 29224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner lldb_private::LogIfAnyCategoriesSet (LIBLLDB_LOG_COMMUNICATION, 29324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner "%p Communication::AppendBytesToCache (src = %p, src_len = %zu, broadcast = %i)", 29424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner this, bytes, len, broadcast); 295bd91d9a8c309f9bfd36987ad877ad07f7353b425Greg Clayton if (bytes == NULL || len == 0) 29624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return; 29724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (m_callback) 29824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 29924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // If the user registered a callback, then call it and do not broadcast 30024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner m_callback (m_callback_baton, bytes, len); 30124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 30224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner else 30324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 30424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner Mutex::Locker locker(m_bytes_mutex); 30524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner m_bytes.append ((const char *)bytes, len); 30624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (broadcast) 30724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner BroadcastEventIfUnique (eBroadcastBitReadThreadGotBytes); 30824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 30924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 31024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 31124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnersize_t 31224943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerCommunication::ReadFromConnection (void *dst, size_t dst_len, ConnectionStatus &status, Error *error_ptr) 31324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 314427f290ff96f3ab9f2cf3a1af7001d2c560424c7Greg Clayton lldb::ConnectionSP connection_sp (m_connection_sp); 315427f290ff96f3ab9f2cf3a1af7001d2c560424c7Greg Clayton if (connection_sp.get()) 316427f290ff96f3ab9f2cf3a1af7001d2c560424c7Greg Clayton return connection_sp->Read (dst, dst_len, status, error_ptr); 31724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return 0; 31824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 31924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 3209ac497bc11512d221b3962e4f883eeac07db188aCaroline Ticebool 32124943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerCommunication::ReadThreadIsRunning () 32224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 323421bc91323c5d7bd9b60c519a0066cbeac5a85a2Stephen Wilson return m_read_thread_enabled; 32424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 32524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 32624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid * 32724943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerCommunication::ReadThread (void *p) 32824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 32924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner Communication *comm = (Communication *)p; 33024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 331e005f2ce03c489ebde9110678a29cbfe8488d5b4Greg Clayton LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_COMMUNICATION)); 33224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 33324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (log) 33424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner log->Printf ("%p Communication::ReadThread () thread starting...", p); 33524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 33624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner uint8_t buf[1024]; 33724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 33824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner Error error; 33924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner ConnectionStatus status = eConnectionStatusSuccess; 34024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner bool done = false; 34124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner while (!done && comm->m_read_thread_enabled) 34224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 34324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner status = comm->BytesAvailable (UINT32_MAX, &error); 34424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 34524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (status == eConnectionStatusSuccess) 34624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 34724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner size_t bytes_read = comm->ReadFromConnection (buf, sizeof(buf), status, &error); 34824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (bytes_read > 0) 349c4f55fee15b66ea53da092ca50400ac5d8b0692dCaroline Tice comm->AppendBytesToCache (buf, bytes_read, true, status); 35024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 35124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 35224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner switch (status) 35324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 35424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner case eConnectionStatusSuccess: 35524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner break; 35624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 357bd91d9a8c309f9bfd36987ad877ad07f7353b425Greg Clayton case eConnectionStatusEndOfFile: 35824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner case eConnectionStatusNoConnection: // No connection 35924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner case eConnectionStatusLostConnection: // Lost connection while connected to a valid connection 36024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner done = true; 36124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Fall through... 36224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner default: 36324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner case eConnectionStatusError: // Check GetError() for details 36424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner case eConnectionStatusTimedOut: // Request timed out 365e005f2ce03c489ebde9110678a29cbfe8488d5b4Greg Clayton if (log) 366e005f2ce03c489ebde9110678a29cbfe8488d5b4Greg Clayton error.LogIfError(log.get(), "%p Communication::BytesAvailable () => status = %i", p, status); 36724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner break; 36824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 36924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 370926060e198137f8a64face70455324a8cd4362a5Caroline Tice log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_COMMUNICATION); 37124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (log) 37224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner log->Printf ("%p Communication::ReadThread () thread exiting...", p); 37324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 37424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Let clients know that this thread is exiting 37524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner comm->BroadcastEvent (eBroadcastBitReadThreadDidExit); 376421bc91323c5d7bd9b60c519a0066cbeac5a85a2Stephen Wilson comm->m_read_thread_enabled = false; 377b89274fed17a85aeb81968685af781f24db30dedGreg Clayton comm->Disconnect(); 37824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return NULL; 37924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 38024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 38124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid 38224943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerCommunication::SetReadThreadBytesReceivedCallback 38324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner( 38424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner ReadThreadBytesReceived callback, 38524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner void *callback_baton 38624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner) 38724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 38824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner m_callback = callback; 38924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner m_callback_baton = callback_baton; 39024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 39124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 39224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid 39324943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerCommunication::SetConnection (Connection *connection) 39424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 39524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner StopReadThread(NULL); 39624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner Disconnect (NULL); 397427f290ff96f3ab9f2cf3a1af7001d2c560424c7Greg Clayton m_connection_sp.reset(connection); 39824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 3997826c8894803dc729f29789ebc038956a94d3e7aCaroline Tice 4007826c8894803dc729f29789ebc038956a94d3e7aCaroline Ticeconst char * 4017826c8894803dc729f29789ebc038956a94d3e7aCaroline TiceCommunication::ConnectionStatusAsCString (lldb::ConnectionStatus status) 4027826c8894803dc729f29789ebc038956a94d3e7aCaroline Tice{ 4037826c8894803dc729f29789ebc038956a94d3e7aCaroline Tice switch (status) 4047826c8894803dc729f29789ebc038956a94d3e7aCaroline Tice { 4057826c8894803dc729f29789ebc038956a94d3e7aCaroline Tice case eConnectionStatusSuccess: return "success"; 4067826c8894803dc729f29789ebc038956a94d3e7aCaroline Tice case eConnectionStatusError: return "error"; 4077826c8894803dc729f29789ebc038956a94d3e7aCaroline Tice case eConnectionStatusTimedOut: return "timed out"; 4087826c8894803dc729f29789ebc038956a94d3e7aCaroline Tice case eConnectionStatusNoConnection: return "no connection"; 4097826c8894803dc729f29789ebc038956a94d3e7aCaroline Tice case eConnectionStatusLostConnection: return "lost connection"; 4107826c8894803dc729f29789ebc038956a94d3e7aCaroline Tice } 4117826c8894803dc729f29789ebc038956a94d3e7aCaroline Tice 4127826c8894803dc729f29789ebc038956a94d3e7aCaroline Tice static char unknown_state_string[64]; 4137826c8894803dc729f29789ebc038956a94d3e7aCaroline Tice snprintf(unknown_state_string, sizeof (unknown_state_string), "ConnectionStatus = %i", status); 4147826c8894803dc729f29789ebc038956a94d3e7aCaroline Tice return unknown_state_string; 4157826c8894803dc729f29789ebc038956a94d3e7aCaroline Tice} 416