Back to home page

EIC code displayed by LXR

 
 

    


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