LLDB  mainline
ThreadedCommunication.h
Go to the documentation of this file.
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 
13 #include "lldb/Host/HostThread.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).
63 
64 public:
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);
208 
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  ///
218 
220 
221  ConstString &GetBroadcasterClass() const override {
222  return GetStaticBroadcasterClass();
223  }
224 
225 protected:
226  HostThread m_read_thread; ///< The read thread handle in case we need to
227  /// cancel the thread.
228  std::atomic<bool> m_read_thread_enabled;
229  std::atomic<bool> m_read_thread_did_exit;
231  m_bytes; ///< A buffer to cache bytes read in the ReadThread function.
232  std::recursive_mutex m_bytes_mutex; ///< A mutex to protect multi-threaded
233  /// access to the cached bytes.
234  lldb::ConnectionStatus m_pass_status; ///< Connection status passthrough
235  /// from read thread.
236  Status m_pass_error; ///< Error passthrough from read thread.
240 
241  /// Append new bytes that get read from the read thread into the internal
242  /// object byte cache. This will cause a \b eBroadcastBitReadThreadGotBytes
243  /// event to be broadcast if \a broadcast is true.
244  ///
245  /// Subclasses can override this function in order to inspect the received
246  /// data and check if a packet is available.
247  ///
248  /// Subclasses can also still call this function from the overridden method
249  /// to allow the caching to correctly happen and suppress the broadcasting
250  /// of the \a eBroadcastBitReadThreadGotBytes event by setting \a broadcast
251  /// to false.
252  ///
253  /// \param[in] src
254  /// A source buffer that must be at least \a src_len bytes
255  /// long.
256  ///
257  /// \param[in] src_len
258  /// The number of bytes to append to the cache.
259  virtual void AppendBytesToCache(const uint8_t *src, size_t src_len,
260  bool broadcast,
261  lldb::ConnectionStatus status);
262 
263  /// Get any available bytes from our data cache. If this call empties the
264  /// data cache, the \b eBroadcastBitReadThreadGotBytes event will be reset
265  /// to signify no more bytes are available.
266  ///
267  /// \param[in] dst
268  /// A destination buffer that must be at least \a dst_len bytes
269  /// long.
270  ///
271  /// \param[in] dst_len
272  /// The number of bytes to attempt to read from the cache,
273  /// and also the max number of bytes that can be placed into
274  /// \a dst.
275  ///
276  /// \return
277  /// The number of bytes extracted from the data cache.
278  size_t GetCachedBytes(void *dst, size_t dst_len);
279 
280 private:
282  const ThreadedCommunication &
283  operator=(const ThreadedCommunication &) = delete;
284 };
285 
286 } // namespace lldb_private
287 
288 #endif // LLDB_CORE_THREADEDCOMMUNICATION_H
lldb_private::ThreadedCommunication::SynchronizeWithReadThread
void SynchronizeWithReadThread()
Wait for the read thread to process all outstanding data.
Definition: ThreadedCommunication.cpp:347
lldb_private::ThreadedCommunication::ReadThread
lldb::thread_result_t ReadThread()
The read thread function.
Definition: ThreadedCommunication.cpp:261
lldb_private::ThreadedCommunication::m_read_thread_did_exit
std::atomic< bool > m_read_thread_did_exit
Definition: ThreadedCommunication.h:229
lldb_private::ThreadedCommunication::ReadThreadIsRunning
bool ReadThreadIsRunning()
Checks if there is a currently running read thread.
Definition: ThreadedCommunication.cpp:257
lldb_private::ThreadedCommunication::SetConnection
void SetConnection(std::unique_ptr< Connection > connection) override
Sets the connection that it to be used by this class.
Definition: ThreadedCommunication.cpp:368
lldb_private::HostThread
Definition: HostThread.h:29
lldb_private::ThreadedCommunication::StopReadThread
virtual bool StopReadThread(Status *error_ptr=nullptr)
Stops the read thread by cancelling it.
Definition: ThreadedCommunication.cpp:192
lldb_private::ThreadedCommunication::m_synchronize_mutex
std::mutex m_synchronize_mutex
Definition: ThreadedCommunication.h:237
lldb_private::ThreadedCommunication::Clear
void Clear() override
Definition: ThreadedCommunication.cpp:64
lldb_private::ThreadedCommunication::m_bytes
std::string m_bytes
A buffer to cache bytes read in the ReadThread function.
Definition: ThreadedCommunication.h:231
lldb_private::ThreadedCommunication::m_pass_error
Status m_pass_error
Error passthrough from read thread.
Definition: ThreadedCommunication.h:236
lldb_private::ThreadedCommunication::JoinReadThread
virtual bool JoinReadThread(Status *error_ptr=nullptr)
Definition: ThreadedCommunication.cpp:209
lldb_private::ThreadedCommunication::FLAGS_ANONYMOUS_ENUM
FLAGS_ANONYMOUS_ENUM()
Definition: ThreadedCommunication.h:65
lldb_private::ThreadedCommunication::ThreadedCommunication
ThreadedCommunication(const char *broadcaster_name)
Construct the ThreadedCommunication object with the specified name for the Broadcaster that this obje...
Definition: ThreadedCommunication.cpp:40
Broadcaster.h
lldb_private::Communication
Definition: Communication.h:39
lldb_private::ThreadedCommunication::m_bytes_mutex
std::recursive_mutex m_bytes_mutex
A mutex to protect multi-threaded access to the cached bytes.
Definition: ThreadedCommunication.h:232
lldb_private::ThreadedCommunication::GetBroadcasterClass
ConstString & GetBroadcasterClass() const override
This needs to be filled in if you are going to register the broadcaster with the broadcaster manager ...
Definition: ThreadedCommunication.h:221
lldb_private::ThreadedCommunication::m_callback
ReadThreadBytesReceived m_callback
Definition: ThreadedCommunication.h:238
HostThread.h
lldb_private::ThreadedCommunication::SetReadThreadBytesReceivedCallback
void SetReadThreadBytesReceivedCallback(ReadThreadBytesReceived callback, void *callback_baton)
Definition: ThreadedCommunication.cpp:341
lldb_private::Communication::Communication
Communication()
Construct the Communication object.
Definition: Communication.cpp:29
lldb_private::ConstString
Definition: ConstString.h:39
lldb_private::ThreadedCommunication::~ThreadedCommunication
~ThreadedCommunication() override
Destructor.
Definition: ThreadedCommunication.cpp:58
lldb::ConnectionStatus
ConnectionStatus
Connection Status Types.
Definition: lldb-enumerations.h:296
lldb_private::ThreadedCommunication::GetStaticBroadcasterClass
static ConstString & GetStaticBroadcasterClass()
Definition: ThreadedCommunication.cpp:35
string
string(SUBSTRING ${p} 10 -1 pStripped) if($
Definition: Plugins/CMakeLists.txt:40
Communication.h
lldb_private::ThreadedCommunication::m_read_thread
HostThread m_read_thread
The read thread handle in case we need to cancel the thread.
Definition: ThreadedCommunication.h:226
lldb_private::ThreadedCommunication::StartReadThread
virtual bool StartReadThread(Status *error_ptr=nullptr)
Starts a read thread whose sole purpose it to read bytes from the current connection.
Definition: ThreadedCommunication.cpp:158
lldb_private::ThreadedCommunication::ReadThreadBytesReceived
void(* ReadThreadBytesReceived)(void *baton, const void *src, size_t src_len)
Definition: ThreadedCommunication.h:82
lldb_private::Status
Definition: Status.h:44
lldb_private::Timeout< std::micro >
lldb_private::ThreadedCommunication::m_pass_status
lldb::ConnectionStatus m_pass_status
Connection status passthrough from read thread.
Definition: ThreadedCommunication.h:234
lldb::thread_result_t
void * thread_result_t
Definition: lldb-types.h:62
lldb_private::ThreadedCommunication::operator=
const ThreadedCommunication & operator=(const ThreadedCommunication &)=delete
lldb_private::ThreadedCommunication::Read
size_t Read(void *dst, size_t dst_len, const Timeout< std::micro > &timeout, lldb::ConnectionStatus &status, Status *error_ptr) override
Read bytes from the current connection.
Definition: ThreadedCommunication.cpp:76
lldb_private::ThreadedCommunication::AppendBytesToCache
virtual void AppendBytesToCache(const uint8_t *src, size_t src_len, bool broadcast, lldb::ConnectionStatus status)
Append new bytes that get read from the read thread into the internal object byte cache.
Definition: ThreadedCommunication.cpp:235
lldb_private::ThreadedCommunication::m_read_thread_enabled
std::atomic< bool > m_read_thread_enabled
Definition: ThreadedCommunication.h:228
lldb_private::ThreadedCommunication::Disconnect
lldb::ConnectionStatus Disconnect(Status *error_ptr=nullptr) override
Disconnect the communications connection if one is currently connected.
Definition: ThreadedCommunication.cpp:70
lldb_private
A class that represents a running process on the host machine.
Definition: SBCommandInterpreterRunOptions.h:16
lldb_private::ThreadedCommunication
Definition: ThreadedCommunication.h:61
lldb_private::Broadcaster
Definition: Broadcaster.h:242
lldb_private::ThreadedCommunication::m_callback_baton
void * m_callback_baton
Definition: ThreadedCommunication.h:239
lldb_private::ThreadedCommunication::GetCachedBytes
size_t GetCachedBytes(void *dst, size_t dst_len)
Get any available bytes from our data cache.
Definition: ThreadedCommunication.cpp:217