Coverage Report

Created: 2023-09-30 09:22

/Users/buildslave/jenkins/workspace/coverage/llvm-project/lldb/include/lldb/Utility/Broadcaster.h
Line
Count
Source (jump to first uncovered line)
1
//===-- Broadcaster.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_UTILITY_BROADCASTER_H
10
#define LLDB_UTILITY_BROADCASTER_H
11
12
#include "lldb/Utility/ConstString.h"
13
#include "lldb/lldb-defines.h"
14
#include "lldb/lldb-forward.h"
15
16
#include "llvm/ADT/SmallVector.h"
17
18
#include <cstdint>
19
#include <map>
20
#include <memory>
21
#include <mutex>
22
#include <set>
23
#include <string>
24
#include <utility>
25
#include <vector>
26
27
namespace lldb_private {
28
class Broadcaster;
29
class EventData;
30
class Listener;
31
class Stream;
32
} // namespace lldb_private
33
34
namespace lldb_private {
35
36
/// lldb::BroadcastEventSpec
37
///
38
/// This class is used to specify a kind of event to register for.  The
39
/// Debugger maintains a list of BroadcastEventSpec's and when it is made
40
class BroadcastEventSpec {
41
public:
42
  BroadcastEventSpec(const ConstString &broadcaster_class, uint32_t event_bits)
43
2.85k
      : m_broadcaster_class(broadcaster_class), m_event_bits(event_bits) {}
44
45
  ~BroadcastEventSpec() = default;
46
47
12.9k
  ConstString GetBroadcasterClass() const { return m_broadcaster_class; }
48
49
2.69k
  uint32_t GetEventBits() const { return m_event_bits; }
50
51
  /// Tell whether this BroadcastEventSpec is contained in in_spec. That is:
52
  /// (a) the two spec's share the same broadcaster class (b) the event bits of
53
  /// this spec are wholly contained in those of in_spec.
54
0
  bool IsContainedIn(const BroadcastEventSpec &in_spec) const {
55
0
    if (m_broadcaster_class != in_spec.GetBroadcasterClass())
56
0
      return false;
57
0
    uint32_t in_bits = in_spec.GetEventBits();
58
0
    if (in_bits == m_event_bits)
59
0
      return true;
60
61
0
    if ((m_event_bits & in_bits) != 0 && (m_event_bits & ~in_bits) == 0)
62
0
      return true;
63
64
0
    return false;
65
0
  }
66
67
  bool operator<(const BroadcastEventSpec &rhs) const;
68
69
private:
70
  ConstString m_broadcaster_class;
71
  uint32_t m_event_bits;
72
};
73
74
class BroadcasterManager
75
    : public std::enable_shared_from_this<BroadcasterManager> {
76
public:
77
  friend class Listener;
78
79
protected:
80
  BroadcasterManager();
81
82
public:
83
  /// Listeners hold onto weak pointers to their broadcaster managers.  So they
84
  /// must be made into shared pointers, which you do with
85
  /// MakeBroadcasterManager.
86
  static lldb::BroadcasterManagerSP MakeBroadcasterManager();
87
88
5.89k
  ~BroadcasterManager() = default;
89
90
  uint32_t RegisterListenerForEvents(const lldb::ListenerSP &listener_sp,
91
                                     const BroadcastEventSpec &event_spec);
92
93
  bool UnregisterListenerForEvents(const lldb::ListenerSP &listener_sp,
94
                                   const BroadcastEventSpec &event_spec);
95
96
  lldb::ListenerSP
97
  GetListenerForEventSpec(const BroadcastEventSpec &event_spec) const;
98
99
  void SignUpListenersForBroadcaster(Broadcaster &broadcaster);
100
101
  void RemoveListener(const lldb::ListenerSP &listener_sp);
102
103
  void RemoveListener(Listener *listener);
104
105
  void Clear();
106
107
private:
108
  typedef std::pair<BroadcastEventSpec, lldb::ListenerSP> event_listener_key;
109
  typedef std::map<BroadcastEventSpec, lldb::ListenerSP> collection;
110
  typedef std::set<lldb::ListenerSP> listener_collection;
111
  collection m_event_map;
112
  listener_collection m_listeners;
113
114
  mutable std::recursive_mutex m_manager_mutex;
115
};
116
117
/// \class Broadcaster Broadcaster.h "lldb/Utility/Broadcaster.h" An event
118
/// broadcasting class.
119
///
120
/// The Broadcaster class is designed to be subclassed by objects that wish to
121
/// vend events in a multi-threaded environment. Broadcaster objects can each
122
/// vend 32 events. Each event is represented by a bit in a 32 bit value and
123
/// these bits can be set:
124
///     \see Broadcaster::SetEventBits(uint32_t)
125
/// or cleared:
126
///     \see Broadcaster::ResetEventBits(uint32_t)
127
/// When an event gets set the Broadcaster object will notify the Listener
128
/// object that is listening for the event (if there is one).
129
///
130
/// Subclasses should provide broadcast bit definitions for any events they
131
/// vend, typically using an enumeration:
132
///     \code
133
///         class Foo : public Broadcaster
134
///         {
135
///         public:
136
///         // Broadcaster event bits definitions.
137
///         enum
138
///         {
139
///             eBroadcastBitOne   = (1 << 0),
140
///             eBroadcastBitTwo   = (1 << 1),
141
///             eBroadcastBitThree = (1 << 2),
142
///             ...
143
///         };
144
///     \endcode
145
class Broadcaster {
146
  friend class Listener;
147
  friend class Event;
148
149
public:
150
  /// Construct with a broadcaster with a name.
151
  ///
152
  /// \param[in] manager_sp
153
  ///   A shared pointer to the BroadcasterManager that will manage this
154
  ///   broadcaster.
155
  /// \param[in] name
156
  ///   A std::string of the name that this broadcaster will have.
157
  Broadcaster(lldb::BroadcasterManagerSP manager_sp, std::string name);
158
159
  /// Destructor.
160
  ///
161
  /// The destructor is virtual since this class gets subclassed.
162
  virtual ~Broadcaster();
163
164
  void CheckInWithManager();
165
166
  /// Broadcast an event which has no associated data.
167
79.6k
  void BroadcastEvent(lldb::EventSP &event_sp) {
168
79.6k
    m_broadcaster_sp->BroadcastEvent(event_sp);
169
79.6k
  }
170
171
0
  void BroadcastEventIfUnique(lldb::EventSP &event_sp) {
172
0
    m_broadcaster_sp->BroadcastEventIfUnique(event_sp);
173
0
  }
174
175
  void BroadcastEvent(uint32_t event_type,
176
4.90k
                      const lldb::EventDataSP &event_data_sp) {
177
4.90k
    m_broadcaster_sp->BroadcastEvent(event_type, event_data_sp);
178
4.90k
  }
179
180
73.9k
  void BroadcastEvent(uint32_t event_type, EventData *event_data = nullptr) {
181
73.9k
    m_broadcaster_sp->BroadcastEvent(event_type, event_data);
182
73.9k
  }
183
184
  void BroadcastEventIfUnique(uint32_t event_type,
185
3.85k
                              EventData *event_data = nullptr) {
186
3.85k
    m_broadcaster_sp->BroadcastEventIfUnique(event_type, event_data);
187
3.85k
  }
188
189
62.1k
  void Clear() { m_broadcaster_sp->Clear(); }
190
191
  virtual void AddInitialEventsToListener(const lldb::ListenerSP &listener_sp,
192
                                          uint32_t requested_events);
193
194
  /// Listen for any events specified by \a event_mask.
195
  ///
196
  /// Only one listener can listen to each event bit in a given Broadcaster.
197
  /// Once a listener has acquired an event bit, no other broadcaster will
198
  /// have access to it until it is relinquished by the first listener that
199
  /// gets it. The actual event bits that get acquired by \a listener may be
200
  /// different from what is requested in \a event_mask, and to track this the
201
  /// actual event bits that are acquired get returned.
202
  ///
203
  /// \param[in] listener_sp
204
  ///     The Listener object that wants to monitor the events that
205
  ///     get broadcast by this object.
206
  ///
207
  /// \param[in] event_mask
208
  ///     A bit mask that indicates which events the listener is
209
  ///     asking to monitor.
210
  ///
211
  /// \return
212
  ///     The actual event bits that were acquired by \a listener.
213
  uint32_t AddListener(const lldb::ListenerSP &listener_sp,
214
55.6k
                       uint32_t event_mask) {
215
55.6k
    return m_broadcaster_sp->AddListener(listener_sp, event_mask);
216
55.6k
  }
217
218
  /// Get this broadcaster's name.
219
  ///
220
  /// \return
221
  ///     A reference to a constant std::string containing the name of the
222
  ///     broadcaster.
223
2.19k
  const std::string &GetBroadcasterName() { return m_broadcaster_name; }
224
225
  /// Get the event name(s) for one or more event bits.
226
  ///
227
  /// \param[in] event_mask
228
  ///     A bit mask that indicates which events to get names for.
229
  ///
230
  /// \return
231
  ///     The NULL terminated C string name of this Broadcaster.
232
  bool GetEventNames(Stream &s, const uint32_t event_mask,
233
7
                     bool prefix_with_broadcaster_name) const {
234
7
    return m_broadcaster_sp->GetEventNames(s, event_mask,
235
7
                                           prefix_with_broadcaster_name);
236
7
  }
237
238
  /// Set the name for an event bit.
239
  ///
240
  /// \param[in] event_mask
241
  ///     A bit mask that indicates which events the listener is
242
  ///     asking to monitor.
243
147k
  void SetEventName(uint32_t event_mask, const char *name) {
244
147k
    m_broadcaster_sp->SetEventName(event_mask, name);
245
147k
  }
246
247
0
  const char *GetEventName(uint32_t event_mask) const {
248
0
    return m_broadcaster_sp->GetEventName(event_mask);
249
0
  }
250
251
528k
  bool EventTypeHasListeners(uint32_t event_type) {
252
528k
    return m_broadcaster_sp->EventTypeHasListeners(event_type);
253
528k
  }
254
255
  /// Removes a Listener from this broadcasters list and frees the event bits
256
  /// specified by \a event_mask that were previously acquired by \a listener
257
  /// (assuming \a listener was listening to this object) for other listener
258
  /// objects to use.
259
  ///
260
  /// \param[in] listener_sp
261
  ///     A Listener object that previously called AddListener.
262
  ///
263
  /// \param[in] event_mask
264
  ///     The event bits \a listener wishes to relinquish.
265
  ///
266
  /// \return
267
  ///     \b True if the listener was listening to this broadcaster
268
  ///     and was removed, \b false otherwise.
269
  ///
270
  /// \see uint32_t Broadcaster::AddListener (Listener*, uint32_t)
271
  bool RemoveListener(const lldb::ListenerSP &listener_sp,
272
2
                      uint32_t event_mask = UINT32_MAX) {
273
2
    return m_broadcaster_sp->RemoveListener(listener_sp, event_mask);
274
2
  }
275
276
  /// Provides a simple mechanism to temporarily redirect events from
277
  /// broadcaster.  When you call this function passing in a listener and
278
  /// event type mask, all events from the broadcaster matching the mask will
279
  /// now go to the hijacking listener. Only one hijack can occur at a time.
280
  /// If we need more than this we will have to implement a Listener stack.
281
  ///
282
  /// \param[in] listener_sp
283
  ///     A Listener object.  You do not need to call StartListeningForEvents
284
  ///     for this broadcaster (that would fail anyway since the event bits
285
  ///     would most likely be taken by the listener(s) you are usurping.
286
  ///
287
  /// \param[in] event_mask
288
  ///     The event bits \a listener wishes to hijack.
289
  ///
290
  /// \return
291
  ///     \b True if the event mask could be hijacked, \b false otherwise.
292
  ///
293
  /// \see uint32_t Broadcaster::AddListener (Listener*, uint32_t)
294
  bool HijackBroadcaster(const lldb::ListenerSP &listener_sp,
295
9.86k
                         uint32_t event_mask = UINT32_MAX) {
296
9.86k
    return m_broadcaster_sp->HijackBroadcaster(listener_sp, event_mask);
297
9.86k
  }
298
299
57.9k
  bool IsHijackedForEvent(uint32_t event_mask) {
300
57.9k
    return m_broadcaster_sp->IsHijackedForEvent(event_mask);
301
57.9k
  }
302
303
  /// Restore the state of the Broadcaster from a previous hijack attempt.
304
9.85k
  void RestoreBroadcaster() { m_broadcaster_sp->RestoreBroadcaster(); }
305
306
  /// This needs to be filled in if you are going to register the broadcaster
307
  /// with the broadcaster manager and do broadcaster class matching.
308
  /// FIXME: Probably should make a ManagedBroadcaster subclass with all the
309
  /// bits needed to work with the BroadcasterManager, so that it is clearer
310
  /// how to add one.
311
  virtual ConstString &GetBroadcasterClass() const;
312
313
  lldb::BroadcasterManagerSP GetManager();
314
315
2.67k
  void SetPrimaryListener(lldb::ListenerSP listener_sp) {
316
2.67k
    m_broadcaster_sp->SetPrimaryListener(listener_sp);
317
2.67k
  }
318
319
0
  lldb::ListenerSP GetPrimaryListener() {
320
0
    return m_broadcaster_sp->m_primary_listener_sp;
321
0
  }
322
323
protected:
324
  /// BroadcasterImpl contains the actual Broadcaster implementation.  The
325
  /// Broadcaster makes a BroadcasterImpl which lives as long as it does.  The
326
  /// Listeners & the Events hold a weak pointer to the BroadcasterImpl, so
327
  /// that they can survive if a Broadcaster they were listening to is
328
  /// destroyed w/o their being able to unregister from it (which can happen if
329
  /// the Broadcasters & Listeners are being destroyed on separate threads
330
  /// simultaneously. The Broadcaster itself can't be shared out as a weak
331
  /// pointer, because some things that are broadcasters (e.g. the Target and
332
  /// the Process) are shared in their own right.
333
  ///
334
  /// For the most part, the Broadcaster functions dispatch to the
335
  /// BroadcasterImpl, and are documented in the public Broadcaster API above.
336
  class BroadcasterImpl {
337
    friend class Listener;
338
    friend class Broadcaster;
339
340
  public:
341
    BroadcasterImpl(Broadcaster &broadcaster);
342
343
59.4k
    ~BroadcasterImpl() = default;
344
345
    void BroadcastEvent(lldb::EventSP &event_sp);
346
347
    void BroadcastEventIfUnique(lldb::EventSP &event_sp);
348
349
    void BroadcastEvent(uint32_t event_type, EventData *event_data = nullptr);
350
351
    void BroadcastEvent(uint32_t event_type,
352
                        const lldb::EventDataSP &event_data_sp);
353
354
    void BroadcastEventIfUnique(uint32_t event_type,
355
                                EventData *event_data = nullptr);
356
357
    void Clear();
358
359
    uint32_t AddListener(const lldb::ListenerSP &listener_sp,
360
                         uint32_t event_mask);
361
362
0
    const std::string &GetBroadcasterName() const {
363
0
      return m_broadcaster.GetBroadcasterName();
364
0
    }
365
366
    Broadcaster *GetBroadcaster();
367
368
    bool GetEventNames(Stream &s, const uint32_t event_mask,
369
                       bool prefix_with_broadcaster_name) const;
370
371
147k
    void SetEventName(uint32_t event_mask, const char *name) {
372
147k
      m_event_names[event_mask] = name;
373
147k
    }
374
375
0
    const char *GetEventName(uint32_t event_mask) const {
376
0
      const auto pos = m_event_names.find(event_mask);
377
0
      if (pos != m_event_names.end())
378
0
        return pos->second.c_str();
379
0
      return nullptr;
380
0
    }
381
382
    bool EventTypeHasListeners(uint32_t event_type);
383
384
    void SetPrimaryListener(lldb::ListenerSP listener_sp);
385
386
    bool RemoveListener(lldb_private::Listener *listener,
387
                        uint32_t event_mask = UINT32_MAX);
388
389
    bool RemoveListener(const lldb::ListenerSP &listener_sp,
390
                        uint32_t event_mask = UINT32_MAX);
391
392
    bool HijackBroadcaster(const lldb::ListenerSP &listener_sp,
393
                           uint32_t event_mask = UINT32_MAX);
394
395
    bool IsHijackedForEvent(uint32_t event_mask);
396
397
    void RestoreBroadcaster();
398
399
  protected:
400
    void PrivateBroadcastEvent(lldb::EventSP &event_sp, bool unique);
401
402
    const char *GetHijackingListenerName();
403
404
    typedef llvm::SmallVector<std::pair<lldb::ListenerWP, uint32_t>, 4>
405
        collection;
406
    typedef std::map<uint32_t, std::string> event_names_map;
407
408
    llvm::SmallVector<std::pair<lldb::ListenerSP, uint32_t &>, 4>
409
    GetListeners(uint32_t event_mask = UINT32_MAX, bool include_primary = true);
410
411
    bool HasListeners(uint32_t event_mask);
412
413
    /// The broadcaster that this implements.
414
    Broadcaster &m_broadcaster;
415
416
    /// Optionally define event names for readability and logging for each
417
    /// event bit.
418
    event_names_map m_event_names;
419
420
    /// A Broadcaster can have zero, one or many listeners.  A Broadcaster with
421
    /// zero listeners is a no-op, with one Listener is trivial.
422
    /// In most cases of multiple Listeners,the Broadcaster treats all its
423
    /// Listeners as equal, sending each event to all of the Listeners in no
424
    /// guaranteed order.
425
    /// However, some Broadcasters - in particular the Process broadcaster, can
426
    /// designate one Listener to be the "Primary Listener".  In the case of
427
    /// the Process Broadcaster, the Listener passed to the Process constructor
428
    /// will be the Primary Listener.
429
    /// If the broadcaster has a Primary Listener, then the event gets
430
    /// sent first to the Primary Listener, and then when the Primary Listener
431
    /// pulls the event and the the event's DoOnRemoval finishes running,
432
    /// the event is forwarded to all the other Listeners.
433
    /// The other wrinkle is that a Broadcaster may be serving a Hijack
434
    /// Listener.  If the Hijack Listener is present, events are only sent to
435
    /// the Hijack Listener.  We use that, for instance, to absorb all the
436
    /// events generated by running an expression so that they don't show up to
437
    /// the driver or UI as starts and stops.
438
    /// If a Broadcaster has both a Primary and a Hijack Listener, the top-most
439
    /// Hijack Listener is treated as the current Primary Listener.
440
441
    /// A list of Listener / event_mask pairs that are listening to this
442
    /// broadcaster.
443
    collection m_listeners;
444
445
    /// A mutex that protects \a m_listeners.
446
    std::recursive_mutex m_listeners_mutex;
447
448
    /// See the discussion of Broadcasters and Listeners above.
449
    lldb::ListenerSP m_primary_listener_sp;
450
    // The primary listener listens to all bits:
451
    uint32_t m_primary_listener_mask = UINT32_MAX;
452
453
    /// A simple mechanism to intercept events from a broadcaster
454
    std::vector<lldb::ListenerSP> m_hijacking_listeners;
455
456
    /// At some point we may want to have a stack or Listener collections, but
457
    /// for now this is just for private hijacking.
458
    std::vector<uint32_t> m_hijacking_masks;
459
460
  private:
461
    BroadcasterImpl(const BroadcasterImpl &) = delete;
462
    const BroadcasterImpl &operator=(const BroadcasterImpl &) = delete;
463
  };
464
465
  typedef std::shared_ptr<BroadcasterImpl> BroadcasterImplSP;
466
  typedef std::weak_ptr<BroadcasterImpl> BroadcasterImplWP;
467
468
220k
  BroadcasterImplSP GetBroadcasterImpl() { return m_broadcaster_sp; }
469
470
28.9k
  const char *GetHijackingListenerName() {
471
28.9k
    return m_broadcaster_sp->GetHijackingListenerName();
472
28.9k
  }
473
474
private:
475
  BroadcasterImplSP m_broadcaster_sp;
476
  lldb::BroadcasterManagerSP m_manager_sp;
477
478
  /// The name of this broadcaster object.
479
  const std::string m_broadcaster_name;
480
481
  Broadcaster(const Broadcaster &) = delete;
482
  const Broadcaster &operator=(const Broadcaster &) = delete;
483
};
484
485
} // namespace lldb_private
486
487
#endif // LLDB_UTILITY_BROADCASTER_H