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