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
24using namespace lldb;
25using namespace lldb_private;
26
27Listener::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
40Listener::~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
55void
56Listener::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
69uint32_t
70Listener::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
102uint32_t
103Listener::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
126bool
127Listener::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
145void
146Listener::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
173void
174Listener::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
183void
184Listener::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
198class EventBroadcasterMatches
199{
200public:
201    EventBroadcasterMatches (Broadcaster *broadcaster) :
202        m_broadcaster (broadcaster)    {
203    }
204
205    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
213private:
214    Broadcaster *m_broadcaster;
215
216};
217
218class EventMatcher
219{
220public:
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
229    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
255private:
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
263bool
264Listener::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
331Event *
332Listener::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
340Event *
341Listener::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
349Event *
350Listener::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
359bool
360Listener::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
372bool
373Listener::GetNextEvent (EventSP &event_sp)
374{
375    return GetNextEventInternal (NULL, NULL, 0, 0, event_sp);
376}
377
378
379bool
380Listener::GetNextEventForBroadcaster (Broadcaster *broadcaster, EventSP &event_sp)
381{
382    return GetNextEventInternal (broadcaster, NULL, 0, 0, event_sp);
383}
384
385bool
386Listener::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
392bool
393Listener::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
455bool
456Listener::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
467bool
468Listener::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
478bool
479Listener::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
507size_t
508Listener::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
532uint32_t
533Listener::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
548bool
549Listener::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