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