]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/source/Core/Listener.cpp
MFV r302003,r302037,r302038,r302056:
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lldb / source / Core / Listener.cpp
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
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
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
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
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
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
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
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
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
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:
208     EventBroadcasterMatches (Broadcaster *broadcaster) :
209         m_broadcaster (broadcaster)    {
210     }
211
212     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:
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
236     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
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 *
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 *
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 *
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
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
377 Listener::GetNextEvent (EventSP &event_sp)
378 {
379     return GetNextEventInternal (NULL, NULL, 0, 0, event_sp);
380 }
381
382
383 bool
384 Listener::GetNextEventForBroadcaster (Broadcaster *broadcaster, EventSP &event_sp)
385 {
386     return GetNextEventInternal (broadcaster, NULL, 0, 0, event_sp);
387 }
388
389 bool
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
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
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
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
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
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
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
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