|
|
|||
File indexing completed on 2026-05-10 08:42:46
0001 //===-- ThreadedCommunication.h ---------------------------------*- C++ -*-===// 0002 // 0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 0004 // See https://llvm.org/LICENSE.txt for license information. 0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 0006 // 0007 //===----------------------------------------------------------------------===// 0008 0009 #ifndef LLDB_CORE_THREADEDCOMMUNICATION_H 0010 #define LLDB_CORE_THREADEDCOMMUNICATION_H 0011 0012 #include "lldb/Core/Communication.h" 0013 #include "lldb/Host/HostThread.h" 0014 #include "lldb/Utility/Broadcaster.h" 0015 0016 #include <atomic> 0017 #include <mutex> 0018 #include <string> 0019 0020 #include <cstddef> 0021 #include <cstdint> 0022 0023 namespace lldb_private { 0024 0025 /// \class ThreadedCommunication ThreadedCommunication.h 0026 /// "lldb/Core/ThreadedCommunication.h" Variation of Communication that 0027 /// supports threaded reads. 0028 /// 0029 /// ThreadedCommunication enhances the base Communication class with support 0030 /// for multi-threaded mode. In this mode, a read thread is spawned that 0031 /// continually reads data and caches any received bytes. To start the read 0032 /// thread clients call: 0033 /// 0034 /// bool ThreadedCommunication::StartReadThread (Status *); 0035 /// 0036 /// If true is returned a read thread has been spawned that will continually 0037 /// execute a call to the pure virtual DoRead function: 0038 /// 0039 /// size_t Communication::ReadFromConnection (void *, size_t, uint32_t); 0040 /// 0041 /// When bytes are received the data gets cached in \a m_bytes and this class 0042 /// will broadcast a \b eBroadcastBitReadThreadGotBytes event. Clients that 0043 /// want packet based communication should override AppendBytesToCache. The 0044 /// subclasses can choose to call the built in AppendBytesToCache with the \a 0045 /// broadcast parameter set to false. This will cause the \b 0046 /// eBroadcastBitReadThreadGotBytes event not get broadcast, and then the 0047 /// subclass can post a \b eBroadcastBitPacketAvailable event when a full 0048 /// packet of data has been received. 0049 /// 0050 /// If the connection is disconnected a \b eBroadcastBitDisconnected event 0051 /// gets broadcast. If the read thread exits a \b 0052 /// eBroadcastBitReadThreadDidExit event will be broadcast. Clients can also 0053 /// post a \b eBroadcastBitReadThreadShouldExit event to this object which 0054 /// will cause the read thread to exit. 0055 /// 0056 /// ThreadedCommunication inherits from Broadcaster which means it can be used 0057 /// in conjunction with Listener to wait for multiple broadcaster objects and 0058 /// multiple events from each of those objects. ThreadedCommunication defines a 0059 /// set of pre-defined event bits (see enumerations definitions that start with 0060 /// "eBroadcastBit" below). 0061 class ThreadedCommunication : public Communication, public Broadcaster { 0062 using Communication::Communication; 0063 0064 public: 0065 FLAGS_ANONYMOUS_ENUM(){ 0066 eBroadcastBitDisconnected = 0067 (1u << 0), ///< Sent when the communications connection is lost. 0068 eBroadcastBitReadThreadGotBytes = 0069 (1u << 1), ///< Sent by the read thread when bytes become available. 0070 eBroadcastBitReadThreadDidExit = 0071 (1u 0072 << 2), ///< Sent by the read thread when it exits to inform clients. 0073 eBroadcastBitReadThreadShouldExit = 0074 (1u << 3), ///< Sent by clients that need to cancel the read thread. 0075 eBroadcastBitPacketAvailable = 0076 (1u << 4), ///< Sent when data received makes a complete packet. 0077 eBroadcastBitNoMorePendingInput = (1u << 5), ///< Sent by the read thread 0078 /// to indicate all pending 0079 /// input has been processed. 0080 }; 0081 0082 typedef void (*ReadThreadBytesReceived)(void *baton, const void *src, 0083 size_t src_len); 0084 0085 /// Construct the ThreadedCommunication object with the specified name for the 0086 /// Broadcaster that this object inherits from. 0087 /// 0088 /// \param[in] broadcaster_name 0089 /// The name of the broadcaster object. This name should be as 0090 /// complete as possible to uniquely identify this object. The 0091 /// broadcaster name can be updated after the connect function 0092 /// is called. 0093 ThreadedCommunication(const char *broadcaster_name); 0094 0095 /// Destructor. 0096 /// 0097 /// The destructor is virtual since this class gets subclassed. 0098 ~ThreadedCommunication() override; 0099 0100 void Clear() override; 0101 0102 /// Disconnect the communications connection if one is currently connected. 0103 /// 0104 /// \return 0105 /// \b True if the disconnect succeeded, \b false otherwise. The 0106 /// internal error object should be filled in with an 0107 /// appropriate value based on the result of this function. 0108 /// 0109 /// \see Status& Communication::GetError (); 0110 /// \see bool Connection::Disconnect (); 0111 lldb::ConnectionStatus Disconnect(Status *error_ptr = nullptr) override; 0112 0113 /// Read bytes from the current connection. 0114 /// 0115 /// If no read thread is running, this function call the connection's 0116 /// Connection::Read(...) function to get any available. 0117 /// 0118 /// If a read thread has been started, this function will check for any 0119 /// cached bytes that have already been read and return any currently 0120 /// available bytes. If no bytes are cached, it will wait for the bytes to 0121 /// become available by listening for the \a eBroadcastBitReadThreadGotBytes 0122 /// event. If this function consumes all of the bytes in the cache, it will 0123 /// reset the \a eBroadcastBitReadThreadGotBytes event bit. 0124 /// 0125 /// \param[in] dst 0126 /// A destination buffer that must be at least \a dst_len bytes 0127 /// long. 0128 /// 0129 /// \param[in] dst_len 0130 /// The number of bytes to attempt to read, and also the max 0131 /// number of bytes that can be placed into \a dst. 0132 /// 0133 /// \param[in] timeout 0134 /// A timeout value or std::nullopt for no timeout. 0135 /// 0136 /// \return 0137 /// The number of bytes actually read. 0138 /// 0139 /// \see size_t Connection::Read (void *, size_t); 0140 size_t Read(void *dst, size_t dst_len, const Timeout<std::micro> &timeout, 0141 lldb::ConnectionStatus &status, Status *error_ptr) override; 0142 0143 /// Sets the connection that it to be used by this class. 0144 /// 0145 /// By making a communication class that uses different connections it 0146 /// allows a single communication interface to negotiate and change its 0147 /// connection without any interruption to the client. It also allows the 0148 /// Communication class to be subclassed for packet based communication. 0149 /// 0150 /// \param[in] connection 0151 /// A connection that this class will own and destroy. 0152 /// 0153 /// \see 0154 /// class Connection 0155 void SetConnection(std::unique_ptr<Connection> connection) override; 0156 0157 /// Starts a read thread whose sole purpose it to read bytes from the 0158 /// current connection. This function will call connection's read function: 0159 /// 0160 /// size_t Connection::Read (void *, size_t); 0161 /// 0162 /// When bytes are read and cached, this function will call: 0163 /// 0164 /// Communication::AppendBytesToCache (const uint8_t * bytes, size_t len, 0165 /// bool 0166 /// broadcast); 0167 /// 0168 /// Subclasses should override this function if they wish to override the 0169 /// default action of caching the bytes and broadcasting a \b 0170 /// eBroadcastBitReadThreadGotBytes event. 0171 /// 0172 /// \return 0173 /// \b True if the read thread was successfully started, \b 0174 /// false otherwise. 0175 /// 0176 /// \see size_t Connection::Read (void *, size_t); 0177 /// \see void Communication::AppendBytesToCache (const uint8_t * bytes, 0178 /// size_t len, bool broadcast); 0179 virtual bool StartReadThread(Status *error_ptr = nullptr); 0180 0181 /// Stops the read thread by cancelling it. 0182 /// 0183 /// \return 0184 /// \b True if the read thread was successfully canceled, \b 0185 /// false otherwise. 0186 virtual bool StopReadThread(Status *error_ptr = nullptr); 0187 0188 virtual bool JoinReadThread(Status *error_ptr = nullptr); 0189 /// Checks if there is a currently running read thread. 0190 /// 0191 /// \return 0192 /// \b True if the read thread is running, \b false otherwise. 0193 bool ReadThreadIsRunning(); 0194 0195 /// The read thread function. This function will call the "DoRead" 0196 /// function continuously and wait for data to become available. When data 0197 /// is received it will append the available data to the internal cache and 0198 /// broadcast a \b eBroadcastBitReadThreadGotBytes event. 0199 /// 0200 /// \param[in] comm_ptr 0201 /// A pointer to an instance of this class. 0202 /// 0203 /// \return 0204 /// \b NULL. 0205 /// 0206 /// \see void Communication::ReadThreadGotBytes (const uint8_t *, size_t); 0207 lldb::thread_result_t ReadThread(); 0208 0209 void SetReadThreadBytesReceivedCallback(ReadThreadBytesReceived callback, 0210 void *callback_baton); 0211 0212 /// Wait for the read thread to process all outstanding data. 0213 /// 0214 /// After this function returns, the read thread has processed all data that 0215 /// has been waiting in the Connection queue. 0216 /// 0217 void SynchronizeWithReadThread(); 0218 0219 static llvm::StringRef GetStaticBroadcasterClass(); 0220 0221 llvm::StringRef GetBroadcasterClass() const override { 0222 return GetStaticBroadcasterClass(); 0223 } 0224 0225 protected: 0226 /// The read thread handle in case we need to cancel the thread. 0227 /// @{ 0228 HostThread m_read_thread; 0229 std::mutex m_read_thread_mutex; 0230 /// @} 0231 0232 /// Whether the read thread is enabled. This cannot be guarded by the read 0233 /// thread mutex becuase it is used as the control variable to exit the read 0234 /// thread. 0235 std::atomic<bool> m_read_thread_enabled; 0236 0237 /// Whether the read thread is enabled. Technically this could be guarded by 0238 /// the read thread mutex but that needlessly complicates things to 0239 /// check this variables momentary value. 0240 std::atomic<bool> m_read_thread_did_exit; 0241 0242 std::string 0243 m_bytes; ///< A buffer to cache bytes read in the ReadThread function. 0244 std::recursive_mutex m_bytes_mutex; ///< A mutex to protect multi-threaded 0245 /// access to the cached bytes. 0246 lldb::ConnectionStatus m_pass_status; ///< Connection status passthrough 0247 /// from read thread. 0248 Status m_pass_error; ///< Error passthrough from read thread. 0249 std::mutex m_synchronize_mutex; 0250 ReadThreadBytesReceived m_callback; 0251 void *m_callback_baton; 0252 0253 /// Append new bytes that get read from the read thread into the internal 0254 /// object byte cache. This will cause a \b eBroadcastBitReadThreadGotBytes 0255 /// event to be broadcast if \a broadcast is true. 0256 /// 0257 /// Subclasses can override this function in order to inspect the received 0258 /// data and check if a packet is available. 0259 /// 0260 /// Subclasses can also still call this function from the overridden method 0261 /// to allow the caching to correctly happen and suppress the broadcasting 0262 /// of the \a eBroadcastBitReadThreadGotBytes event by setting \a broadcast 0263 /// to false. 0264 /// 0265 /// \param[in] src 0266 /// A source buffer that must be at least \a src_len bytes 0267 /// long. 0268 /// 0269 /// \param[in] src_len 0270 /// The number of bytes to append to the cache. 0271 virtual void AppendBytesToCache(const uint8_t *src, size_t src_len, 0272 bool broadcast, 0273 lldb::ConnectionStatus status); 0274 0275 /// Get any available bytes from our data cache. If this call empties the 0276 /// data cache, the \b eBroadcastBitReadThreadGotBytes event will be reset 0277 /// to signify no more bytes are available. 0278 /// 0279 /// \param[in] dst 0280 /// A destination buffer that must be at least \a dst_len bytes 0281 /// long. 0282 /// 0283 /// \param[in] dst_len 0284 /// The number of bytes to attempt to read from the cache, 0285 /// and also the max number of bytes that can be placed into 0286 /// \a dst. 0287 /// 0288 /// \return 0289 /// The number of bytes extracted from the data cache. 0290 size_t GetCachedBytes(void *dst, size_t dst_len); 0291 0292 private: 0293 ThreadedCommunication(const ThreadedCommunication &) = delete; 0294 const ThreadedCommunication & 0295 operator=(const ThreadedCommunication &) = delete; 0296 }; 0297 0298 } // namespace lldb_private 0299 0300 #endif // LLDB_CORE_THREADEDCOMMUNICATION_H
| [ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
|
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
|