xref: /freebsd/contrib/llvm-project/lldb/include/lldb/Core/ThreadedCommunication.h (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
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