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