[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