[Lldb-commits] [lldb] r116271 - in /lldb/trunk: include/lldb/Core/Broadcaster.h include/lldb/Target/Process.h lldb.xcodeproj/project.pbxproj source/Core/Broadcaster.cpp source/Expression/ClangFunction.cpp source/Target/Process.cpp
Jim Ingham
jingham at apple.com
Mon Oct 11 16:53:15 PDT 2010
Author: jingham
Date: Mon Oct 11 18:53:14 2010
New Revision: 116271
URL: http://llvm.org/viewvc/llvm-project?rev=116271&view=rev
Log:
Add a way to temporarily divert events from a broadcaster to a private listener.
Modified:
lldb/trunk/include/lldb/Core/Broadcaster.h
lldb/trunk/include/lldb/Target/Process.h
lldb/trunk/lldb.xcodeproj/project.pbxproj
lldb/trunk/source/Core/Broadcaster.cpp
lldb/trunk/source/Expression/ClangFunction.cpp
lldb/trunk/source/Target/Process.cpp
Modified: lldb/trunk/include/lldb/Core/Broadcaster.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/Broadcaster.h?rev=116271&r1=116270&r2=116271&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/Broadcaster.h (original)
+++ lldb/trunk/include/lldb/Core/Broadcaster.h Mon Oct 11 18:53:14 2010
@@ -165,10 +165,41 @@
//------------------------------------------------------------------
bool
RemoveListener (Listener* listener, uint32_t event_mask = UINT32_MAX);
-
-
+
protected:
+
+ //------------------------------------------------------------------
+ /// Provides a simple mechanism to temporarily redirect events from
+ /// broadcaster. When you call this function passing in a listener and
+ /// event type mask, all events from the broadcaster matching the mask
+ /// will now go to the hijacking listener.
+ /// Only one hijack can occur at a time. If we need more than this we
+ /// will have to implement a Listener stack.
+ ///
+ /// @param[in] listener
+ /// A Listener object. You do not need to call StartListeningForEvents
+ /// for this broadcaster (that would fail anyway since the event bits
+ /// would most likely be taken by the listener(s) you are usurping.
+ ///
+ /// @param[in] event_mask
+ /// The event bits \a listener wishes to hijack.
+ ///
+ /// @return
+ /// \b True if the event mask could be hijacked, \b false otherwise.
+ ///
+ /// @see uint32_t Broadcaster::AddListener (Listener*, uint32_t)
+ //------------------------------------------------------------------
+ bool
+ HijackBroadcaster (Listener *listener, uint32_t event_mask = UINT32_MAX);
+
+ //------------------------------------------------------------------
+ /// Restore the state of the Broadcaster from a previous hijack attempt.
+ ///
+ //------------------------------------------------------------------
+ void
+ RestoreBroadcaster ();
+
void
PrivateBroadcastEvent (lldb::EventSP &event_sp, bool unique);
@@ -181,7 +212,9 @@
const ConstString m_broadcaster_name; ///< The name of this broadcaster object.
collection m_broadcaster_listeners; ///< A list of Listener / event_mask pairs that are listening to this broadcaster.
Mutex m_broadcaster_listeners_mutex; ///< A mutex that protects \a m_broadcaster_listeners.
-
+ Listener *m_hijacking_listener; // A simple mechanism to intercept events in lieu of a real Listener collection stack.
+ uint32_t m_hijack_mask;
+
private:
//------------------------------------------------------------------
// For Broadcaster only
Modified: lldb/trunk/include/lldb/Target/Process.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/Process.h?rev=116271&r1=116270&r2=116271&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/Process.h (original)
+++ lldb/trunk/include/lldb/Target/Process.h Mon Oct 11 18:53:14 2010
@@ -1512,7 +1512,33 @@
Event *
PeekAtStateChangedEvents ();
+
+
+ //------------------------------------------------------------------
+ /// If you need to ensure that you and only you will hear about some public
+ /// event, then make a new listener, set to listen to process events, and
+ /// then call this with that listener. Then you will have to wait on that
+ /// listener explicitly for events (rather than using the GetNextEvent & WaitFor*
+ /// calls above. Be sure to call RestoreProcessEvents when you are done.
+ ///
+ /// @param[in] listener
+ /// This is the new listener to whom all process events will be delivered.
+ ///
+ /// @return
+ /// Returns \b true if the new listener could be installed,
+ /// \b false otherwise.
+ //------------------------------------------------------------------
+ bool
+ HijackProcessEvents (Listener *listener);
+
+ //------------------------------------------------------------------
+ /// Restores the process event broadcasting to its normal state.
+ ///
+ //------------------------------------------------------------------
+ void
+ RestoreProcessEvents ();
+protected:
//------------------------------------------------------------------
/// This is the part of the event handling that for a process event.
/// It decides what to do with the event and returns true if the
@@ -1530,6 +1556,7 @@
bool
ShouldBroadcastEvent (Event *event_ptr);
+public:
//------------------------------------------------------------------
/// Gets the byte order for this process.
///
Modified: lldb/trunk/lldb.xcodeproj/project.pbxproj
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lldb.xcodeproj/project.pbxproj?rev=116271&r1=116270&r2=116271&view=diff
==============================================================================
--- lldb/trunk/lldb.xcodeproj/project.pbxproj (original)
+++ lldb/trunk/lldb.xcodeproj/project.pbxproj Mon Oct 11 18:53:14 2010
@@ -2438,7 +2438,6 @@
isa = PBXProject;
buildConfigurationList = 1DEB91EF08733DB70010E9CD /* Build configuration list for PBXProject "lldb" */;
compatibilityVersion = "Xcode 3.1";
- developmentRegion = English;
hasScannedForEncodings = 1;
knownRegions = (
en,
Modified: lldb/trunk/source/Core/Broadcaster.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/Broadcaster.cpp?rev=116271&r1=116270&r2=116271&view=diff
==============================================================================
--- lldb/trunk/source/Core/Broadcaster.cpp (original)
+++ lldb/trunk/source/Core/Broadcaster.cpp Mon Oct 11 18:53:14 2010
@@ -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();
+ if (m_hijacking_listener != NULL && m_hijack_mask & event_type)
+ {
+ 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 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)
+ // 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;
+}
+
Modified: lldb/trunk/source/Expression/ClangFunction.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangFunction.cpp?rev=116271&r1=116270&r2=116271&view=diff
==============================================================================
--- lldb/trunk/source/Expression/ClangFunction.cpp (original)
+++ lldb/trunk/source/Expression/ClangFunction.cpp Mon Oct 11 18:53:14 2010
@@ -513,6 +513,9 @@
timeout_ptr = &real_timeout;
}
+ Listener listener("ClangFunction temporary listener");
+ exe_ctx.process->HijackProcessEvents(&listener);
+
Error resume_error = exe_ctx.process->Resume ();
if (!resume_error.Success())
{
@@ -525,11 +528,11 @@
while (1)
{
lldb::EventSP event_sp;
-
+ lldb::StateType stop_state = lldb::eStateInvalid;
// Now wait for the process to stop again:
- lldb::StateType stop_state = exe_ctx.process->WaitForStateChangedEvents (timeout_ptr, event_sp);
+ bool got_event = listener.WaitForEvent (timeout_ptr, event_sp);
- if (stop_state == lldb::eStateInvalid && timeout_ptr != NULL)
+ if (!got_event)
{
// Right now this is the only way to tell we've timed out...
// We should interrupt the process here...
@@ -544,7 +547,9 @@
{
timeout_ptr = NULL;
- stop_state = exe_ctx.process->WaitForStateChangedEvents (timeout_ptr, event_sp);
+ got_event = listener.WaitForEvent (timeout_ptr, event_sp);
+ stop_state = Process::ProcessEventData::GetStateFromEvent(event_sp.get());
+
if (stop_state == lldb::eStateInvalid)
{
errors.Printf ("Got an invalid stop state after halt.");
@@ -572,9 +577,15 @@
continue;
}
else
+ {
+ exe_ctx.process->RestoreProcessEvents ();
return eExecutionInterrupted;
+ }
}
}
+
+ stop_state = Process::ProcessEventData::GetStateFromEvent(event_sp.get());
+
if (stop_state == lldb::eStateRunning || stop_state == lldb::eStateStepping)
continue;
@@ -664,6 +675,9 @@
}
}
+ if (exe_ctx.process)
+ exe_ctx.process->RestoreProcessEvents ();
+
// Thread we ran the function in may have gone away because we ran the target
// Check that it's still there.
exe_ctx.thread = exe_ctx.process->GetThreadList().FindThreadByIndexID(tid, true).get();
Modified: lldb/trunk/source/Target/Process.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/Process.cpp?rev=116271&r1=116270&r2=116271&view=diff
==============================================================================
--- lldb/trunk/source/Target/Process.cpp (original)
+++ lldb/trunk/source/Target/Process.cpp Mon Oct 11 18:53:14 2010
@@ -217,6 +217,23 @@
return state;
}
+bool
+Process::HijackProcessEvents (Listener *listener)
+{
+ if (listener != NULL)
+ {
+ return HijackBroadcaster(listener, eBroadcastBitStateChanged);
+ }
+ else
+ return false;
+}
+
+void
+Process::RestoreProcessEvents ()
+{
+ RestoreBroadcaster();
+}
+
StateType
Process::WaitForStateChangedEvents (const TimeValue *timeout, EventSP &event_sp)
{
More information about the lldb-commits
mailing list