1*f6aab3d8Srobert //===-- ThreadedCommunication.h ---------------------------------*- C++ -*-===// 2*f6aab3d8Srobert // 3*f6aab3d8Srobert // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*f6aab3d8Srobert // See https://llvm.org/LICENSE.txt for license information. 5*f6aab3d8Srobert // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*f6aab3d8Srobert // 7*f6aab3d8Srobert //===----------------------------------------------------------------------===// 8*f6aab3d8Srobert 9*f6aab3d8Srobert #ifndef LLDB_CORE_THREADEDCOMMUNICATION_H 10*f6aab3d8Srobert #define LLDB_CORE_THREADEDCOMMUNICATION_H 11*f6aab3d8Srobert 12*f6aab3d8Srobert #include "lldb/Core/Communication.h" 13*f6aab3d8Srobert #include "lldb/Host/HostThread.h" 14*f6aab3d8Srobert #include "lldb/Utility/Broadcaster.h" 15*f6aab3d8Srobert 16*f6aab3d8Srobert #include <atomic> 17*f6aab3d8Srobert #include <mutex> 18*f6aab3d8Srobert #include <string> 19*f6aab3d8Srobert 20*f6aab3d8Srobert #include <cstddef> 21*f6aab3d8Srobert #include <cstdint> 22*f6aab3d8Srobert 23*f6aab3d8Srobert namespace lldb_private { 24*f6aab3d8Srobert 25*f6aab3d8Srobert /// \class ThreadedCommunication ThreadedCommunication.h 26*f6aab3d8Srobert /// "lldb/Core/ThreadedCommunication.h" Variation of Communication that 27*f6aab3d8Srobert /// supports threaded reads. 28*f6aab3d8Srobert /// 29*f6aab3d8Srobert /// ThreadedCommunication enhances the base Communication class with support 30*f6aab3d8Srobert /// for multi-threaded mode. In this mode, a read thread is spawned that 31*f6aab3d8Srobert /// continually reads data and caches any received bytes. To start the read 32*f6aab3d8Srobert /// thread clients call: 33*f6aab3d8Srobert /// 34*f6aab3d8Srobert /// bool ThreadedCommunication::StartReadThread (Status *); 35*f6aab3d8Srobert /// 36*f6aab3d8Srobert /// If true is returned a read thread has been spawned that will continually 37*f6aab3d8Srobert /// execute a call to the pure virtual DoRead function: 38*f6aab3d8Srobert /// 39*f6aab3d8Srobert /// size_t Communication::ReadFromConnection (void *, size_t, uint32_t); 40*f6aab3d8Srobert /// 41*f6aab3d8Srobert /// When bytes are received the data gets cached in \a m_bytes and this class 42*f6aab3d8Srobert /// will broadcast a \b eBroadcastBitReadThreadGotBytes event. Clients that 43*f6aab3d8Srobert /// want packet based communication should override AppendBytesToCache. The 44*f6aab3d8Srobert /// subclasses can choose to call the built in AppendBytesToCache with the \a 45*f6aab3d8Srobert /// broadcast parameter set to false. This will cause the \b 46*f6aab3d8Srobert /// eBroadcastBitReadThreadGotBytes event not get broadcast, and then the 47*f6aab3d8Srobert /// subclass can post a \b eBroadcastBitPacketAvailable event when a full 48*f6aab3d8Srobert /// packet of data has been received. 49*f6aab3d8Srobert /// 50*f6aab3d8Srobert /// If the connection is disconnected a \b eBroadcastBitDisconnected event 51*f6aab3d8Srobert /// gets broadcast. If the read thread exits a \b 52*f6aab3d8Srobert /// eBroadcastBitReadThreadDidExit event will be broadcast. Clients can also 53*f6aab3d8Srobert /// post a \b eBroadcastBitReadThreadShouldExit event to this object which 54*f6aab3d8Srobert /// will cause the read thread to exit. 55*f6aab3d8Srobert /// 56*f6aab3d8Srobert /// ThreadedCommunication inherits from Broadcaster which means it can be used 57*f6aab3d8Srobert /// in conjunction with Listener to wait for multiple broadcaster objects and 58*f6aab3d8Srobert /// multiple events from each of those objects. ThreadedCommunication defines a 59*f6aab3d8Srobert /// set of pre-defined event bits (see enumerations definitions that start with 60*f6aab3d8Srobert /// "eBroadcastBit" below). 61*f6aab3d8Srobert class ThreadedCommunication : public Communication, public Broadcaster { 62*f6aab3d8Srobert using Communication::Communication; 63*f6aab3d8Srobert 64*f6aab3d8Srobert public: FLAGS_ANONYMOUS_ENUM()65*f6aab3d8Srobert FLAGS_ANONYMOUS_ENUM(){ 66*f6aab3d8Srobert eBroadcastBitDisconnected = 67*f6aab3d8Srobert (1u << 0), ///< Sent when the communications connection is lost. 68*f6aab3d8Srobert eBroadcastBitReadThreadGotBytes = 69*f6aab3d8Srobert (1u << 1), ///< Sent by the read thread when bytes become available. 70*f6aab3d8Srobert eBroadcastBitReadThreadDidExit = 71*f6aab3d8Srobert (1u 72*f6aab3d8Srobert << 2), ///< Sent by the read thread when it exits to inform clients. 73*f6aab3d8Srobert eBroadcastBitReadThreadShouldExit = 74*f6aab3d8Srobert (1u << 3), ///< Sent by clients that need to cancel the read thread. 75*f6aab3d8Srobert eBroadcastBitPacketAvailable = 76*f6aab3d8Srobert (1u << 4), ///< Sent when data received makes a complete packet. 77*f6aab3d8Srobert eBroadcastBitNoMorePendingInput = (1u << 5), ///< Sent by the read thread 78*f6aab3d8Srobert /// to indicate all pending 79*f6aab3d8Srobert /// input has been processed. 80*f6aab3d8Srobert }; 81*f6aab3d8Srobert 82*f6aab3d8Srobert typedef void (*ReadThreadBytesReceived)(void *baton, const void *src, 83*f6aab3d8Srobert size_t src_len); 84*f6aab3d8Srobert 85*f6aab3d8Srobert /// Construct the ThreadedCommunication object with the specified name for the 86*f6aab3d8Srobert /// Broadcaster that this object inherits from. 87*f6aab3d8Srobert /// 88*f6aab3d8Srobert /// \param[in] broadcaster_name 89*f6aab3d8Srobert /// The name of the broadcaster object. This name should be as 90*f6aab3d8Srobert /// complete as possible to uniquely identify this object. The 91*f6aab3d8Srobert /// broadcaster name can be updated after the connect function 92*f6aab3d8Srobert /// is called. 93*f6aab3d8Srobert ThreadedCommunication(const char *broadcaster_name); 94*f6aab3d8Srobert 95*f6aab3d8Srobert /// Destructor. 96*f6aab3d8Srobert /// 97*f6aab3d8Srobert /// The destructor is virtual since this class gets subclassed. 98*f6aab3d8Srobert ~ThreadedCommunication() override; 99*f6aab3d8Srobert 100*f6aab3d8Srobert void Clear() override; 101*f6aab3d8Srobert 102*f6aab3d8Srobert /// Disconnect the communications connection if one is currently connected. 103*f6aab3d8Srobert /// 104*f6aab3d8Srobert /// \return 105*f6aab3d8Srobert /// \b True if the disconnect succeeded, \b false otherwise. The 106*f6aab3d8Srobert /// internal error object should be filled in with an 107*f6aab3d8Srobert /// appropriate value based on the result of this function. 108*f6aab3d8Srobert /// 109*f6aab3d8Srobert /// \see Status& Communication::GetError (); 110*f6aab3d8Srobert /// \see bool Connection::Disconnect (); 111*f6aab3d8Srobert lldb::ConnectionStatus Disconnect(Status *error_ptr = nullptr) override; 112*f6aab3d8Srobert 113*f6aab3d8Srobert /// Read bytes from the current connection. 114*f6aab3d8Srobert /// 115*f6aab3d8Srobert /// If no read thread is running, this function call the connection's 116*f6aab3d8Srobert /// Connection::Read(...) function to get any available. 117*f6aab3d8Srobert /// 118*f6aab3d8Srobert /// If a read thread has been started, this function will check for any 119*f6aab3d8Srobert /// cached bytes that have already been read and return any currently 120*f6aab3d8Srobert /// available bytes. If no bytes are cached, it will wait for the bytes to 121*f6aab3d8Srobert /// become available by listening for the \a eBroadcastBitReadThreadGotBytes 122*f6aab3d8Srobert /// event. If this function consumes all of the bytes in the cache, it will 123*f6aab3d8Srobert /// reset the \a eBroadcastBitReadThreadGotBytes event bit. 124*f6aab3d8Srobert /// 125*f6aab3d8Srobert /// \param[in] dst 126*f6aab3d8Srobert /// A destination buffer that must be at least \a dst_len bytes 127*f6aab3d8Srobert /// long. 128*f6aab3d8Srobert /// 129*f6aab3d8Srobert /// \param[in] dst_len 130*f6aab3d8Srobert /// The number of bytes to attempt to read, and also the max 131*f6aab3d8Srobert /// number of bytes that can be placed into \a dst. 132*f6aab3d8Srobert /// 133*f6aab3d8Srobert /// \param[in] timeout 134*f6aab3d8Srobert /// A timeout value or std::nullopt for no timeout. 135*f6aab3d8Srobert /// 136*f6aab3d8Srobert /// \return 137*f6aab3d8Srobert /// The number of bytes actually read. 138*f6aab3d8Srobert /// 139*f6aab3d8Srobert /// \see size_t Connection::Read (void *, size_t); 140*f6aab3d8Srobert size_t Read(void *dst, size_t dst_len, const Timeout<std::micro> &timeout, 141*f6aab3d8Srobert lldb::ConnectionStatus &status, Status *error_ptr) override; 142*f6aab3d8Srobert 143*f6aab3d8Srobert /// Sets the connection that it to be used by this class. 144*f6aab3d8Srobert /// 145*f6aab3d8Srobert /// By making a communication class that uses different connections it 146*f6aab3d8Srobert /// allows a single communication interface to negotiate and change its 147*f6aab3d8Srobert /// connection without any interruption to the client. It also allows the 148*f6aab3d8Srobert /// Communication class to be subclassed for packet based communication. 149*f6aab3d8Srobert /// 150*f6aab3d8Srobert /// \param[in] connection 151*f6aab3d8Srobert /// A connection that this class will own and destroy. 152*f6aab3d8Srobert /// 153*f6aab3d8Srobert /// \see 154*f6aab3d8Srobert /// class Connection 155*f6aab3d8Srobert void SetConnection(std::unique_ptr<Connection> connection) override; 156*f6aab3d8Srobert 157*f6aab3d8Srobert /// Starts a read thread whose sole purpose it to read bytes from the 158*f6aab3d8Srobert /// current connection. This function will call connection's read function: 159*f6aab3d8Srobert /// 160*f6aab3d8Srobert /// size_t Connection::Read (void *, size_t); 161*f6aab3d8Srobert /// 162*f6aab3d8Srobert /// When bytes are read and cached, this function will call: 163*f6aab3d8Srobert /// 164*f6aab3d8Srobert /// Communication::AppendBytesToCache (const uint8_t * bytes, size_t len, 165*f6aab3d8Srobert /// bool 166*f6aab3d8Srobert /// broadcast); 167*f6aab3d8Srobert /// 168*f6aab3d8Srobert /// Subclasses should override this function if they wish to override the 169*f6aab3d8Srobert /// default action of caching the bytes and broadcasting a \b 170*f6aab3d8Srobert /// eBroadcastBitReadThreadGotBytes event. 171*f6aab3d8Srobert /// 172*f6aab3d8Srobert /// \return 173*f6aab3d8Srobert /// \b True if the read thread was successfully started, \b 174*f6aab3d8Srobert /// false otherwise. 175*f6aab3d8Srobert /// 176*f6aab3d8Srobert /// \see size_t Connection::Read (void *, size_t); 177*f6aab3d8Srobert /// \see void Communication::AppendBytesToCache (const uint8_t * bytes, 178*f6aab3d8Srobert /// size_t len, bool broadcast); 179*f6aab3d8Srobert virtual bool StartReadThread(Status *error_ptr = nullptr); 180*f6aab3d8Srobert 181*f6aab3d8Srobert /// Stops the read thread by cancelling it. 182*f6aab3d8Srobert /// 183*f6aab3d8Srobert /// \return 184*f6aab3d8Srobert /// \b True if the read thread was successfully canceled, \b 185*f6aab3d8Srobert /// false otherwise. 186*f6aab3d8Srobert virtual bool StopReadThread(Status *error_ptr = nullptr); 187*f6aab3d8Srobert 188*f6aab3d8Srobert virtual bool JoinReadThread(Status *error_ptr = nullptr); 189*f6aab3d8Srobert /// Checks if there is a currently running read thread. 190*f6aab3d8Srobert /// 191*f6aab3d8Srobert /// \return 192*f6aab3d8Srobert /// \b True if the read thread is running, \b false otherwise. 193*f6aab3d8Srobert bool ReadThreadIsRunning(); 194*f6aab3d8Srobert 195*f6aab3d8Srobert /// The read thread function. This function will call the "DoRead" 196*f6aab3d8Srobert /// function continuously and wait for data to become available. When data 197*f6aab3d8Srobert /// is received it will append the available data to the internal cache and 198*f6aab3d8Srobert /// broadcast a \b eBroadcastBitReadThreadGotBytes event. 199*f6aab3d8Srobert /// 200*f6aab3d8Srobert /// \param[in] comm_ptr 201*f6aab3d8Srobert /// A pointer to an instance of this class. 202*f6aab3d8Srobert /// 203*f6aab3d8Srobert /// \return 204*f6aab3d8Srobert /// \b NULL. 205*f6aab3d8Srobert /// 206*f6aab3d8Srobert /// \see void Communication::ReadThreadGotBytes (const uint8_t *, size_t); 207*f6aab3d8Srobert lldb::thread_result_t ReadThread(); 208*f6aab3d8Srobert 209*f6aab3d8Srobert void SetReadThreadBytesReceivedCallback(ReadThreadBytesReceived callback, 210*f6aab3d8Srobert void *callback_baton); 211*f6aab3d8Srobert 212*f6aab3d8Srobert /// Wait for the read thread to process all outstanding data. 213*f6aab3d8Srobert /// 214*f6aab3d8Srobert /// After this function returns, the read thread has processed all data that 215*f6aab3d8Srobert /// has been waiting in the Connection queue. 216*f6aab3d8Srobert /// 217*f6aab3d8Srobert void SynchronizeWithReadThread(); 218*f6aab3d8Srobert 219*f6aab3d8Srobert static ConstString &GetStaticBroadcasterClass(); 220*f6aab3d8Srobert GetBroadcasterClass()221*f6aab3d8Srobert ConstString &GetBroadcasterClass() const override { 222*f6aab3d8Srobert return GetStaticBroadcasterClass(); 223*f6aab3d8Srobert } 224*f6aab3d8Srobert 225*f6aab3d8Srobert protected: 226*f6aab3d8Srobert HostThread m_read_thread; ///< The read thread handle in case we need to 227*f6aab3d8Srobert /// cancel the thread. 228*f6aab3d8Srobert std::atomic<bool> m_read_thread_enabled; 229*f6aab3d8Srobert std::atomic<bool> m_read_thread_did_exit; 230*f6aab3d8Srobert std::string 231*f6aab3d8Srobert m_bytes; ///< A buffer to cache bytes read in the ReadThread function. 232*f6aab3d8Srobert std::recursive_mutex m_bytes_mutex; ///< A mutex to protect multi-threaded 233*f6aab3d8Srobert /// access to the cached bytes. 234*f6aab3d8Srobert lldb::ConnectionStatus m_pass_status; ///< Connection status passthrough 235*f6aab3d8Srobert /// from read thread. 236*f6aab3d8Srobert Status m_pass_error; ///< Error passthrough from read thread. 237*f6aab3d8Srobert std::mutex m_synchronize_mutex; 238*f6aab3d8Srobert ReadThreadBytesReceived m_callback; 239*f6aab3d8Srobert void *m_callback_baton; 240*f6aab3d8Srobert 241*f6aab3d8Srobert /// Append new bytes that get read from the read thread into the internal 242*f6aab3d8Srobert /// object byte cache. This will cause a \b eBroadcastBitReadThreadGotBytes 243*f6aab3d8Srobert /// event to be broadcast if \a broadcast is true. 244*f6aab3d8Srobert /// 245*f6aab3d8Srobert /// Subclasses can override this function in order to inspect the received 246*f6aab3d8Srobert /// data and check if a packet is available. 247*f6aab3d8Srobert /// 248*f6aab3d8Srobert /// Subclasses can also still call this function from the overridden method 249*f6aab3d8Srobert /// to allow the caching to correctly happen and suppress the broadcasting 250*f6aab3d8Srobert /// of the \a eBroadcastBitReadThreadGotBytes event by setting \a broadcast 251*f6aab3d8Srobert /// to false. 252*f6aab3d8Srobert /// 253*f6aab3d8Srobert /// \param[in] src 254*f6aab3d8Srobert /// A source buffer that must be at least \a src_len bytes 255*f6aab3d8Srobert /// long. 256*f6aab3d8Srobert /// 257*f6aab3d8Srobert /// \param[in] src_len 258*f6aab3d8Srobert /// The number of bytes to append to the cache. 259*f6aab3d8Srobert virtual void AppendBytesToCache(const uint8_t *src, size_t src_len, 260*f6aab3d8Srobert bool broadcast, 261*f6aab3d8Srobert lldb::ConnectionStatus status); 262*f6aab3d8Srobert 263*f6aab3d8Srobert /// Get any available bytes from our data cache. If this call empties the 264*f6aab3d8Srobert /// data cache, the \b eBroadcastBitReadThreadGotBytes event will be reset 265*f6aab3d8Srobert /// to signify no more bytes are available. 266*f6aab3d8Srobert /// 267*f6aab3d8Srobert /// \param[in] dst 268*f6aab3d8Srobert /// A destination buffer that must be at least \a dst_len bytes 269*f6aab3d8Srobert /// long. 270*f6aab3d8Srobert /// 271*f6aab3d8Srobert /// \param[in] dst_len 272*f6aab3d8Srobert /// The number of bytes to attempt to read from the cache, 273*f6aab3d8Srobert /// and also the max number of bytes that can be placed into 274*f6aab3d8Srobert /// \a dst. 275*f6aab3d8Srobert /// 276*f6aab3d8Srobert /// \return 277*f6aab3d8Srobert /// The number of bytes extracted from the data cache. 278*f6aab3d8Srobert size_t GetCachedBytes(void *dst, size_t dst_len); 279*f6aab3d8Srobert 280*f6aab3d8Srobert private: 281*f6aab3d8Srobert ThreadedCommunication(const ThreadedCommunication &) = delete; 282*f6aab3d8Srobert const ThreadedCommunication & 283*f6aab3d8Srobert operator=(const ThreadedCommunication &) = delete; 284*f6aab3d8Srobert }; 285*f6aab3d8Srobert 286*f6aab3d8Srobert } // namespace lldb_private 287*f6aab3d8Srobert 288*f6aab3d8Srobert #endif // LLDB_CORE_THREADEDCOMMUNICATION_H 289