• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //===-- Listener.cpp --------------------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "lldb/Core/Listener.h"
11 
12 // C Includes
13 // C++ Includes
14 // Other libraries and framework includes
15 // Project includes
16 #include "lldb/Core/Broadcaster.h"
17 #include "lldb/Core/Log.h"
18 #include "lldb/Core/StreamString.h"
19 #include "lldb/Core/Event.h"
20 #include "lldb/Host/TimeValue.h"
21 #include "lldb/lldb-private-log.h"
22 #include <algorithm>
23 
24 using namespace lldb;
25 using namespace lldb_private;
26 
Listener(const char * name)27 Listener::Listener(const char *name) :
28     m_name (name),
29     m_broadcasters(),
30     m_broadcasters_mutex (Mutex::eMutexTypeRecursive),
31     m_events (),
32     m_events_mutex (Mutex::eMutexTypeRecursive),
33     m_cond_wait()
34 {
35     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
36     if (log)
37         log->Printf ("%p Listener::Listener('%s')", this, m_name.c_str());
38 }
39 
~Listener()40 Listener::~Listener()
41 {
42     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
43     Mutex::Locker locker (m_broadcasters_mutex);
44 
45     size_t num_managers = m_broadcaster_managers.size();
46 
47     for (size_t i = 0; i < num_managers; i++)
48         m_broadcaster_managers[i]->RemoveListener(*this);
49 
50     if (log)
51         log->Printf ("%p Listener::~Listener('%s')", this, m_name.c_str());
52     Clear();
53 }
54 
55 void
Clear()56 Listener::Clear()
57 {
58     Mutex::Locker locker(m_broadcasters_mutex);
59     broadcaster_collection::iterator pos, end = m_broadcasters.end();
60     for (pos = m_broadcasters.begin(); pos != end; ++pos)
61         pos->first->RemoveListener (this, pos->second.event_mask);
62     m_broadcasters.clear();
63     m_cond_wait.SetValue (false, eBroadcastNever);
64     m_broadcasters.clear();
65     Mutex::Locker event_locker(m_events_mutex);
66     m_events.clear();
67 }
68 
69 uint32_t
StartListeningForEvents(Broadcaster * broadcaster,uint32_t event_mask)70 Listener::StartListeningForEvents (Broadcaster* broadcaster, uint32_t event_mask)
71 {
72     if (broadcaster)
73     {
74         // Scope for "locker"
75         // Tell the broadcaster to add this object as a listener
76         {
77             Mutex::Locker locker(m_broadcasters_mutex);
78             m_broadcasters.insert(std::make_pair(broadcaster, BroadcasterInfo(event_mask)));
79         }
80 
81         uint32_t acquired_mask = broadcaster->AddListener (this, event_mask);
82 
83         if (event_mask != acquired_mask)
84         {
85 
86         }
87         Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EVENTS));
88         if (log)
89             log->Printf ("%p Listener::StartListeningForEvents (broadcaster = %p, mask = 0x%8.8x) acquired_mask = 0x%8.8x for %s",
90                          this,
91                          broadcaster,
92                          event_mask,
93                          acquired_mask,
94                          m_name.c_str());
95 
96         return acquired_mask;
97 
98     }
99     return 0;
100 }
101 
102 uint32_t
StartListeningForEvents(Broadcaster * broadcaster,uint32_t event_mask,HandleBroadcastCallback callback,void * callback_user_data)103 Listener::StartListeningForEvents (Broadcaster* broadcaster, uint32_t event_mask, HandleBroadcastCallback callback, void *callback_user_data)
104 {
105     if (broadcaster)
106     {
107         // Scope for "locker"
108         // Tell the broadcaster to add this object as a listener
109         {
110             Mutex::Locker locker(m_broadcasters_mutex);
111             m_broadcasters.insert(std::make_pair(broadcaster, BroadcasterInfo(event_mask, callback, callback_user_data)));
112         }
113 
114         uint32_t acquired_mask = broadcaster->AddListener (this, event_mask);
115 
116         Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EVENTS));
117         if (log)
118             log->Printf ("%p Listener::StartListeningForEvents (broadcaster = %p, mask = 0x%8.8x, callback = %p, user_data = %p) acquired_mask = 0x%8.8x for %s",
119                         this, broadcaster, event_mask, callback, callback_user_data, acquired_mask, m_name.c_str());
120 
121         return acquired_mask;
122     }
123     return 0;
124 }
125 
126 bool
StopListeningForEvents(Broadcaster * broadcaster,uint32_t event_mask)127 Listener::StopListeningForEvents (Broadcaster* broadcaster, uint32_t event_mask)
128 {
129     if (broadcaster)
130     {
131         // Scope for "locker"
132         {
133             Mutex::Locker locker(m_broadcasters_mutex);
134             m_broadcasters.erase (broadcaster);
135         }
136         // Remove the broadcaster from our set of broadcasters
137         return broadcaster->RemoveListener (this, event_mask);
138     }
139 
140     return false;
141 }
142 
143 // Called when a Broadcaster is in its destuctor. We need to remove all
144 // knowledge of this broadcaster and any events that it may have queued up
145 void
BroadcasterWillDestruct(Broadcaster * broadcaster)146 Listener::BroadcasterWillDestruct (Broadcaster *broadcaster)
147 {
148     // Scope for "broadcasters_locker"
149     {
150         Mutex::Locker broadcasters_locker(m_broadcasters_mutex);
151         m_broadcasters.erase (broadcaster);
152     }
153 
154     // Scope for "event_locker"
155     {
156         Mutex::Locker event_locker(m_events_mutex);
157         // Remove all events for this broadcaster object.
158         event_collection::iterator pos = m_events.begin();
159         while (pos != m_events.end())
160         {
161             if ((*pos)->GetBroadcaster() == broadcaster)
162                 pos = m_events.erase(pos);
163             else
164                 ++pos;
165         }
166 
167         if (m_events.empty())
168             m_cond_wait.SetValue (false, eBroadcastNever);
169 
170     }
171 }
172 
173 void
BroadcasterManagerWillDestruct(BroadcasterManager * manager)174 Listener::BroadcasterManagerWillDestruct (BroadcasterManager *manager)
175 {
176     // Just need to remove this broadcast manager from the list of managers:
177     broadcaster_manager_collection::iterator iter, end_iter = m_broadcaster_managers.end();
178     iter = find(m_broadcaster_managers.begin(), end_iter, manager);
179     if (iter != end_iter)
180         m_broadcaster_managers.erase (iter);
181 }
182 
183 void
AddEvent(EventSP & event_sp)184 Listener::AddEvent (EventSP &event_sp)
185 {
186     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EVENTS));
187     if (log)
188         log->Printf ("%p Listener('%s')::AddEvent (event_sp = {%p})", this, m_name.c_str(), event_sp.get());
189 
190     // Scope for "locker"
191     {
192         Mutex::Locker locker(m_events_mutex);
193         m_events.push_back (event_sp);
194     }
195     m_cond_wait.SetValue (true, eBroadcastAlways);
196 }
197 
198 class EventBroadcasterMatches
199 {
200 public:
EventBroadcasterMatches(Broadcaster * broadcaster)201     EventBroadcasterMatches (Broadcaster *broadcaster) :
202         m_broadcaster (broadcaster)    {
203     }
204 
operator ()(const EventSP & event_sp) const205     bool operator() (const EventSP &event_sp) const
206     {
207         if (event_sp->BroadcasterIs(m_broadcaster))
208             return true;
209         else
210             return false;
211     }
212 
213 private:
214     Broadcaster *m_broadcaster;
215 
216 };
217 
218 class EventMatcher
219 {
220 public:
EventMatcher(Broadcaster * broadcaster,const ConstString * broadcaster_names,uint32_t num_broadcaster_names,uint32_t event_type_mask)221     EventMatcher (Broadcaster *broadcaster, const ConstString *broadcaster_names, uint32_t num_broadcaster_names, uint32_t event_type_mask) :
222         m_broadcaster (broadcaster),
223         m_broadcaster_names (broadcaster_names),
224         m_num_broadcaster_names (num_broadcaster_names),
225         m_event_type_mask (event_type_mask)
226     {
227     }
228 
operator ()(const EventSP & event_sp) const229     bool operator() (const EventSP &event_sp) const
230     {
231         if (m_broadcaster && !event_sp->BroadcasterIs(m_broadcaster))
232             return false;
233 
234         if (m_broadcaster_names)
235         {
236             bool found_source = false;
237             const ConstString &event_broadcaster_name = event_sp->GetBroadcaster()->GetBroadcasterName();
238             for (uint32_t i=0; i<m_num_broadcaster_names; ++i)
239             {
240                 if (m_broadcaster_names[i] == event_broadcaster_name)
241                 {
242                     found_source = true;
243                     break;
244                 }
245             }
246             if (!found_source)
247                 return false;
248         }
249 
250         if (m_event_type_mask == 0 || m_event_type_mask & event_sp->GetType())
251             return true;
252         return false;
253     }
254 
255 private:
256     Broadcaster *m_broadcaster;
257     const ConstString *m_broadcaster_names;
258     const uint32_t m_num_broadcaster_names;
259     const uint32_t m_event_type_mask;
260 };
261 
262 
263 bool
FindNextEventInternal(Broadcaster * broadcaster,const ConstString * broadcaster_names,uint32_t num_broadcaster_names,uint32_t event_type_mask,EventSP & event_sp,bool remove)264 Listener::FindNextEventInternal
265 (
266     Broadcaster *broadcaster,   // NULL for any broadcaster
267     const ConstString *broadcaster_names, // NULL for any event
268     uint32_t num_broadcaster_names,
269     uint32_t event_type_mask,
270     EventSP &event_sp,
271     bool remove)
272 {
273     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EVENTS));
274 
275     Mutex::Locker lock(m_events_mutex);
276 
277     if (m_events.empty())
278         return false;
279 
280 
281     Listener::event_collection::iterator pos = m_events.end();
282 
283     if (broadcaster == NULL && broadcaster_names == NULL && event_type_mask == 0)
284     {
285         pos = m_events.begin();
286     }
287     else
288     {
289         pos = std::find_if (m_events.begin(), m_events.end(), EventMatcher (broadcaster, broadcaster_names, num_broadcaster_names, event_type_mask));
290     }
291 
292     if (pos != m_events.end())
293     {
294         event_sp = *pos;
295 
296         if (log)
297             log->Printf ("%p '%s' Listener::FindNextEventInternal(broadcaster=%p, broadcaster_names=%p[%u], event_type_mask=0x%8.8x, remove=%i) event %p",
298                          this,
299                          GetName(),
300                          broadcaster,
301                          broadcaster_names,
302                          num_broadcaster_names,
303                          event_type_mask,
304                          remove,
305                          event_sp.get());
306 
307         if (remove)
308         {
309             m_events.erase(pos);
310 
311             if (m_events.empty())
312                 m_cond_wait.SetValue (false, eBroadcastNever);
313         }
314 
315         // Unlock the event queue here.  We've removed this event and are about to return
316         // it so it should be okay to get the next event off the queue here - and it might
317         // be useful to do that in the "DoOnRemoval".
318         lock.Unlock();
319 
320         // Don't call DoOnRemoval if you aren't removing the event...
321         if (remove)
322             event_sp->DoOnRemoval();
323 
324         return true;
325     }
326 
327     event_sp.reset();
328     return false;
329 }
330 
331 Event *
PeekAtNextEvent()332 Listener::PeekAtNextEvent ()
333 {
334     EventSP event_sp;
335     if (FindNextEventInternal (NULL, NULL, 0, 0, event_sp, false))
336         return event_sp.get();
337     return NULL;
338 }
339 
340 Event *
PeekAtNextEventForBroadcaster(Broadcaster * broadcaster)341 Listener::PeekAtNextEventForBroadcaster (Broadcaster *broadcaster)
342 {
343     EventSP event_sp;
344     if (FindNextEventInternal (broadcaster, NULL, 0, 0, event_sp, false))
345         return event_sp.get();
346     return NULL;
347 }
348 
349 Event *
PeekAtNextEventForBroadcasterWithType(Broadcaster * broadcaster,uint32_t event_type_mask)350 Listener::PeekAtNextEventForBroadcasterWithType (Broadcaster *broadcaster, uint32_t event_type_mask)
351 {
352     EventSP event_sp;
353     if (FindNextEventInternal (broadcaster, NULL, 0, event_type_mask, event_sp, false))
354         return event_sp.get();
355     return NULL;
356 }
357 
358 
359 bool
GetNextEventInternal(Broadcaster * broadcaster,const ConstString * broadcaster_names,uint32_t num_broadcaster_names,uint32_t event_type_mask,EventSP & event_sp)360 Listener::GetNextEventInternal
361 (
362     Broadcaster *broadcaster,   // NULL for any broadcaster
363     const ConstString *broadcaster_names, // NULL for any event
364     uint32_t num_broadcaster_names,
365     uint32_t event_type_mask,
366     EventSP &event_sp
367 )
368 {
369     return FindNextEventInternal (broadcaster, broadcaster_names, num_broadcaster_names, event_type_mask, event_sp, true);
370 }
371 
372 bool
GetNextEvent(EventSP & event_sp)373 Listener::GetNextEvent (EventSP &event_sp)
374 {
375     return GetNextEventInternal (NULL, NULL, 0, 0, event_sp);
376 }
377 
378 
379 bool
GetNextEventForBroadcaster(Broadcaster * broadcaster,EventSP & event_sp)380 Listener::GetNextEventForBroadcaster (Broadcaster *broadcaster, EventSP &event_sp)
381 {
382     return GetNextEventInternal (broadcaster, NULL, 0, 0, event_sp);
383 }
384 
385 bool
GetNextEventForBroadcasterWithType(Broadcaster * broadcaster,uint32_t event_type_mask,EventSP & event_sp)386 Listener::GetNextEventForBroadcasterWithType (Broadcaster *broadcaster, uint32_t event_type_mask, EventSP &event_sp)
387 {
388     return GetNextEventInternal (broadcaster, NULL, 0, event_type_mask, event_sp);
389 }
390 
391 
392 bool
WaitForEventsInternal(const TimeValue * timeout,Broadcaster * broadcaster,const ConstString * broadcaster_names,uint32_t num_broadcaster_names,uint32_t event_type_mask,EventSP & event_sp)393 Listener::WaitForEventsInternal
394 (
395     const TimeValue *timeout,
396     Broadcaster *broadcaster,   // NULL for any broadcaster
397     const ConstString *broadcaster_names, // NULL for any event
398     uint32_t num_broadcaster_names,
399     uint32_t event_type_mask,
400     EventSP &event_sp
401 )
402 {
403     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EVENTS));
404     bool timed_out = false;
405 
406     if (log)
407     {
408         log->Printf ("%p Listener::WaitForEventsInternal (timeout = { %p }) for %s",
409                     this, timeout, m_name.c_str());
410     }
411 
412     while (1)
413     {
414         // Note, we don't want to lock the m_events_mutex in the call to GetNextEventInternal, since the DoOnRemoval
415         // code might require that new events be serviced.  For instance, the Breakpoint Command's
416         if (GetNextEventInternal (broadcaster, broadcaster_names, num_broadcaster_names, event_type_mask, event_sp))
417                 return true;
418 
419         {
420             // Reset condition value to false, so we can wait for new events to be
421             // added that might meet our current filter
422             // But first poll for any new event that might satisfy our condition, and if so consume it,
423             // otherwise wait.
424 
425             Mutex::Locker event_locker(m_events_mutex);
426             const bool remove = false;
427             if (FindNextEventInternal (broadcaster, broadcaster_names, num_broadcaster_names, event_type_mask, event_sp, remove))
428                 continue;
429             else
430                 m_cond_wait.SetValue (false, eBroadcastNever);
431         }
432 
433         if (m_cond_wait.WaitForValueEqualTo (true, timeout, &timed_out))
434             continue;
435 
436         else if (timed_out)
437         {
438             log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EVENTS);
439             if (log)
440                 log->Printf ("%p Listener::WaitForEventsInternal() timed out for %s", this, m_name.c_str());
441             break;
442         }
443         else
444         {
445             log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EVENTS);
446             if (log)
447                 log->Printf ("%p Listener::WaitForEventsInternal() unknown error for %s", this, m_name.c_str());
448             break;
449         }
450     }
451 
452     return false;
453 }
454 
455 bool
WaitForEventForBroadcasterWithType(const TimeValue * timeout,Broadcaster * broadcaster,uint32_t event_type_mask,EventSP & event_sp)456 Listener::WaitForEventForBroadcasterWithType
457 (
458     const TimeValue *timeout,
459     Broadcaster *broadcaster,
460     uint32_t event_type_mask,
461     EventSP &event_sp
462 )
463 {
464     return WaitForEventsInternal (timeout, broadcaster, NULL, 0, event_type_mask, event_sp);
465 }
466 
467 bool
WaitForEventForBroadcaster(const TimeValue * timeout,Broadcaster * broadcaster,EventSP & event_sp)468 Listener::WaitForEventForBroadcaster
469 (
470     const TimeValue *timeout,
471     Broadcaster *broadcaster,
472     EventSP &event_sp
473 )
474 {
475     return WaitForEventsInternal (timeout, broadcaster, NULL, 0, 0, event_sp);
476 }
477 
478 bool
WaitForEvent(const TimeValue * timeout,EventSP & event_sp)479 Listener::WaitForEvent (const TimeValue *timeout, EventSP &event_sp)
480 {
481     return WaitForEventsInternal (timeout, NULL, NULL, 0, 0, event_sp);
482 }
483 
484 //Listener::broadcaster_collection::iterator
485 //Listener::FindBroadcasterWithMask (Broadcaster *broadcaster, uint32_t event_mask, bool exact)
486 //{
487 //    broadcaster_collection::iterator pos;
488 //    broadcaster_collection::iterator end = m_broadcasters.end();
489 //    for (pos = m_broadcasters.find (broadcaster);
490 //        pos != end && pos->first == broadcaster;
491 //        ++pos)
492 //    {
493 //        if (exact)
494 //        {
495 //            if ((event_mask & pos->second.event_mask) == event_mask)
496 //                return pos;
497 //        }
498 //        else
499 //        {
500 //            if (event_mask & pos->second.event_mask)
501 //                return pos;
502 //        }
503 //    }
504 //    return end;
505 //}
506 
507 size_t
HandleBroadcastEvent(EventSP & event_sp)508 Listener::HandleBroadcastEvent (EventSP &event_sp)
509 {
510     size_t num_handled = 0;
511     Mutex::Locker locker(m_broadcasters_mutex);
512     Broadcaster *broadcaster = event_sp->GetBroadcaster();
513     broadcaster_collection::iterator pos;
514     broadcaster_collection::iterator end = m_broadcasters.end();
515     for (pos = m_broadcasters.find (broadcaster);
516         pos != end && pos->first == broadcaster;
517         ++pos)
518     {
519         BroadcasterInfo info = pos->second;
520         if (event_sp->GetType () & info.event_mask)
521         {
522             if (info.callback != NULL)
523             {
524                 info.callback (event_sp, info.callback_user_data);
525                 ++num_handled;
526             }
527         }
528     }
529     return num_handled;
530 }
531 
532 uint32_t
StartListeningForEventSpec(BroadcasterManager & manager,const BroadcastEventSpec & event_spec)533 Listener::StartListeningForEventSpec (BroadcasterManager &manager,
534                              const BroadcastEventSpec &event_spec)
535 {
536     // The BroadcasterManager mutex must be locked before m_broadcasters_mutex
537     // to avoid violating the lock hierarchy (manager before broadcasters).
538     Mutex::Locker manager_locker(manager.m_manager_mutex);
539     Mutex::Locker locker(m_broadcasters_mutex);
540 
541     uint32_t bits_acquired = manager.RegisterListenerForEvents(*this, event_spec);
542     if (bits_acquired)
543         m_broadcaster_managers.push_back(&manager);
544 
545     return bits_acquired;
546 }
547 
548 bool
StopListeningForEventSpec(BroadcasterManager & manager,const BroadcastEventSpec & event_spec)549 Listener::StopListeningForEventSpec (BroadcasterManager &manager,
550                              const BroadcastEventSpec &event_spec)
551 {
552     Mutex::Locker locker(m_broadcasters_mutex);
553     return manager.UnregisterListenerForEvents (*this, event_spec);
554 
555 }
556 
557 
558