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