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