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