Home | History | Annotate | Download | only in Core
      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')", 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')", this, m_name.c_str());
     52     Clear();
     53 }
     54 
     55 void
     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
     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
    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
    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
    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
    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
    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:
    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 
    213 private:
    214     Broadcaster *m_broadcaster;
    215 
    216 };
    217 
    218 class EventMatcher
    219 {
    220 public:
    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 
    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
    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 *
    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 *
    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 *
    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
    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
    373 Listener::GetNextEvent (EventSP &event_sp)
    374 {
    375     return GetNextEventInternal (NULL, NULL, 0, 0, event_sp);
    376 }
    377 
    378 
    379 bool
    380 Listener::GetNextEventForBroadcaster (Broadcaster *broadcaster, EventSP &event_sp)
    381 {
    382     return GetNextEventInternal (broadcaster, NULL, 0, 0, event_sp);
    383 }
    384 
    385 bool
    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
    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
    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
    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
    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
    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
    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
    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