Add a way to temporarily divert events from a broadcaster to a private listener.
llvm-svn: 116271
GitOrigin-RevId: 30f9b21bf4811bd4694fc7074393dcaf9590add7
diff --git a/source/Core/Broadcaster.cpp b/source/Core/Broadcaster.cpp
index b311a8b..4847373 100644
--- a/source/Core/Broadcaster.cpp
+++ b/source/Core/Broadcaster.cpp
@@ -24,7 +24,9 @@
Broadcaster::Broadcaster (const char *name) :
m_broadcaster_name (name),
m_broadcaster_listeners (),
- m_broadcaster_listeners_mutex (Mutex::eMutexTypeRecursive)
+ m_broadcaster_listeners_mutex (Mutex::eMutexTypeRecursive),
+ m_hijacking_listener(NULL),
+ m_hijack_mask(UINT32_MAX)
{
Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT);
if (log)
@@ -116,6 +118,10 @@
Broadcaster::EventTypeHasListeners (uint32_t event_type)
{
Mutex::Locker locker (m_broadcaster_listeners_mutex);
+
+ if (m_hijacking_listener != NULL && event_type & m_hijack_mask)
+ return true;
+
if (m_broadcaster_listeners.empty())
return false;
@@ -185,20 +191,29 @@
unique);
}
- Mutex::Locker event_types_locker(m_broadcaster_listeners_mutex);
- collection::iterator pos, end = m_broadcaster_listeners.end();
-
-
- // Iterate through all listener/mask pairs
- for (pos = m_broadcaster_listeners.begin(); pos != end; ++pos)
+ if (m_hijacking_listener != NULL && m_hijack_mask & event_type)
{
- // If the listener's mask matches any bits that we just set, then
- // put the new event on its event queue.
- if (event_type & pos->second)
+ if (unique && m_hijacking_listener->PeekAtNextEventForBroadcasterWithType (this, event_type))
+ return;
+ m_hijacking_listener->AddEvent (event_sp);
+ }
+ else
+ {
+ Mutex::Locker event_types_locker(m_broadcaster_listeners_mutex);
+ collection::iterator pos, end = m_broadcaster_listeners.end();
+
+
+ // Iterate through all listener/mask pairs
+ for (pos = m_broadcaster_listeners.begin(); pos != end; ++pos)
{
- if (unique && pos->first->PeekAtNextEventForBroadcasterWithType (this, event_type))
- continue;
- pos->first->AddEvent (event_sp);
+ // If the listener's mask matches any bits that we just set, then
+ // put the new event on its event queue.
+ if (event_type & pos->second)
+ {
+ if (unique && pos->first->PeekAtNextEventForBroadcasterWithType (this, event_type))
+ continue;
+ pos->first->AddEvent (event_sp);
+ }
}
}
}
@@ -217,3 +232,24 @@
PrivateBroadcastEvent (event_sp, true);
}
+bool
+Broadcaster::HijackBroadcaster (Listener *listener, uint32_t event_mask)
+{
+ Mutex::Locker event_types_locker(m_broadcaster_listeners_mutex);
+
+ if (m_hijacking_listener != NULL)
+ return false;
+
+ m_hijacking_listener = listener;
+ m_hijack_mask = event_mask;
+ return true;
+}
+
+void
+Broadcaster::RestoreBroadcaster ()
+{
+ Mutex::Locker event_types_locker(m_broadcaster_listeners_mutex);
+
+ m_hijacking_listener = NULL;
+}
+