Change over the broadcaster/listener process to hold shared or weak pointers
authorJim Ingham <jingham@apple.com>
Mon, 7 Mar 2016 21:50:25 +0000 (21:50 +0000)
committerJim Ingham <jingham@apple.com>
Mon, 7 Mar 2016 21:50:25 +0000 (21:50 +0000)
to each other.  This should remove some infrequent teardown crashes when the
listener is not the debugger's listener.

Processes now need to take a ListenerSP, not a Listener&.

This required changing over the Process plugin class constructors to take a ListenerSP, instead
of a Listener&.   Other than that there should be no functional change.

<rdar://problem/24580184> CrashTracer: [USER] Xcode at â€¦ework: lldb_private::Listener::BroadcasterWillDestruct + 39

llvm-svn: 262863

50 files changed:
lldb/include/lldb/API/SBListener.h
lldb/include/lldb/Core/Broadcaster.h
lldb/include/lldb/Core/Debugger.h
lldb/include/lldb/Core/Event.h
lldb/include/lldb/Core/Listener.h
lldb/include/lldb/Target/Process.h
lldb/include/lldb/Target/ProcessLaunchInfo.h
lldb/include/lldb/Target/Target.h
lldb/include/lldb/lldb-forward.h
lldb/include/lldb/lldb-private-interfaces.h
lldb/packages/Python/lldbsuite/test/api/listeners/Makefile [new file with mode: 0644]
lldb/packages/Python/lldbsuite/test/api/listeners/TestListener.py [new file with mode: 0644]
lldb/packages/Python/lldbsuite/test/api/listeners/main.c [new file with mode: 0644]
lldb/source/API/SBBroadcaster.cpp
lldb/source/API/SBDebugger.cpp
lldb/source/API/SBListener.cpp
lldb/source/API/SBTarget.cpp
lldb/source/Core/Broadcaster.cpp
lldb/source/Core/Communication.cpp
lldb/source/Core/Debugger.cpp
lldb/source/Core/Event.cpp
lldb/source/Core/IOHandler.cpp
lldb/source/Core/Listener.cpp
lldb/source/Interpreter/CommandInterpreter.cpp
lldb/source/Plugins/Platform/Linux/PlatformLinux.cpp
lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp
lldb/source/Plugins/Platform/Windows/PlatformWindows.cpp
lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp
lldb/source/Plugins/Process/FreeBSD/ProcessFreeBSD.cpp
lldb/source/Plugins/Process/FreeBSD/ProcessFreeBSD.h
lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp
lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.h
lldb/source/Plugins/Process/Windows/Common/ProcessWindows.cpp
lldb/source/Plugins/Process/Windows/Common/ProcessWindows.h
lldb/source/Plugins/Process/Windows/Live/ProcessWindowsLive.cpp
lldb/source/Plugins/Process/Windows/Live/ProcessWindowsLive.h
lldb/source/Plugins/Process/Windows/MiniDump/ProcessWinMiniDump.cpp
lldb/source/Plugins/Process/Windows/MiniDump/ProcessWinMiniDump.h
lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp
lldb/source/Plugins/Process/elf-core/ProcessElfCore.h
lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp
lldb/source/Plugins/Process/mach-core/ProcessMachCore.h
lldb/source/Target/Process.cpp
lldb/source/Target/ProcessLaunchInfo.cpp
lldb/source/Target/Target.cpp
lldb/source/Target/TargetList.cpp
lldb/source/Target/Thread.cpp

index 924f810..e74d318 100644 (file)
@@ -106,8 +106,6 @@ protected:
     friend class SBLaunchInfo;
     friend class SBTarget;
 
-    SBListener (lldb_private::Listener &listener);
-
     SBListener (const lldb::ListenerSP &listener_sp);
 
     lldb::ListenerSP
@@ -124,20 +122,11 @@ private:
     lldb_private::Listener *
     get() const;
 
-    lldb_private::Listener &
-    ref() const;
-        
-    lldb_private::Listener &
-    operator *();
-
-    const lldb_private::Listener &
-    operator *() const;
-
     void
-    reset(lldb_private::Listener *listener, bool transfer_ownership);
+    reset(lldb::ListenerSP listener_sp);
 
     lldb::ListenerSP m_opaque_sp;
-    lldb_private::Listener *m_opaque_ptr;
+    lldb_private::Listener *m_unused_ptr;
 };
 
 } // namespace lldb
index ce5119b..8a61432 100644 (file)
@@ -19,9 +19,8 @@
 // Other libraries and framework includes
 // Project includes
 #include "lldb/lldb-private.h"
-//#include "lldb/Core/Flags.h"
 #include "lldb/Core/ConstString.h"
-#include "lldb/Core/Listener.h"
+#include "lldb/Host/Mutex.h"
 
 namespace lldb_private {
 
@@ -82,37 +81,47 @@ private:
     uint32_t m_event_bits;
 };
 
-class BroadcasterManager
+class BroadcasterManager :
+    public std::enable_shared_from_this<BroadcasterManager>
 {
 public:
     friend class Listener;
 
+protected:
     BroadcasterManager ();
-
+public:
+    // Listeners hold onto weak pointers to their broadcaster managers.  So they must be
+    // made into shared pointers, which you do with MakeBroadcasterManager.
+    
+    static lldb::BroadcasterManagerSP
+    MakeBroadcasterManager();
+    
     ~BroadcasterManager() = default;
 
     uint32_t
-    RegisterListenerForEvents (Listener &listener, BroadcastEventSpec event_spec);
+    RegisterListenerForEvents (lldb::ListenerSP listener_sp, BroadcastEventSpec event_spec);
     
     bool
-    UnregisterListenerForEvents (Listener &listener, BroadcastEventSpec event_spec);
+    UnregisterListenerForEvents (lldb::ListenerSP listener_sp, BroadcastEventSpec event_spec);
     
-    Listener *
+    lldb::ListenerSP
     GetListenerForEventSpec (BroadcastEventSpec event_spec) const;
     
     void
     SignUpListenersForBroadcaster (Broadcaster &broadcaster);
     
     void
-    RemoveListener (Listener &Listener);
+    RemoveListener (lldb::ListenerSP listener_sp);
+
+    void
+    RemoveListener (Listener *listener);
 
-protected:
     void Clear();
     
 private:
-    typedef std::pair<BroadcastEventSpec, Listener *> event_listener_key;
-    typedef std::map<BroadcastEventSpec, Listener *> collection;
-    typedef std::set<Listener *> listener_collection;
+    typedef std::pair<BroadcastEventSpec, lldb::ListenerSP> event_listener_key;
+    typedef std::map<BroadcastEventSpec, lldb::ListenerSP> collection;
+    typedef std::set<lldb::ListenerSP> listener_collection;
     collection m_event_map;
     listener_collection m_listeners;
     
@@ -162,9 +171,9 @@ private:
     {
     public:
         ListenerMatchesAndSharedBits (BroadcastEventSpec broadcaster_spec, 
-                                                   const Listener &listener) : 
+                                                   const lldb::ListenerSP listener_sp) :
             m_broadcaster_spec (broadcaster_spec),
-            m_listener (&listener) 
+            m_listener_sp (listener_sp)
         {
         }
         
@@ -174,19 +183,19 @@ private:
         {
             return (input.first.GetBroadcasterClass() == m_broadcaster_spec.GetBroadcasterClass()
                     && (input.first.GetEventBits() & m_broadcaster_spec.GetEventBits()) != 0
-                    && input.second == m_listener);
+                    && input.second == m_listener_sp);
         }
         
     private:
         BroadcastEventSpec m_broadcaster_spec;
-        const Listener *m_listener;
+        const lldb::ListenerSP m_listener_sp;
     };
     
     class ListenerMatches
     {
     public:
-        ListenerMatches (const Listener &in_listener) :
-            m_listener (&in_listener)
+        ListenerMatches (const lldb::ListenerSP in_listener_sp) :
+            m_listener_sp (in_listener_sp)
         {
         }
         
@@ -194,7 +203,40 @@ private:
         
         bool operator () (const event_listener_key input) const
         {
-            return (input.second == m_listener);
+            if (input.second == m_listener_sp)
+                return true;
+            else
+                return false;
+        }
+        
+    private:
+        const lldb::ListenerSP m_listener_sp;
+    };
+    
+    class ListenerMatchesPointer
+    {
+    public:
+        ListenerMatchesPointer (const Listener *in_listener) :
+            m_listener (in_listener)
+        {
+        }
+        
+        ~ListenerMatchesPointer() = default;
+        
+        bool operator () (const event_listener_key input) const
+        {
+            if (input.second.get() == m_listener)
+                return true;
+            else
+                return false;
+        }
+        
+        bool operator () (const lldb::ListenerSP input) const
+        {
+            if (input.get() == m_listener)
+                return true;
+            else
+                return false;
         }
         
     private:
@@ -237,6 +279,8 @@ private:
 //----------------------------------------------------------------------
 class Broadcaster
 {
+friend class Listener;
+friend class Event;
 public:
     //------------------------------------------------------------------
     /// Construct with a broadcaster with a name.
@@ -245,7 +289,7 @@ public:
     ///     A NULL terminated C string that contains the name of the
     ///     broadcaster object.
     //------------------------------------------------------------------
-    Broadcaster (BroadcasterManager *manager, const char *name);
+    Broadcaster (lldb::BroadcasterManagerSP manager_sp, const char *name);
 
     //------------------------------------------------------------------
     /// Destructor.
@@ -275,22 +319,37 @@ public:
     ///
     //------------------------------------------------------------------
     void
-    BroadcastEvent (lldb::EventSP &event_sp);
+    BroadcastEvent (lldb::EventSP &event_sp)
+    {
+        m_broadcaster_sp->BroadcastEvent(event_sp);
+    }
 
     void
-    BroadcastEventIfUnique (lldb::EventSP &event_sp);
+    BroadcastEventIfUnique (lldb::EventSP &event_sp)
+    {
+        m_broadcaster_sp->BroadcastEventIfUnique(event_sp);
+    }
 
     void
-    BroadcastEvent(uint32_t event_type, EventData *event_data = nullptr);
+    BroadcastEvent(uint32_t event_type, EventData *event_data = nullptr)
+    {
+        m_broadcaster_sp->BroadcastEvent(event_type, event_data);
+    }
 
     void
-    BroadcastEventIfUnique(uint32_t event_type, EventData *event_data = nullptr);
+    BroadcastEventIfUnique(uint32_t event_type, EventData *event_data = nullptr)
+    {
+        m_broadcaster_sp->BroadcastEventIfUnique(event_type, event_data);
+    }
 
     void
-    Clear();
+    Clear()
+    {
+        m_broadcaster_sp->Clear();
+    }
 
     virtual void
-    AddInitialEventsToListener (Listener *listener, uint32_t requested_events);
+    AddInitialEventsToListener (lldb::ListenerSP listener_sp, uint32_t requested_events);
 
     //------------------------------------------------------------------
     /// Listen for any events specified by \a event_mask.
@@ -315,7 +374,10 @@ public:
     ///     The actual event bits that were acquired by \a listener.
     //------------------------------------------------------------------
     uint32_t
-    AddListener (Listener* listener, uint32_t event_mask);
+    AddListener (lldb::ListenerSP listener_sp, uint32_t event_mask)
+    {
+        return m_broadcaster_sp->AddListener(listener_sp, event_mask);
+    }
 
     //------------------------------------------------------------------
     /// Get the NULL terminated C string name of this Broadcaster
@@ -325,7 +387,10 @@ public:
     ///     The NULL terminated C string name of this Broadcaster.
     //------------------------------------------------------------------
     const ConstString &
-    GetBroadcasterName ();
+    GetBroadcasterName ()
+    {
+        return m_broadcaster_name;
+    }
 
     //------------------------------------------------------------------
     /// Get the event name(s) for one or more event bits.
@@ -337,7 +402,10 @@ public:
     ///     The NULL terminated C string name of this Broadcaster.
     //------------------------------------------------------------------
     bool
-    GetEventNames (Stream &s, const uint32_t event_mask, bool prefix_with_broadcaster_name) const;
+    GetEventNames (Stream &s, const uint32_t event_mask, bool prefix_with_broadcaster_name) const
+    {
+        return m_broadcaster_sp->GetEventNames(s, event_mask, prefix_with_broadcaster_name);
+    }
 
     //------------------------------------------------------------------
     /// Set the name for an event bit.
@@ -352,20 +420,20 @@ public:
     void
     SetEventName (uint32_t event_mask, const char *name)
     {
-        m_event_names[event_mask] = name;
+        m_broadcaster_sp->SetEventName(event_mask, name);
     }
     
     const char *
     GetEventName (uint32_t event_mask) const
     {
-        const auto pos = m_event_names.find (event_mask);
-        if (pos != m_event_names.end())
-            return pos->second.c_str();
-        return nullptr;
+        return m_broadcaster_sp->GetEventName(event_mask);
     }
 
     bool
-    EventTypeHasListeners (uint32_t event_type);
+    EventTypeHasListeners (uint32_t event_type)
+    {
+        return m_broadcaster_sp->EventTypeHasListeners(event_type);
+    }
 
     //------------------------------------------------------------------
     /// Removes a Listener from this broadcasters list and frees the
@@ -386,7 +454,10 @@ public:
     /// @see uint32_t Broadcaster::AddListener (Listener*, uint32_t)
     //------------------------------------------------------------------
     bool
-    RemoveListener (Listener* listener, uint32_t event_mask = UINT32_MAX);
+    RemoveListener (lldb::ListenerSP listener_sp, uint32_t event_mask = UINT32_MAX)
+    {
+        return m_broadcaster_sp->RemoveListener(listener_sp, event_mask);
+    }
     
     //------------------------------------------------------------------
     /// Provides a simple mechanism to temporarily redirect events from 
@@ -410,17 +481,26 @@ public:
     /// @see uint32_t Broadcaster::AddListener (Listener*, uint32_t)
     //------------------------------------------------------------------
     bool
-    HijackBroadcaster (Listener *listener, uint32_t event_mask = UINT32_MAX);
+    HijackBroadcaster (lldb::ListenerSP listener_sp, uint32_t event_mask = UINT32_MAX)
+    {
+        return m_broadcaster_sp->HijackBroadcaster(listener_sp, event_mask);
+    }
     
     bool
-    IsHijackedForEvent (uint32_t event_mask);
+    IsHijackedForEvent (uint32_t event_mask)
+    {
+        return m_broadcaster_sp->IsHijackedForEvent(event_mask);
+    }
 
     //------------------------------------------------------------------
     /// Restore the state of the Broadcaster from a previous hijack attempt.
     ///
     //------------------------------------------------------------------
     void
-    RestoreBroadcaster ();
+    RestoreBroadcaster ()
+    {
+        m_broadcaster_sp->RestoreBroadcaster();
+    }
     
     // This needs to be filled in if you are going to register the broadcaster with the broadcaster
     // manager and do broadcaster class matching.
@@ -428,32 +508,145 @@ public:
     // with the BroadcasterManager, so that it is clearer how to add one.
     virtual ConstString &GetBroadcasterClass() const;
     
-    BroadcasterManager *GetManager();
+    lldb::BroadcasterManagerSP GetManager();
 
 protected:
-    void
-    PrivateBroadcastEvent (lldb::EventSP &event_sp, bool unique);
+    // BroadcasterImpl contains the actual Broadcaster implementation.  The Broadcaster makes a BroadcasterImpl
+    // which lives as long as it does.  The Listeners & the Events hold a weak pointer to the BroadcasterImpl,
+    // so that they can survive if a Broadcaster they were listening to is destroyed w/o their being able to
+    // unregister from it (which can happen if the Broadcasters & Listeners are being destroyed on separate threads
+    // simultaneously.
+    // The Broadcaster itself can't be shared out as a weak pointer, because some things that are broadcasters
+    // (e.g. the Target and the Process) are shared in their own right.
+    //
+    // For the most part, the Broadcaster functions dispatch to the BroadcasterImpl, and are documented in the
+    // public Broadcaster API above.
+    
+    
+    class BroadcasterImpl
+    {
+    friend class Listener;
+    friend class Broadcaster;
+    public:
+        BroadcasterImpl (Broadcaster &broadcaster);
+
+        ~BroadcasterImpl() = default;
+
+        void
+        BroadcastEvent (lldb::EventSP &event_sp);
+
+        void
+        BroadcastEventIfUnique (lldb::EventSP &event_sp);
+
+        void
+        BroadcastEvent(uint32_t event_type, EventData *event_data = nullptr);
+
+        void
+        BroadcastEventIfUnique(uint32_t event_type, EventData *event_data = nullptr);
 
+        void
+        Clear();
+
+        uint32_t
+        AddListener (lldb::ListenerSP listener_sp, uint32_t event_mask);
+
+        const char *
+        GetBroadcasterName () const
+        {
+            return m_broadcaster.GetBroadcasterName().AsCString();
+        }
+
+        Broadcaster *
+        GetBroadcaster();
+        
+        bool
+        GetEventNames (Stream &s, const uint32_t event_mask, bool prefix_with_broadcaster_name) const;
+
+        void
+        SetEventName (uint32_t event_mask, const char *name)
+        {
+            m_event_names[event_mask] = name;
+        }
+        
+        const char *
+        GetEventName (uint32_t event_mask) const
+        {
+            const auto pos = m_event_names.find (event_mask);
+            if (pos != m_event_names.end())
+                return pos->second.c_str();
+            return nullptr;
+        }
+
+        bool
+        EventTypeHasListeners (uint32_t event_type);
+
+        bool
+        RemoveListener (lldb::ListenerSP listener_sp, uint32_t event_mask = UINT32_MAX);
+        
+        bool
+        HijackBroadcaster (lldb::ListenerSP listener_sp, uint32_t event_mask = UINT32_MAX);
+        
+        bool
+        IsHijackedForEvent (uint32_t event_mask);
+
+        void
+        RestoreBroadcaster ();
+
+    protected:
+        void
+        PrivateBroadcastEvent (lldb::EventSP &event_sp, bool unique);
+
+        const char *
+        GetHijackingListenerName();
+
+        //------------------------------------------------------------------
+        //
+        //------------------------------------------------------------------
+        typedef std::vector< std::pair<lldb::ListenerSP,uint32_t> > collection;
+        typedef std::map<uint32_t, std::string> event_names_map;
+        
+        Broadcaster &m_broadcaster;                     ///< The broadcsater that this implements
+        event_names_map m_event_names;                  ///< Optionally define event names for readability and logging for each event bit
+        collection m_listeners;                         ///< A list of Listener / event_mask pairs that are listening to this broadcaster.
+        Mutex m_listeners_mutex;                        ///< A mutex that protects \a m_listeners.
+        std::vector<lldb::ListenerSP> m_hijacking_listeners;  // A simple mechanism to intercept events from a broadcaster
+        std::vector<uint32_t> m_hijacking_masks;        // At some point we may want to have a stack or Listener
+                                                        // collections, but for now this is just for private hijacking.
+        
+    private:
+        //------------------------------------------------------------------
+        // For Broadcaster only
+        //------------------------------------------------------------------
+        DISALLOW_COPY_AND_ASSIGN (BroadcasterImpl);
+    };
+    
+    typedef std::shared_ptr<BroadcasterImpl> BroadcasterImplSP;
+    typedef std::weak_ptr<BroadcasterImpl> BroadcasterImplWP;
+
+    BroadcasterImplSP
+    GetBroadcasterImpl()
+    {
+        return m_broadcaster_sp;
+    }
+    
+    const char *
+    GetHijackingListenerName()
+    {
+        return m_broadcaster_sp->GetHijackingListenerName();
+    }
     //------------------------------------------------------------------
     // Classes that inherit from Broadcaster can see and modify these
     //------------------------------------------------------------------
-    typedef std::vector< std::pair<Listener*,uint32_t> > collection;
-    typedef std::map<uint32_t, std::string> event_names_map;
-    // Prefix the name of our member variables with "m_broadcaster_"
-    // since this is a class that gets subclassed.
-    const ConstString m_broadcaster_name;   ///< The name of this broadcaster object.
-    event_names_map m_event_names;  ///< Optionally define event names for readability and logging for each event bit
-    collection m_listeners;     ///< A list of Listener / event_mask pairs that are listening to this broadcaster.
-    Mutex m_listeners_mutex;    ///< A mutex that protects \a m_listeners.
-    std::vector<Listener *> m_hijacking_listeners;  // A simple mechanism to intercept events from a broadcaster 
-    std::vector<uint32_t> m_hijacking_masks;        // At some point we may want to have a stack or Listener
-                                                    // collections, but for now this is just for private hijacking.
-    BroadcasterManager *m_manager;
+    
     
 private:
     //------------------------------------------------------------------
     // For Broadcaster only
     //------------------------------------------------------------------
+    BroadcasterImplSP m_broadcaster_sp;
+    lldb::BroadcasterManagerSP m_manager_sp;
+    const ConstString m_broadcaster_name;   ///< The name of this broadcaster object.
+    
     DISALLOW_COPY_AND_ASSIGN (Broadcaster);
 };
 
index 4ca648c..6398008 100644 (file)
@@ -53,8 +53,7 @@ namespace lldb_private {
 class Debugger :
     public std::enable_shared_from_this<Debugger>,
     public UserID,
-    public Properties,
-    public BroadcasterManager
+    public Properties
 {
 friend class SourceManager;  // For GetSourceFileCache.
 
@@ -159,10 +158,10 @@ public:
         return *m_command_interpreter_ap;
     }
 
-    Listener &
+    lldb::ListenerSP
     GetListener ()
     {
-        return m_listener;
+        return m_listener_sp;
     }
 
     // This returns the Debugger's scratch source manager.  It won't be able to look up files in debug
@@ -392,6 +391,12 @@ public:
     Target *GetSelectedOrDummyTarget(bool prefer_dummy = false);
     Target *GetDummyTarget();
 
+    lldb::BroadcasterManagerSP
+    GetBroadcasterManager()
+    {
+        return m_broadcaster_manager_sp;
+    }
+
 protected:
     friend class CommandInterpreter;
     friend class REPL;
@@ -446,15 +451,20 @@ protected:
 
     void
     InstanceInitialize ();
-
+    
     lldb::StreamFileSP m_input_file_sp;
     lldb::StreamFileSP m_output_file_sp;
     lldb::StreamFileSP m_error_file_sp;
+
+    lldb::BroadcasterManagerSP m_broadcaster_manager_sp;  // The debugger acts as a broadcaster manager of last resort.
+                                                          // It needs to get constructed before the target_list or any other
+                                                          // member that might want to broadcast through the debugger.
+
     TerminalState m_terminal_state;
     TargetList m_target_list;
 
     PlatformList m_platform_list;
-    Listener m_listener;
+    lldb::ListenerSP m_listener_sp;
     std::unique_ptr<SourceManager> m_source_manager_ap;    // This is a scratch source manager that we return if we have no targets.
     SourceManager::SourceFileCache m_source_file_cache; // All the source managers for targets created in this debugger used this shared
                                                         // source file cache.
index e8867c0..05f8d7e 100644 (file)
@@ -20,6 +20,7 @@
 #include "lldb/lldb-private.h"
 #include "lldb/Core/ConstString.h"
 #include "lldb/Host/Predicate.h"
+#include "lldb/Core/Broadcaster.h"
 
 namespace lldb_private {
 
@@ -118,9 +119,9 @@ private:
 //----------------------------------------------------------------------
 class Event
 {
-    friend class Broadcaster;
     friend class Listener;
     friend class EventData;
+    friend class Broadcaster::BroadcasterImpl;
 
 public:
     Event(Broadcaster *broadcaster, uint32_t event_type, EventData *data = nullptr);
@@ -165,13 +166,21 @@ public:
     Broadcaster *
     GetBroadcaster () const
     {
-        return m_broadcaster;
+        Broadcaster::BroadcasterImplSP broadcaster_impl_sp = m_broadcaster_wp.lock();
+        if (broadcaster_impl_sp)
+            return broadcaster_impl_sp->GetBroadcaster();
+        else
+            return nullptr;
     }
     
     bool
     BroadcasterIs (Broadcaster *broadcaster)
     {
-        return broadcaster == m_broadcaster;
+        Broadcaster::BroadcasterImplSP broadcaster_impl_sp = m_broadcaster_wp.lock();
+        if (broadcaster_impl_sp)
+            return broadcaster_impl_sp->GetBroadcaster() == broadcaster;
+        else
+            return false;
     }
 
     void
@@ -194,10 +203,10 @@ private:
     void
     SetBroadcaster (Broadcaster *broadcaster)
     {
-        m_broadcaster = broadcaster;
+        m_broadcaster_wp = broadcaster->GetBroadcasterImpl();
     }
 
-    Broadcaster *   m_broadcaster;  // The broadcaster that sent this event
+    Broadcaster::BroadcasterImplWP   m_broadcaster_wp;  // The broadcaster that sent this event
     uint32_t        m_type;         // The bit describing this event
     std::unique_ptr<EventData> m_data_ap;         // User specific data for this event
 
index b11c164..2e050c6 100644 (file)
 // Project includes
 #include "lldb/lldb-private.h"
 #include "lldb/Host/Predicate.h"
+#include "lldb/Core/Broadcaster.h"
 #include "lldb/Core/Event.h"
 
 namespace lldb_private {
 
-class Listener
+class Listener :
+    public std::enable_shared_from_this<Listener>
 {
 public:
     typedef bool (*HandleBroadcastCallback) (lldb::EventSP &event_sp, void *baton);
@@ -36,8 +38,16 @@ public:
     //------------------------------------------------------------------
     // Constructors and Destructors
     //------------------------------------------------------------------
+    //
+    // Listeners have to be constructed into shared pointers - at least if you want them to listen to
+    // Broadcasters, 
+protected:
     Listener (const char *name);
 
+public:
+    static lldb::ListenerSP
+    MakeListener(const char *name);
+    
     ~Listener ();
 
     void
@@ -53,11 +63,11 @@ public:
     }
 
     uint32_t
-    StartListeningForEventSpec (BroadcasterManager &manager, 
+    StartListeningForEventSpec (lldb::BroadcasterManagerSP manager_sp,
                                  const BroadcastEventSpec &event_spec);
     
     bool
-    StopListeningForEventSpec (BroadcasterManager &manager, 
+    StopListeningForEventSpec (lldb::BroadcasterManagerSP manager_sp,
                                  const BroadcastEventSpec &event_spec);
     
     uint32_t
@@ -133,9 +143,11 @@ private:
         void *callback_user_data;
     };
 
-    typedef std::multimap<Broadcaster*, BroadcasterInfo> broadcaster_collection;
+    typedef std::multimap<Broadcaster::BroadcasterImplWP,
+                          BroadcasterInfo,
+                          std::owner_less<Broadcaster::BroadcasterImplWP>> broadcaster_collection;
     typedef std::list<lldb::EventSP> event_collection;
-    typedef std::vector<BroadcasterManager *> broadcaster_manager_collection;
+    typedef std::vector<lldb::BroadcasterManagerWP> broadcaster_manager_collection;
 
     bool
     FindNextEventInternal(Broadcaster *broadcaster,   // nullptr for any broadcaster
@@ -172,7 +184,7 @@ private:
     BroadcasterWillDestruct (Broadcaster *);
     
     void
-    BroadcasterManagerWillDestruct (BroadcasterManager *manager);
+    BroadcasterManagerWillDestruct (lldb::BroadcasterManagerSP manager_sp);
     
 
 //    broadcaster_collection::iterator
index 09e6c27..e6e1260 100644 (file)
@@ -30,6 +30,7 @@
 #include "lldb/Core/Communication.h"
 #include "lldb/Core/Error.h"
 #include "lldb/Core/Event.h"
+#include "lldb/Core/Listener.h"
 #include "lldb/Core/LoadedModuleInfoList.h"
 #include "lldb/Core/ThreadSafeValue.h"
 #include "lldb/Core/PluginInterface.h"
@@ -400,7 +401,7 @@ public:
         m_listener_sp = listener_sp;
     }
 
-    Listener &
+    lldb::ListenerSP
     GetListenerForProcess (Debugger &debugger);
 
 protected:
@@ -939,13 +940,13 @@ public:
     /// Construct with a shared pointer to a target, and the Process listener.
     /// Uses the Host UnixSignalsSP by default.
     //------------------------------------------------------------------
-    Process(lldb::TargetSP target_sp, Listener &listener);
+    Process(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp);
 
     //------------------------------------------------------------------
     /// Construct with a shared pointer to a target, the Process listener,
     /// and the appropriate UnixSignalsSP for the process.
     //------------------------------------------------------------------
-    Process(lldb::TargetSP target_sp, Listener &listener, const lldb::UnixSignalsSP &unix_signals_sp);
+    Process(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp, const lldb::UnixSignalsSP &unix_signals_sp);
 
     //------------------------------------------------------------------
     /// Destructor.
@@ -985,7 +986,7 @@ public:
     static lldb::ProcessSP
     FindPlugin (lldb::TargetSP target_sp,
                 const char *plugin_name, 
-                Listener &listener, 
+                lldb::ListenerSP listener_sp,
                 const FileSpec *crash_file_path);
 
     //------------------------------------------------------------------
@@ -2851,7 +2852,7 @@ public:
     WaitForProcessToStop(const TimeValue *timeout,
                          lldb::EventSP *event_sp_ptr = nullptr,
                          bool wait_always = true,
-                         Listener *hijack_listener = nullptr,
+                         lldb::ListenerSP hijack_listener = lldb::ListenerSP(),
                          Stream *stream = nullptr,
                          bool use_run_lock = true);
 
@@ -2877,7 +2878,7 @@ public:
     lldb::StateType
     WaitForStateChangedEvents(const TimeValue *timeout,
                               lldb::EventSP &event_sp,
-                              Listener *hijack_listener); // Pass nullptr to use builtin listener
+                              lldb::ListenerSP hijack_listener); // Pass an empty ListenerSP to use builtin listener
 
     //--------------------------------------------------------------------------------------
     /// Centralize the code that handles and prints descriptions for process state changes.
@@ -2908,10 +2909,10 @@ public:
     ProcessEventHijacker
     {
     public:
-        ProcessEventHijacker (Process &process, Listener *listener) :
+        ProcessEventHijacker (Process &process, lldb::ListenerSP listener_sp) :
             m_process (process)
         {
-            m_process.HijackProcessEvents (listener);
+            m_process.HijackProcessEvents (listener_sp);
         }
 
         ~ProcessEventHijacker ()
@@ -2940,7 +2941,7 @@ public:
     ///     \b false otherwise.
     //------------------------------------------------------------------
     bool
-    HijackProcessEvents (Listener *listener);
+    HijackProcessEvents (lldb::ListenerSP listener_sp);
     
     //------------------------------------------------------------------
     /// Restores the process event broadcasting to its normal state.
@@ -3343,7 +3344,7 @@ protected:
     ThreadSafeValue<lldb::StateType>  m_private_state; // The actual state of our process
     Broadcaster                 m_private_state_broadcaster;  // This broadcaster feeds state changed events into the private state thread's listener.
     Broadcaster                 m_private_state_control_broadcaster; // This is the control broadcaster, used to pause, resume & stop the private state thread.
-    Listener                    m_private_state_listener;     // This is the listener for the private state thread.
+    lldb::ListenerSP            m_private_state_listener_sp;     // This is the listener for the private state thread.
     Predicate<bool>             m_private_state_control_wait; /// This Predicate is used to signal that a control operation is complete.
     HostThread                  m_private_state_thread; ///< Thread ID for the thread that watches internal state events
     ProcessModID                m_mod_id;               ///< Tracks the state of the process over stops and other alterations.
@@ -3363,7 +3364,7 @@ protected:
     uint32_t                    m_queue_list_stop_id;   ///< The natural stop id when queue list was last fetched
     std::vector<Notifications>  m_notifications;        ///< The list of notifications that this process can deliver.
     std::vector<lldb::addr_t>   m_image_tokens;
-    Listener                    &m_listener;
+    lldb::ListenerSP            m_listener_sp;          ///< Shared pointer to the listener used for public events.  Can not be empty.
     BreakpointSiteList          m_breakpoint_site_list; ///< This is the list of breakpoint locations we intend to insert in the target.
     lldb::DynamicLoaderUP       m_dyld_ap;
     lldb::JITLoaderListUP       m_jit_loaders_ap;
index 92a3ed4..eb5a66d 100644 (file)
@@ -196,7 +196,7 @@ namespace lldb_private
             m_listener_sp = listener_sp;
         }
 
-        Listener &
+        lldb::ListenerSP
         GetListenerForProcess (Debugger &debugger);
 
         lldb::ListenerSP
index 5932dda..dcc5940 100644 (file)
@@ -719,7 +719,7 @@ public:
     Dump (Stream *s, lldb::DescriptionLevel description_level);
 
     const lldb::ProcessSP &
-    CreateProcess (Listener &listener, 
+    CreateProcess (lldb::ListenerSP listener,
                    const char *plugin_name,
                    const FileSpec *crash_file);
 
index 516f319..f67dab1 100644 (file)
@@ -310,6 +310,8 @@ namespace lldb {
     typedef std::weak_ptr<lldb_private::BreakpointLocation> BreakpointLocationWP;
     typedef std::shared_ptr<lldb_private::BreakpointResolver> BreakpointResolverSP;
     typedef std::shared_ptr<lldb_private::Broadcaster> BroadcasterSP;
+    typedef std::shared_ptr<lldb_private::BroadcasterManager> BroadcasterManagerSP;
+    typedef std::weak_ptr<lldb_private::BroadcasterManager> BroadcasterManagerWP;
     typedef std::unique_ptr<lldb_private::ClangASTContext> ClangASTContextUP;
     typedef std::shared_ptr<lldb_private::ClangASTImporter> ClangASTImporterSP;
     typedef std::unique_ptr<lldb_private::ClangModulesDeclVendor> ClangModulesDeclVendorUP;
index 6bc8dad..8775ce6 100644 (file)
@@ -35,7 +35,7 @@ namespace lldb_private
     typedef lldb::CommandObjectSP (*LanguageRuntimeGetCommandObject) (CommandInterpreter& interpreter);
     typedef SystemRuntime *(*SystemRuntimeCreateInstance) (Process *process);
     typedef lldb::PlatformSP (*PlatformCreateInstance) (bool force, const ArchSpec *arch);
-    typedef lldb::ProcessSP (*ProcessCreateInstance) (lldb::TargetSP target_sp, Listener &listener, const FileSpec *crash_file_path);
+    typedef lldb::ProcessSP (*ProcessCreateInstance) (lldb::TargetSP target_sp, lldb::ListenerSP listener_sp, const FileSpec *crash_file_path);
     typedef lldb::ScriptInterpreterSP (*ScriptInterpreterCreateInstance)(CommandInterpreter &interpreter);
     typedef SymbolFile* (*SymbolFileCreateInstance) (ObjectFile* obj_file);
     typedef SymbolVendor* (*SymbolVendorCreateInstance) (const lldb::ModuleSP &module_sp, lldb_private::Stream *feedback_strm);   // Module can be NULL for default system symbol vendor
diff --git a/lldb/packages/Python/lldbsuite/test/api/listeners/Makefile b/lldb/packages/Python/lldbsuite/test/api/listeners/Makefile
new file mode 100644 (file)
index 0000000..fbedeab
--- /dev/null
@@ -0,0 +1,6 @@
+LEVEL = ../../make
+
+C_SOURCES := main.c
+
+include $(LEVEL)/Makefile.rules
+
diff --git a/lldb/packages/Python/lldbsuite/test/api/listeners/TestListener.py b/lldb/packages/Python/lldbsuite/test/api/listeners/TestListener.py
new file mode 100644 (file)
index 0000000..bd8c204
--- /dev/null
@@ -0,0 +1,55 @@
+"""
+Test that we can listen to modules loaded events.
+"""
+
+from __future__ import print_function
+
+import copy
+import os
+import time
+
+import lldb
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+import six
+
+class ListenToModuleLoadedEvents (TestBase):
+
+    mydir = TestBase.compute_mydir(__file__)
+
+    def setUp(self):
+        # Call super's setUp().
+        TestBase.setUp(self)
+        self.build()
+
+    def test_receiving_breakpoint_added (self):
+        """Test that we get breakpoint added events, waiting on event classes on the debugger"""
+
+        my_listener = lldb.SBListener("test_listener")
+        
+        my_listener.StartListeningForEventClass(self.dbg, lldb.SBTarget.GetBroadcasterClassName(), lldb.SBTarget.eBroadcastBitBreakpointChanged)
+
+        exe = os.path.join (os.getcwd(), "a.out")
+
+        target = self.dbg.CreateTarget(exe)
+
+        bkpt = target.BreakpointCreateByName("main")
+
+        event = lldb.SBEvent()
+        my_listener.WaitForEvent(1, event)
+        
+        self.assertTrue(event.IsValid(), "Got a valid event.")
+        self.assertTrue(lldb.SBBreakpoint.EventIsBreakpointEvent(event), "It is a breakpoint event.")
+        self.assertTrue(lldb.SBBreakpoint.GetBreakpointEventTypeFromEvent(event) == lldb.eBreakpointEventTypeAdded, "It is a breakpoint added event.")
+        self.assertTrue(bkpt == lldb.SBBreakpoint.GetBreakpointFromEvent(event), "It is our breakpoint.")
+
+        # Now make sure if we stop listening for events we don't get them:
+
+        my_listener.StopListeningForEventClass(self.dbg, lldb.SBTarget.GetBroadcasterClassName(), lldb.SBTarget.eBroadcastBitBreakpointChanged)
+        my_listener.StopListeningForEvents(target.GetBroadcaster(), lldb.SBTarget.eBroadcastBitBreakpointChanged)
+
+        bkpt2 = target.BreakpointCreateByName("main")
+        my_listener.WaitForEvent(1, event)
+        self.assertTrue(not event.IsValid(), "We don't get events we aren't listening to.")
diff --git a/lldb/packages/Python/lldbsuite/test/api/listeners/main.c b/lldb/packages/Python/lldbsuite/test/api/listeners/main.c
new file mode 100644 (file)
index 0000000..f930e51
--- /dev/null
@@ -0,0 +1,7 @@
+#include <stdio.h>
+
+int
+main()
+{
+    printf ("Hello there.\n");
+}
index 73eac51..4b751ad 100644 (file)
@@ -117,14 +117,14 @@ SBBroadcaster::AddInitialEventsToListener (const SBListener &listener, uint32_t
                      static_cast<void*>(m_opaque_ptr),
                      static_cast<void*>(listener.get()), requested_events);
     if (m_opaque_ptr)
-        m_opaque_ptr->AddInitialEventsToListener (listener.get(), requested_events);
+        m_opaque_ptr->AddInitialEventsToListener (listener.m_opaque_sp, requested_events);
 }
 
 uint32_t
 SBBroadcaster::AddListener (const SBListener &listener, uint32_t event_mask)
 {
     if (m_opaque_ptr)
-        return m_opaque_ptr->AddListener (listener.get(), event_mask);
+        return m_opaque_ptr->AddListener (listener.m_opaque_sp, event_mask);
     return 0;
 }
 
@@ -148,7 +148,7 @@ bool
 SBBroadcaster::RemoveListener (const SBListener &listener, uint32_t event_mask)
 {
     if (m_opaque_ptr)
-        return m_opaque_ptr->RemoveListener (listener.get(), event_mask);
+        return m_opaque_ptr->RemoveListener (listener.m_opaque_sp, event_mask);
     return false;
 }
 
index 1645294..f03262e 100644 (file)
@@ -432,8 +432,8 @@ SBDebugger::HandleCommand (const char *command)
             if (process_sp)
             {
                 EventSP event_sp;
-                Listener &lldb_listener = m_opaque_sp->GetListener();
-                while (lldb_listener.GetNextEventForBroadcaster (process_sp.get(), event_sp))
+                ListenerSP lldb_listener_sp = m_opaque_sp->GetListener();
+                while (lldb_listener_sp->GetNextEventForBroadcaster (process_sp.get(), event_sp))
                 {
                     SBEvent event(event_sp);
                     HandleProcessEvent (process, event, GetOutputFileHandle(), GetErrorFileHandle());
@@ -450,7 +450,7 @@ SBDebugger::GetListener ()
 
     SBListener sb_listener;
     if (m_opaque_sp)
-        sb_listener.reset(&m_opaque_sp->GetListener(), false);
+        sb_listener.reset(m_opaque_sp->GetListener());
 
     if (log)
         log->Printf ("SBDebugger(%p)::GetListener () => SBListener(%p)",
index 643c82d..8e63de0 100644 (file)
@@ -26,27 +26,25 @@ using namespace lldb_private;
 
 SBListener::SBListener () :
     m_opaque_sp (),
-    m_opaque_ptr (NULL)
+    m_unused_ptr (NULL)
 {
 }
 
 SBListener::SBListener (const char *name) :
-    m_opaque_sp (new Listener (name)),
-    m_opaque_ptr (NULL)
+    m_opaque_sp (Listener::MakeListener(name)),
+    m_unused_ptr (nullptr)
 {
-    m_opaque_ptr = m_opaque_sp.get();
-
     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
 
     if (log)
         log->Printf ("SBListener::SBListener (name=\"%s\") => SBListener(%p)",
-                     name, static_cast<void*>(m_opaque_ptr));
+                     name, static_cast<void*>(m_opaque_sp.get()));
 }
 
 
 SBListener::SBListener (const SBListener &rhs) :
     m_opaque_sp (rhs.m_opaque_sp),
-    m_opaque_ptr (rhs.m_opaque_ptr)
+    m_unused_ptr (nullptr)
 {
 }
 
@@ -56,20 +54,14 @@ SBListener::operator = (const lldb::SBListener &rhs)
     if (this != &rhs)
     {
         m_opaque_sp = rhs.m_opaque_sp;
-        m_opaque_ptr = rhs.m_opaque_ptr;
+        m_unused_ptr = nullptr;
     }
     return *this;
 }
 
-SBListener::SBListener (Listener &listener) :
-    m_opaque_sp (),
-    m_opaque_ptr (&listener)
-{
-}
-
 SBListener::SBListener (const lldb::ListenerSP &listener_sp) :
     m_opaque_sp (listener_sp),
-    m_opaque_ptr (listener_sp.get())
+    m_unused_ptr (nullptr)
 {
 }
 
@@ -80,7 +72,7 @@ SBListener::~SBListener ()
 bool
 SBListener::IsValid() const
 {
-    return m_opaque_ptr != NULL;
+    return m_opaque_sp != nullptr;
 }
 
 void
@@ -88,14 +80,14 @@ SBListener::AddEvent (const SBEvent &event)
 {
     EventSP &event_sp = event.GetSP ();
     if (event_sp)
-        m_opaque_ptr->AddEvent (event_sp);
+        m_opaque_sp->AddEvent (event_sp);
 }
 
 void
 SBListener::Clear ()
 {
-    if (m_opaque_ptr)
-        m_opaque_ptr->Clear ();
+    if (m_opaque_sp)
+        m_opaque_sp->Clear ();
 }
 
 uint32_t
@@ -103,13 +95,13 @@ SBListener::StartListeningForEventClass (SBDebugger &debugger,
                              const char *broadcaster_class, 
                              uint32_t event_mask)
 {
-    if (m_opaque_ptr)
+    if (m_opaque_sp)
     {
         Debugger *lldb_debugger = debugger.get();
         if (!lldb_debugger)
             return 0;
         BroadcastEventSpec event_spec (ConstString (broadcaster_class), event_mask);
-        return m_opaque_ptr->StartListeningForEventSpec (*lldb_debugger, event_spec);
+        return m_opaque_sp->StartListeningForEventSpec (lldb_debugger->GetBroadcasterManager(), event_spec);
     }
     else
         return 0;
@@ -120,13 +112,13 @@ SBListener::StopListeningForEventClass (SBDebugger &debugger,
                             const char *broadcaster_class,
                             uint32_t event_mask)
 {
-    if (m_opaque_ptr)
+    if (m_opaque_sp)
     {
         Debugger *lldb_debugger = debugger.get();
         if (!lldb_debugger)
             return false;
         BroadcastEventSpec event_spec (ConstString (broadcaster_class), event_mask);
-        return m_opaque_ptr->StopListeningForEventSpec (*lldb_debugger, event_spec);
+        return m_opaque_sp->StopListeningForEventSpec (lldb_debugger->GetBroadcasterManager(), event_spec);
     }
     else
         return false;
@@ -136,9 +128,9 @@ uint32_t
 SBListener::StartListeningForEvents (const SBBroadcaster& broadcaster, uint32_t event_mask)
 {
     uint32_t acquired_event_mask = 0;
-    if (m_opaque_ptr && broadcaster.IsValid())
+    if (m_opaque_sp && broadcaster.IsValid())
     {
-        acquired_event_mask = m_opaque_ptr->StartListeningForEvents (broadcaster.get(), event_mask);
+        acquired_event_mask = m_opaque_sp->StartListeningForEvents (broadcaster.get(), event_mask);
     }
 
     Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API);
@@ -153,7 +145,7 @@ SBListener::StartListeningForEvents (const SBBroadcaster& broadcaster, uint32_t
             const bool got_requested_names = lldb_broadcaster->GetEventNames (sstr_requested, event_mask, false);
             const bool got_acquired_names = lldb_broadcaster->GetEventNames (sstr_acquired, acquired_event_mask, false);
             log->Printf ("SBListener(%p)::StartListeneingForEvents (SBBroadcaster(%p): %s, event_mask=0x%8.8x%s%s%s) => 0x%8.8x%s%s%s",
-                         static_cast<void*>(m_opaque_ptr),
+                         static_cast<void*>(m_opaque_sp.get()),
                          static_cast<void*>(lldb_broadcaster),
                          lldb_broadcaster->GetBroadcasterName().GetCString(),
                          event_mask,
@@ -168,7 +160,7 @@ SBListener::StartListeningForEvents (const SBBroadcaster& broadcaster, uint32_t
         else
         {
             log->Printf ("SBListener(%p)::StartListeneingForEvents (SBBroadcaster(%p), event_mask=0x%8.8x) => 0x%8.8x",
-                         static_cast<void*>(m_opaque_ptr),
+                         static_cast<void*>(m_opaque_sp.get()),
                          static_cast<void*>(lldb_broadcaster), event_mask,
                          acquired_event_mask);
         }
@@ -180,9 +172,9 @@ SBListener::StartListeningForEvents (const SBBroadcaster& broadcaster, uint32_t
 bool
 SBListener::StopListeningForEvents (const SBBroadcaster& broadcaster, uint32_t event_mask)
 {
-    if (m_opaque_ptr && broadcaster.IsValid())
+    if (m_opaque_sp && broadcaster.IsValid())
     {
-        return m_opaque_ptr->StopListeningForEvents (broadcaster.get(), event_mask);
+        return m_opaque_sp->StopListeningForEvents (broadcaster.get(), event_mask);
     }
     return false;
 }
@@ -196,19 +188,19 @@ SBListener::WaitForEvent (uint32_t timeout_secs, SBEvent &event)
         if (timeout_secs == UINT32_MAX)
         {
             log->Printf ("SBListener(%p)::WaitForEvent (timeout_secs=INFINITE, SBEvent(%p))...",
-                         static_cast<void*>(m_opaque_ptr),
+                         static_cast<void*>(m_opaque_sp.get()),
                          static_cast<void*>(event.get()));
         }
         else
         {
             log->Printf ("SBListener(%p)::WaitForEvent (timeout_secs=%d, SBEvent(%p))...",
-                         static_cast<void*>(m_opaque_ptr), timeout_secs,
+                         static_cast<void*>(m_opaque_sp.get()), timeout_secs,
                          static_cast<void*>(event.get()));
         }
     }
     bool success = false;
 
-    if (m_opaque_ptr)
+    if (m_opaque_sp)
     {
         TimeValue time_value;
         if (timeout_secs != UINT32_MAX)
@@ -218,7 +210,7 @@ SBListener::WaitForEvent (uint32_t timeout_secs, SBEvent &event)
             time_value.OffsetWithSeconds (timeout_secs);
         }
         EventSP event_sp;
-        if (m_opaque_ptr->WaitForEvent (time_value.IsValid() ? &time_value : NULL, event_sp))
+        if (m_opaque_sp->WaitForEvent (time_value.IsValid() ? &time_value : NULL, event_sp))
         {
             event.reset (event_sp);
             success = true;
@@ -230,13 +222,13 @@ SBListener::WaitForEvent (uint32_t timeout_secs, SBEvent &event)
         if (timeout_secs == UINT32_MAX)
         {
             log->Printf ("SBListener(%p)::WaitForEvent (timeout_secs=INFINITE, SBEvent(%p)) => %i",
-                         static_cast<void*>(m_opaque_ptr),
+                         static_cast<void*>(m_opaque_sp.get()),
                          static_cast<void*>(event.get()), success);
         }
         else
         {
             log->Printf ("SBListener(%p)::WaitForEvent (timeout_secs=%d, SBEvent(%p)) => %i",
-                         static_cast<void*>(m_opaque_ptr), timeout_secs,
+                         static_cast<void*>(m_opaque_sp.get()), timeout_secs,
                          static_cast<void*>(event.get()), success);
         }
     }
@@ -253,7 +245,7 @@ SBListener::WaitForEventForBroadcaster
     SBEvent &event
 )
 {
-    if (m_opaque_ptr && broadcaster.IsValid())
+    if (m_opaque_sp && broadcaster.IsValid())
     {
         TimeValue time_value;
         if (num_seconds != UINT32_MAX)
@@ -262,7 +254,7 @@ SBListener::WaitForEventForBroadcaster
             time_value.OffsetWithSeconds (num_seconds);
         }
         EventSP event_sp;
-        if (m_opaque_ptr->WaitForEventForBroadcaster (time_value.IsValid() ? &time_value : NULL,
+        if (m_opaque_sp->WaitForEventForBroadcaster (time_value.IsValid() ? &time_value : NULL,
                                                          broadcaster.get(),
                                                          event_sp))
         {
@@ -284,7 +276,7 @@ SBListener::WaitForEventForBroadcasterWithType
     SBEvent &event
 )
 {
-    if (m_opaque_ptr && broadcaster.IsValid())
+    if (m_opaque_sp && broadcaster.IsValid())
     {
         TimeValue time_value;
         if (num_seconds != UINT32_MAX)
@@ -293,7 +285,7 @@ SBListener::WaitForEventForBroadcasterWithType
             time_value.OffsetWithSeconds (num_seconds);
         }
         EventSP event_sp;
-        if (m_opaque_ptr->WaitForEventForBroadcasterWithType (time_value.IsValid() ? &time_value : NULL,
+        if (m_opaque_sp->WaitForEventForBroadcasterWithType (time_value.IsValid() ? &time_value : NULL,
                                                               broadcaster.get(),
                                                               event_type_mask,
                                                               event_sp))
@@ -309,9 +301,9 @@ SBListener::WaitForEventForBroadcasterWithType
 bool
 SBListener::PeekAtNextEvent (SBEvent &event)
 {
-    if (m_opaque_ptr)
+    if (m_opaque_sp)
     {
-        event.reset (m_opaque_ptr->PeekAtNextEvent ());
+        event.reset (m_opaque_sp->PeekAtNextEvent ());
         return event.IsValid();
     }
     event.reset (NULL);
@@ -321,9 +313,9 @@ SBListener::PeekAtNextEvent (SBEvent &event)
 bool
 SBListener::PeekAtNextEventForBroadcaster (const SBBroadcaster &broadcaster, SBEvent &event)
 {
-    if (m_opaque_ptr && broadcaster.IsValid())
+    if (m_opaque_sp && broadcaster.IsValid())
     {
-        event.reset (m_opaque_ptr->PeekAtNextEventForBroadcaster (broadcaster.get()));
+        event.reset (m_opaque_sp->PeekAtNextEventForBroadcaster (broadcaster.get()));
         return event.IsValid();
     }
     event.reset (NULL);
@@ -334,9 +326,9 @@ bool
 SBListener::PeekAtNextEventForBroadcasterWithType (const SBBroadcaster &broadcaster, uint32_t event_type_mask,
                                                    SBEvent &event)
 {
-    if (m_opaque_ptr && broadcaster.IsValid())
+    if (m_opaque_sp && broadcaster.IsValid())
     {
-        event.reset(m_opaque_ptr->PeekAtNextEventForBroadcasterWithType (broadcaster.get(), event_type_mask));
+        event.reset(m_opaque_sp->PeekAtNextEventForBroadcasterWithType (broadcaster.get(), event_type_mask));
         return event.IsValid();
     }
     event.reset (NULL);
@@ -346,10 +338,10 @@ SBListener::PeekAtNextEventForBroadcasterWithType (const SBBroadcaster &broadcas
 bool
 SBListener::GetNextEvent (SBEvent &event)
 {
-    if (m_opaque_ptr)
+    if (m_opaque_sp)
     {
         EventSP event_sp;
-        if (m_opaque_ptr->GetNextEvent (event_sp))
+        if (m_opaque_sp->GetNextEvent (event_sp))
         {
             event.reset (event_sp);
             return true;
@@ -362,10 +354,10 @@ SBListener::GetNextEvent (SBEvent &event)
 bool
 SBListener::GetNextEventForBroadcaster (const SBBroadcaster &broadcaster, SBEvent &event)
 {
-    if (m_opaque_ptr && broadcaster.IsValid())
+    if (m_opaque_sp && broadcaster.IsValid())
     {
         EventSP event_sp;
-        if (m_opaque_ptr->GetNextEventForBroadcaster (broadcaster.get(), event_sp))
+        if (m_opaque_sp->GetNextEventForBroadcaster (broadcaster.get(), event_sp))
         {
             event.reset (event_sp);
             return true;
@@ -383,10 +375,10 @@ SBListener::GetNextEventForBroadcasterWithType
     SBEvent &event
 )
 {
-    if (m_opaque_ptr && broadcaster.IsValid())
+    if (m_opaque_sp && broadcaster.IsValid())
     {
         EventSP event_sp;
-        if (m_opaque_ptr->GetNextEventForBroadcasterWithType (broadcaster.get(),
+        if (m_opaque_sp->GetNextEventForBroadcasterWithType (broadcaster.get(),
                                                               event_type_mask,
                                                               event_sp))
         {
@@ -401,49 +393,28 @@ SBListener::GetNextEventForBroadcasterWithType
 bool
 SBListener::HandleBroadcastEvent (const SBEvent &event)
 {
-    if (m_opaque_ptr)
-        return m_opaque_ptr->HandleBroadcastEvent (event.GetSP());
+    if (m_opaque_sp)
+        return m_opaque_sp->HandleBroadcastEvent (event.GetSP());
     return false;
 }
 
 Listener *
 SBListener::operator->() const
 {
-    return m_opaque_ptr;
+    return m_opaque_sp.get();
 }
 
 Listener *
 SBListener::get() const
 {
-    return m_opaque_ptr;
+    return m_opaque_sp.get();
 }
 
 void
-SBListener::reset(Listener *listener, bool owns)
-{
-    if (owns)
-        m_opaque_sp.reset (listener);
-    else
-        m_opaque_sp.reset ();
-    m_opaque_ptr = listener;
-}
-
-Listener &
-SBListener::ref() const
-{
-    return *m_opaque_ptr;    
-}
-
-Listener &
-SBListener::operator *()
-{
-    return *m_opaque_ptr;
-}
-
-const Listener &
-SBListener::operator *() const
+SBListener::reset(ListenerSP listener_sp)
 {
-    return *m_opaque_ptr;
+    m_opaque_sp = listener_sp;
+    m_unused_ptr = nullptr;
 }
 
 
index 67c3e42..8dc5bb1 100644 (file)
@@ -623,7 +623,7 @@ SBTarget::ConnectRemote
     {
         Mutex::Locker api_locker (target_sp->GetAPIMutex());
         if (listener.IsValid())
-            process_sp = target_sp->CreateProcess (listener.ref(), plugin_name, NULL);
+            process_sp = target_sp->CreateProcess (listener.m_opaque_sp, plugin_name, NULL);
         else
             process_sp = target_sp->CreateProcess (target_sp->GetDebugger().GetListener(), plugin_name, NULL);
 
index 84a42ae..6494e3d 100644 (file)
 // Project includes
 #include "lldb/Core/Log.h"
 #include "lldb/Core/Event.h"
+#include "lldb/Core/Listener.h"
 #include "lldb/Core/StreamString.h"
 
 using namespace lldb;
 using namespace lldb_private;
 
-Broadcaster::Broadcaster (BroadcasterManager *manager, const char *name) :
-    m_broadcaster_name (name),
+Broadcaster::Broadcaster(BroadcasterManagerSP manager_sp, const char *name) :
+    m_broadcaster_sp(new BroadcasterImpl(*this)),
+    m_manager_sp(manager_sp),
+    m_broadcaster_name(name)
+
+{
+}
+
+Broadcaster::BroadcasterImpl::BroadcasterImpl (Broadcaster &broadcaster) :
+    m_broadcaster(broadcaster),
     m_listeners (),
     m_listeners_mutex (Mutex::eMutexTypeRecursive),
     m_hijacking_listeners(),
-    m_hijacking_masks(),
-    m_manager (manager)
+    m_hijacking_masks()
 {
     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
     if (log)
         log->Printf ("%p Broadcaster::Broadcaster(\"%s\")",
-                     static_cast<void*>(this), m_broadcaster_name.AsCString());
+                     static_cast<void*>(this), m_broadcaster.GetBroadcasterName().AsCString());
 }
 
 Broadcaster::~Broadcaster()
@@ -47,14 +55,14 @@ Broadcaster::~Broadcaster()
 void
 Broadcaster::CheckInWithManager ()
 {
-    if (m_manager != nullptr)
+    if (m_manager_sp)
     {
-        m_manager->SignUpListenersForBroadcaster(*this);
+        m_manager_sp->SignUpListenersForBroadcaster(*this);
     }
 }
 
 void
-Broadcaster::Clear()
+Broadcaster::BroadcasterImpl::Clear()
 {
     Mutex::Locker listeners_locker(m_listeners_mutex);
     
@@ -64,19 +72,19 @@ Broadcaster::Clear()
     
     collection::iterator pos, end = m_listeners.end();
     for (pos = m_listeners.begin(); pos != end; ++pos)
-        pos->first->BroadcasterWillDestruct (this);
+        pos->first->BroadcasterWillDestruct (&m_broadcaster);
     
     m_listeners.clear();
 }
 
-const ConstString &
-Broadcaster::GetBroadcasterName ()
+Broadcaster *
+Broadcaster::BroadcasterImpl::GetBroadcaster()
 {
-    return m_broadcaster_name;
+    return &m_broadcaster;
 }
 
 bool
-Broadcaster::GetEventNames (Stream &s, uint32_t event_mask, bool prefix_with_broadcaster_name) const
+Broadcaster::BroadcasterImpl::GetEventNames (Stream &s, uint32_t event_mask, bool prefix_with_broadcaster_name) const
 {
     uint32_t num_names_added = 0;
     if (event_mask && !m_event_names.empty())
@@ -94,7 +102,7 @@ Broadcaster::GetEventNames (Stream &s, uint32_t event_mask, bool prefix_with_bro
 
                     if (prefix_with_broadcaster_name)
                     {
-                        s.PutCString (m_broadcaster_name.GetCString());
+                        s.PutCString (GetBroadcasterName());
                         s.PutChar('.');
                     }
                     s.PutCString(pos->second.c_str());
@@ -107,14 +115,14 @@ Broadcaster::GetEventNames (Stream &s, uint32_t event_mask, bool prefix_with_bro
 }
 
 void
-Broadcaster::AddInitialEventsToListener (Listener *listener, uint32_t requested_events)
+Broadcaster::AddInitialEventsToListener (lldb::ListenerSP listener_sp, uint32_t requested_events)
 {
 }
 
 uint32_t
-Broadcaster::AddListener (Listener* listener, uint32_t event_mask)
+Broadcaster::BroadcasterImpl::AddListener (lldb::ListenerSP listener_sp, uint32_t event_mask)
 {
-    if (listener == nullptr)
+    if (!listener_sp)
         return 0;
 
     Mutex::Locker locker(m_listeners_mutex);
@@ -125,7 +133,7 @@ Broadcaster::AddListener (Listener* listener, uint32_t event_mask)
     uint32_t taken_event_types = 0;
     for (pos = m_listeners.begin(); pos != end; ++pos)
     {
-        if (pos->first == listener)
+        if (pos->first == listener_sp)
             existing_pos = pos;
     // For now don't descriminate on who gets what
     // FIXME: Implement "unique listener for this bit" mask
@@ -142,7 +150,7 @@ Broadcaster::AddListener (Listener* listener, uint32_t event_mask)
         if (existing_pos == end)
         {
             // Grant a new listener the available event bits
-            m_listeners.push_back(std::make_pair(listener, available_event_types));
+            m_listeners.push_back(std::make_pair(listener_sp, available_event_types));
         }
         else
         {
@@ -153,7 +161,7 @@ Broadcaster::AddListener (Listener* listener, uint32_t event_mask)
         // Individual broadcasters decide whether they have outstanding data when a
         // listener attaches, and insert it into the listener with this method.
 
-        AddInitialEventsToListener (listener, available_event_types);
+        m_broadcaster.AddInitialEventsToListener (listener_sp, available_event_types);
     }
 
     // Return the event bits that were granted to the listener
@@ -161,7 +169,7 @@ Broadcaster::AddListener (Listener* listener, uint32_t event_mask)
 }
 
 bool
-Broadcaster::EventTypeHasListeners (uint32_t event_type)
+Broadcaster::BroadcasterImpl::EventTypeHasListeners (uint32_t event_type)
 {
     Mutex::Locker locker (m_listeners_mutex);
     
@@ -181,14 +189,14 @@ Broadcaster::EventTypeHasListeners (uint32_t event_type)
 }
 
 bool
-Broadcaster::RemoveListener (Listener* listener, uint32_t event_mask)
+Broadcaster::BroadcasterImpl::RemoveListener (lldb::ListenerSP listener_sp, uint32_t event_mask)
 {
     Mutex::Locker locker(m_listeners_mutex);
     collection::iterator pos, end = m_listeners.end();
     // See if we already have this listener, and if so, update its mask
     for (pos = m_listeners.begin(); pos != end; ++pos)
     {
-        if (pos->first == listener)
+        if (pos->first == listener_sp)
         {
             // Relinquish all event bits in "event_mask"
             pos->second &= ~event_mask;
@@ -202,38 +210,39 @@ Broadcaster::RemoveListener (Listener* listener, uint32_t event_mask)
 }
 
 void
-Broadcaster::BroadcastEvent (EventSP &event_sp)
+Broadcaster::BroadcasterImpl::BroadcastEvent (EventSP &event_sp)
 {
     return PrivateBroadcastEvent (event_sp, false);
 }
 
 void
-Broadcaster::BroadcastEventIfUnique (EventSP &event_sp)
+Broadcaster::BroadcasterImpl::BroadcastEventIfUnique (EventSP &event_sp)
 {
     return PrivateBroadcastEvent (event_sp, true);
 }
 
 void
-Broadcaster::PrivateBroadcastEvent (EventSP &event_sp, bool unique)
+Broadcaster::BroadcasterImpl::PrivateBroadcastEvent (EventSP &event_sp, bool unique)
 {
     // Can't add a nullptr event...
     if (!event_sp)
         return;
 
     // Update the broadcaster on this event
-    event_sp->SetBroadcaster (this);
+    event_sp->SetBroadcaster (&m_broadcaster);
 
     const uint32_t event_type = event_sp->GetType();
 
     Mutex::Locker event_types_locker(m_listeners_mutex);
 
-    Listener *hijacking_listener = nullptr;
+    ListenerSP hijacking_listener_sp;
+
     if (!m_hijacking_listeners.empty())
     {
         assert (!m_hijacking_masks.empty());
-        hijacking_listener = m_hijacking_listeners.back();
+        hijacking_listener_sp = m_hijacking_listeners.back();
         if ((event_type & m_hijacking_masks.back()) == 0)
-            hijacking_listener = nullptr;
+            hijacking_listener_sp.reset();
     }
 
     Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_EVENTS));
@@ -242,16 +251,16 @@ Broadcaster::PrivateBroadcastEvent (EventSP &event_sp, bool unique)
         StreamString event_description;
         event_sp->Dump  (&event_description);
         log->Printf ("%p Broadcaster(\"%s\")::BroadcastEvent (event_sp = {%s}, unique =%i) hijack = %p",
-                     static_cast<void*>(this), m_broadcaster_name.AsCString(""),
+                     static_cast<void*>(this), GetBroadcasterName(),
                      event_description.GetData(), unique,
-                     static_cast<void*>(hijacking_listener));
+                     static_cast<void*>(hijacking_listener_sp.get()));
     }
 
-    if (hijacking_listener)
+    if (hijacking_listener_sp)
     {
-        if (unique && hijacking_listener->PeekAtNextEventForBroadcasterWithType (this, event_type))
+        if (unique && hijacking_listener_sp->PeekAtNextEventForBroadcasterWithType (&m_broadcaster, event_type))
             return;
-        hijacking_listener->AddEvent (event_sp);
+        hijacking_listener_sp->AddEvent (event_sp);
     }
     else
     {
@@ -264,7 +273,7 @@ Broadcaster::PrivateBroadcastEvent (EventSP &event_sp, bool unique)
             // put the new event on its event queue.
             if (event_type & pos->second)
             {
-                if (unique && pos->first->PeekAtNextEventForBroadcasterWithType (this, event_type))
+                if (unique && pos->first->PeekAtNextEventForBroadcasterWithType (&m_broadcaster, event_type))
                     continue;
                 pos->first->AddEvent (event_sp);
             }
@@ -273,36 +282,36 @@ Broadcaster::PrivateBroadcastEvent (EventSP &event_sp, bool unique)
 }
 
 void
-Broadcaster::BroadcastEvent (uint32_t event_type, EventData *event_data)
+Broadcaster::BroadcasterImpl::BroadcastEvent (uint32_t event_type, EventData *event_data)
 {
     EventSP event_sp (new Event (event_type, event_data));
     PrivateBroadcastEvent (event_sp, false);
 }
 
 void
-Broadcaster::BroadcastEventIfUnique (uint32_t event_type, EventData *event_data)
+Broadcaster::BroadcasterImpl::BroadcastEventIfUnique (uint32_t event_type, EventData *event_data)
 {
     EventSP event_sp (new Event (event_type, event_data));
     PrivateBroadcastEvent (event_sp, true);
 }
 
 bool
-Broadcaster::HijackBroadcaster (Listener *listener, uint32_t event_mask)
+Broadcaster::BroadcasterImpl::HijackBroadcaster (ListenerSP listener_sp, uint32_t event_mask)
 {
     Mutex::Locker event_types_locker(m_listeners_mutex);
 
     Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_EVENTS));
     if (log)
         log->Printf ("%p Broadcaster(\"%s\")::HijackBroadcaster (listener(\"%s\")=%p)",
-                     static_cast<void*>(this), m_broadcaster_name.AsCString(""),
-                     listener->m_name.c_str(), static_cast<void*>(listener));
-    m_hijacking_listeners.push_back(listener);
+                     static_cast<void*>(this), GetBroadcasterName(),
+                     listener_sp->m_name.c_str(), static_cast<void*>(listener_sp.get()));
+    m_hijacking_listeners.push_back(listener_sp);
     m_hijacking_masks.push_back(event_mask);
     return true;
 }
 
 bool
-Broadcaster::IsHijackedForEvent (uint32_t event_mask)
+Broadcaster::BroadcasterImpl::IsHijackedForEvent (uint32_t event_mask)
 {
     Mutex::Locker event_types_locker(m_listeners_mutex);
 
@@ -311,8 +320,21 @@ Broadcaster::IsHijackedForEvent (uint32_t event_mask)
     return false;
 }
 
+const char *
+Broadcaster::BroadcasterImpl::GetHijackingListenerName()
+{
+    if (m_hijacking_listeners.size())
+    {
+        return m_hijacking_listeners.back()->GetName();
+    }
+    else
+    {
+        return nullptr;
+    }
+}
+
 void
-Broadcaster::RestoreBroadcaster ()
+Broadcaster::BroadcasterImpl::RestoreBroadcaster ()
 {
     Mutex::Locker event_types_locker(m_listeners_mutex);
 
@@ -321,11 +343,11 @@ Broadcaster::RestoreBroadcaster ()
         Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_EVENTS));
         if (log)
         {
-            Listener *listener = m_hijacking_listeners.back();
+            ListenerSP listener_sp = m_hijacking_listeners.back();
             log->Printf ("%p Broadcaster(\"%s\")::RestoreBroadcaster (about to pop listener(\"%s\")=%p)",
                          static_cast<void*>(this),
-                         m_broadcaster_name.AsCString(""),
-                         listener->m_name.c_str(), static_cast<void*>(listener));
+                         GetBroadcasterName(),
+                         listener_sp->m_name.c_str(), static_cast<void*>(listener_sp.get()));
         }
         m_hijacking_listeners.pop_back();
     }
@@ -363,8 +385,14 @@ BroadcasterManager::BroadcasterManager() :
 {
 }
 
+lldb::BroadcasterManagerSP
+BroadcasterManager::MakeBroadcasterManager()
+{
+    return BroadcasterManagerSP(new BroadcasterManager());
+}
+
 uint32_t
-BroadcasterManager::RegisterListenerForEvents (Listener &listener, BroadcastEventSpec event_spec)
+BroadcasterManager::RegisterListenerForEvents (ListenerSP listener_sp, BroadcastEventSpec event_spec)
 {
     Mutex::Locker locker(m_manager_mutex);
     
@@ -380,23 +408,23 @@ BroadcasterManager::RegisterListenerForEvents (Listener &listener, BroadcastEven
     
     if (available_bits != 0)
     {
-        m_event_map.insert (event_listener_key (BroadcastEventSpec (event_spec.GetBroadcasterClass(), available_bits), &listener));
-        m_listeners.insert(&listener);
+        m_event_map.insert (event_listener_key (BroadcastEventSpec (event_spec.GetBroadcasterClass(), available_bits), listener_sp));
+        m_listeners.insert(listener_sp);
     }
     
     return available_bits;
 }
 
 bool
-BroadcasterManager::UnregisterListenerForEvents (Listener &listener, BroadcastEventSpec event_spec)
+BroadcasterManager::UnregisterListenerForEvents (ListenerSP listener_sp, BroadcastEventSpec event_spec)
 {
     Mutex::Locker locker(m_manager_mutex);
     bool removed_some = false;
     
-    if (m_listeners.erase(&listener) == 0)
+    if (m_listeners.erase(listener_sp) == 0)
         return false;
     
-    ListenerMatchesAndSharedBits predicate (event_spec, listener);
+    ListenerMatchesAndSharedBits predicate (event_spec, listener_sp);
     std::vector<BroadcastEventSpec> to_be_readded;
     uint32_t event_bits_to_remove = event_spec.GetEventBits();
     
@@ -426,13 +454,13 @@ BroadcasterManager::UnregisterListenerForEvents (Listener &listener, BroadcastEv
     // Okay now add back the bits that weren't completely removed:
     for (size_t i = 0; i < to_be_readded.size(); i++)
     {
-        m_event_map.insert (event_listener_key (to_be_readded[i], &listener));
+        m_event_map.insert (event_listener_key (to_be_readded[i], listener_sp));
     }
     
     return removed_some;
 }
     
-Listener *
+ListenerSP
 BroadcasterManager::GetListenerForEventSpec (BroadcastEventSpec event_spec) const
 {
     Mutex::Locker locker(*(const_cast<Mutex *> (&m_manager_mutex)));
@@ -446,12 +474,34 @@ BroadcasterManager::GetListenerForEventSpec (BroadcastEventSpec event_spec) cons
 }
 
 void
-BroadcasterManager::RemoveListener (Listener &listener)
+BroadcasterManager::RemoveListener(Listener *listener)
+{
+    Mutex::Locker locker(m_manager_mutex);
+    ListenerMatchesPointer predicate (listener);
+    listener_collection::iterator iter = m_listeners.begin(), end_iter = m_listeners.end();
+    
+    std::find_if (iter, end_iter, predicate);
+    if (iter != end_iter)
+        m_listeners.erase(iter);
+    
+    while (true)
+    {
+        collection::iterator iter, end_iter = m_event_map.end();
+        iter = find_if (m_event_map.begin(), end_iter, predicate);
+        if (iter == end_iter)
+            break;
+        else
+            m_event_map.erase(iter);
+    }    
+}
+
+void
+BroadcasterManager::RemoveListener (ListenerSP listener_sp)
 {
     Mutex::Locker locker(m_manager_mutex);
-    ListenerMatches predicate (listener);
+    ListenerMatches predicate (listener_sp);
 
-    if (m_listeners.erase (&listener) == 0)
+    if (m_listeners.erase (listener_sp) == 0)
         return;
         
     while (true)
@@ -487,7 +537,7 @@ BroadcasterManager::Clear ()
     listener_collection::iterator end_iter = m_listeners.end();
     
     for (listener_collection::iterator iter = m_listeners.begin(); iter != end_iter; iter++)
-        (*iter)->BroadcasterManagerWillDestruct(this);
+        (*iter)->BroadcasterManagerWillDestruct(this->shared_from_this());
     m_listeners.clear();
     m_event_map.clear();
 }
index ab2b293..557fb95 100644 (file)
@@ -15,6 +15,7 @@
 // Project includes
 #include "lldb/Core/Communication.h"
 #include "lldb/Core/Connection.h"
+#include "lldb/Core/Listener.h"
 #include "lldb/Core/Log.h"
 #include "lldb/Core/Timer.h"
 #include "lldb/Core/Event.h"
@@ -64,7 +65,7 @@ Communication::~Communication()
 {
     lldb_private::LogIfAnyCategoriesSet (LIBLLDB_LOG_OBJECT | LIBLLDB_LOG_COMMUNICATION,
                                  "%p Communication::~Communication (name = %s)",
-                                 this, m_broadcaster_name.AsCString(""));
+                                 this, GetBroadcasterName().AsCString());
     Clear();
 }
 
@@ -164,10 +165,10 @@ Communication::Read (void *dst, size_t dst_len, uint32_t timeout_usec, Connectio
             timeout_time.OffsetWithMicroSeconds (timeout_usec);
         }
 
-        Listener listener ("Communication::Read");
-        listener.StartListeningForEvents (this, eBroadcastBitReadThreadGotBytes | eBroadcastBitReadThreadDidExit);
+        ListenerSP listener_sp(Listener::MakeListener("Communication::Read"));
+        listener_sp->StartListeningForEvents (this, eBroadcastBitReadThreadGotBytes | eBroadcastBitReadThreadDidExit);
         EventSP event_sp;
-        while (listener.WaitForEvent((timeout_time.IsValid() ? &timeout_time : nullptr), event_sp))
+        while (listener_sp->WaitForEvent (timeout_time.IsValid() ? &timeout_time : nullptr, event_sp))
         {
             const uint32_t event_type = event_sp->GetType();
             if (event_type & eBroadcastBitReadThreadGotBytes)
@@ -234,7 +235,7 @@ Communication::StartReadThread (Error *error_ptr)
                                  "%p Communication::StartReadThread ()", this);
 
     char thread_name[1024];
-    snprintf(thread_name, sizeof(thread_name), "<lldb.comm.%s>", m_broadcaster_name.AsCString());
+    snprintf(thread_name, sizeof(thread_name), "<lldb.comm.%s>", GetBroadcasterName().AsCString());
 
     m_read_thread_enabled = true;
     m_read_thread_did_exit = false;
@@ -427,8 +428,8 @@ Communication::SynchronizeWithReadThread ()
     Mutex::Locker locker(m_synchronize_mutex);
 
     // First start listening for the synchronization event.
-    Listener listener("Communication::SyncronizeWithReadThread");
-    listener.StartListeningForEvents(this, eBroadcastBitNoMorePendingInput);
+    ListenerSP listener_sp(Listener::MakeListener("Communication::SyncronizeWithReadThread"));
+    listener_sp->StartListeningForEvents(this, eBroadcastBitNoMorePendingInput);
 
     // If the thread is not running, there is no point in synchronizing.
     if (!m_read_thread_enabled || m_read_thread_did_exit)
@@ -439,7 +440,7 @@ Communication::SynchronizeWithReadThread ()
 
     // Wait for the synchronization event.
     EventSP event_sp;
-    listener.WaitForEvent(nullptr, event_sp);
+    listener_sp->WaitForEvent(nullptr, event_sp);
 }
 
 void
index f348bb0..57313a4 100644 (file)
@@ -702,10 +702,11 @@ Debugger::Debugger(lldb::LogOutputCallback log_callback, void *baton) :
     m_input_file_sp(new StreamFile(stdin, false)),
     m_output_file_sp(new StreamFile(stdout, false)),
     m_error_file_sp(new StreamFile(stderr, false)),
+    m_broadcaster_manager_sp(BroadcasterManager::MakeBroadcasterManager()),
     m_terminal_state(),
     m_target_list(*this),
     m_platform_list(),
-    m_listener("lldb.Debugger"),
+    m_listener_sp(Listener::MakeListener("lldb.Debugger")),
     m_source_manager_ap(),
     m_source_file_cache(),
     m_command_interpreter_ap(new CommandInterpreter(*this, eScriptLanguageDefault, false)),
@@ -764,7 +765,7 @@ Debugger::Clear()
     ClearIOHandlers();
     StopIOHandlerThread();
     StopEventHandlerThread();
-    m_listener.Clear();
+    m_listener_sp->Clear();
     int num_targets = m_target_list.GetNumTargets();
     for (int i = 0; i < num_targets; i++)
     {
@@ -777,7 +778,7 @@ Debugger::Clear()
             target_sp->Destroy();
         }
     }
-    BroadcasterManager::Clear ();
+    m_broadcaster_manager_sp->Clear ();
     
     // Close the input file _before_ we close the input read communications class
     // as it does NOT own the input file, our m_input_file does.
@@ -1580,7 +1581,7 @@ Debugger::CancelForwardEvents (const ListenerSP &listener_sp)
 void
 Debugger::DefaultEventHandler()
 {
-    Listener& listener(GetListener());
+    ListenerSP listener_sp(GetListener());
     ConstString broadcaster_class_target(Target::GetStaticBroadcasterClass());
     ConstString broadcaster_class_process(Process::GetStaticBroadcasterClass());
     ConstString broadcaster_class_thread(Thread::GetStaticBroadcasterClass());
@@ -1596,10 +1597,10 @@ Debugger::DefaultEventHandler()
                                           Thread::eBroadcastBitStackChanged     |
                                           Thread::eBroadcastBitThreadSelected   );
     
-    listener.StartListeningForEventSpec (*this, target_event_spec);
-    listener.StartListeningForEventSpec (*this, process_event_spec);
-    listener.StartListeningForEventSpec (*this, thread_event_spec);
-    listener.StartListeningForEvents (m_command_interpreter_ap.get(),
+    listener_sp->StartListeningForEventSpec (m_broadcaster_manager_sp, target_event_spec);
+    listener_sp->StartListeningForEventSpec (m_broadcaster_manager_sp, process_event_spec);
+    listener_sp->StartListeningForEventSpec (m_broadcaster_manager_sp, thread_event_spec);
+    listener_sp->StartListeningForEvents (m_command_interpreter_ap.get(),
                                       CommandInterpreter::eBroadcastBitQuitCommandReceived      |
                                       CommandInterpreter::eBroadcastBitAsynchronousOutputData   |
                                       CommandInterpreter::eBroadcastBitAsynchronousErrorData    );
@@ -1612,7 +1613,7 @@ Debugger::DefaultEventHandler()
     while (!done)
     {
         EventSP event_sp;
-        if (listener.WaitForEvent(nullptr, event_sp))
+        if (listener_sp->WaitForEvent(nullptr, event_sp))
         {
             if (event_sp)
             {
@@ -1694,8 +1695,8 @@ Debugger::StartEventHandlerThread()
         // it is up and running and listening to events before we return from
         // this function. We do this by listening to events for the
         // eBroadcastBitEventThreadIsListening from the m_sync_broadcaster
-        Listener listener("lldb.debugger.event-handler");
-        listener.StartListeningForEvents(&m_sync_broadcaster, eBroadcastBitEventThreadIsListening);
+        ListenerSP listener_sp(Listener::MakeListener("lldb.debugger.event-handler"));
+        listener_sp->StartListeningForEvents(&m_sync_broadcaster, eBroadcastBitEventThreadIsListening);
 
         // Use larger 8MB stack for this thread
         m_event_handler_thread = ThreadLauncher::LaunchThread("lldb.debugger.event-handler",
@@ -1709,7 +1710,7 @@ Debugger::StartEventHandlerThread()
         // eBroadcastBitEventThreadIsListening so we don't need to check the event, we just need
         // to wait an infinite amount of time for it (nullptr timeout as the first parameter)
         lldb::EventSP event_sp;
-        listener.WaitForEvent(nullptr, event_sp);
+        listener_sp->WaitForEvent(nullptr, event_sp);
     }
     return m_event_handler_thread.IsJoinable();
 }
index 293a322..8e20063 100644 (file)
@@ -28,14 +28,13 @@ using namespace lldb_private;
 // Event constructor
 //----------------------------------------------------------------------
 Event::Event (Broadcaster *broadcaster, uint32_t event_type, EventData *data) :
-    m_broadcaster (broadcaster),
+    m_broadcaster_wp (broadcaster->GetBroadcasterImpl()),
     m_type (event_type),
     m_data_ap (data)
 {
 }
 
 Event::Event(uint32_t event_type, EventData *data) :
-    m_broadcaster (NULL),   // Set by the broadcaster when this event gets broadcast
     m_type (event_type),
     m_data_ap (data)
 {
@@ -52,20 +51,27 @@ Event::~Event ()
 void
 Event::Dump (Stream *s) const
 {
-    if (m_broadcaster)
+    Broadcaster *broadcaster;
+    Broadcaster::BroadcasterImplSP broadcaster_impl_sp(m_broadcaster_wp.lock());
+    if (broadcaster_impl_sp)
+        broadcaster = broadcaster_impl_sp->GetBroadcaster();
+    else
+        broadcaster = nullptr;
+    
+    if (broadcaster)
     {
         StreamString event_name;
-        if (m_broadcaster->GetEventNames (event_name, m_type, false))
+        if (broadcaster->GetEventNames (event_name, m_type, false))
             s->Printf("%p Event: broadcaster = %p (%s), type = 0x%8.8x (%s), data = ",
                       static_cast<const void*>(this),
-                      static_cast<void*>(m_broadcaster),
-                      m_broadcaster->GetBroadcasterName().GetCString(),
+                      static_cast<void*>(broadcaster),
+                      broadcaster->GetBroadcasterName().GetCString(),
                       m_type, event_name.GetString().c_str());
         else
             s->Printf("%p Event: broadcaster = %p (%s), type = 0x%8.8x, data = ",
                       static_cast<const void*>(this),
-                      static_cast<void*>(m_broadcaster),
-                      m_broadcaster->GetBroadcasterName().GetCString(), m_type);
+                      static_cast<void*>(broadcaster),
+                      broadcaster->GetBroadcasterName().GetCString(), m_type);
     }
     else
         s->Printf("%p Event: broadcaster = NULL, type = 0x%8.8x, data = ",
index 47d00e9..ea5624a 100644 (file)
@@ -2369,7 +2369,7 @@ type summary add -s "${var.origin%S} ${var.size%S}" curses::Rect
             
             halfdelay(delay_in_tenths_of_a_second); // Poll using some number of tenths of seconds seconds when calling Window::GetChar()
 
-            ListenerSP listener_sp (new Listener ("lldb.IOHandler.curses.Application"));
+            ListenerSP listener_sp (Listener::MakeListener("lldb.IOHandler.curses.Application"));
             ConstString broadcaster_class_target(Target::GetStaticBroadcasterClass());
             ConstString broadcaster_class_process(Process::GetStaticBroadcasterClass());
             ConstString broadcaster_class_thread(Thread::GetStaticBroadcasterClass());
index 3447549..d13a203 100644 (file)
 using namespace lldb;
 using namespace lldb_private;
 
+namespace
+{
+    class BroadcasterManagerWPMatcher
+    {
+    public:
+        BroadcasterManagerWPMatcher (BroadcasterManagerSP manager_sp) : m_manager_sp(manager_sp) {}
+        bool operator() (const BroadcasterManagerWP input_wp) const
+        {
+            BroadcasterManagerSP input_sp = input_wp.lock();
+            if (input_sp && input_sp == m_manager_sp)
+                return true;
+            else
+                return false;
+        }
+        BroadcasterManagerSP m_manager_sp;
+    };
+}
+
 Listener::Listener(const char *name) :
     m_name (name),
     m_broadcasters(),
@@ -39,32 +57,40 @@ Listener::Listener(const char *name) :
 
 Listener::~Listener()
 {
-    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
     Mutex::Locker locker (m_broadcasters_mutex);
 
-    size_t num_managers = m_broadcaster_managers.size();
-
-    for (size_t i = 0; i < num_managers; i++)
-        m_broadcaster_managers[i]->RemoveListener(*this);
-
-    if (log)
-        log->Printf ("%p Listener::~Listener('%s')",
-                     static_cast<void*>(this), m_name.c_str());
     Clear();
 }
 
 void
 Listener::Clear()
 {
+    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
     Mutex::Locker locker(m_broadcasters_mutex);
     broadcaster_collection::iterator pos, end = m_broadcasters.end();
     for (pos = m_broadcasters.begin(); pos != end; ++pos)
-        pos->first->RemoveListener (this, pos->second.event_mask);
+    {
+        Broadcaster::BroadcasterImplSP broadcaster_sp(pos->first.lock());
+        if (broadcaster_sp)
+            broadcaster_sp->RemoveListener (this->shared_from_this(), pos->second.event_mask);
+    }
     m_broadcasters.clear();
     m_cond_wait.SetValue (false, eBroadcastNever);
     m_broadcasters.clear();
     Mutex::Locker event_locker(m_events_mutex);
     m_events.clear();
+    size_t num_managers = m_broadcaster_managers.size();
+
+    for (size_t i = 0; i < num_managers; i++)
+    {
+        BroadcasterManagerSP manager_sp(m_broadcaster_managers[i].lock());
+        if (manager_sp)
+            manager_sp->RemoveListener(this);
+    }
+
+    if (log)
+        log->Printf ("%p Listener::~Listener('%s')",
+                     static_cast<void*>(this), m_name.c_str());
 }
 
 uint32_t
@@ -76,10 +102,11 @@ Listener::StartListeningForEvents (Broadcaster* broadcaster, uint32_t event_mask
         // Tell the broadcaster to add this object as a listener
         {
             Mutex::Locker locker(m_broadcasters_mutex);
-            m_broadcasters.insert(std::make_pair(broadcaster, BroadcasterInfo(event_mask)));
+            Broadcaster::BroadcasterImplWP impl_wp(broadcaster->GetBroadcasterImpl());
+            m_broadcasters.insert(std::make_pair(impl_wp, BroadcasterInfo(event_mask)));
         }
 
-        uint32_t acquired_mask = broadcaster->AddListener (this, event_mask);
+        uint32_t acquired_mask = broadcaster->AddListener (this->shared_from_this(), event_mask);
 
         if (event_mask != acquired_mask)
         {
@@ -107,10 +134,12 @@ Listener::StartListeningForEvents (Broadcaster* broadcaster, uint32_t event_mask
         // Tell the broadcaster to add this object as a listener
         {
             Mutex::Locker locker(m_broadcasters_mutex);
-            m_broadcasters.insert(std::make_pair(broadcaster, BroadcasterInfo(event_mask, callback, callback_user_data)));
+            Broadcaster::BroadcasterImplWP impl_wp(broadcaster->GetBroadcasterImpl());
+            m_broadcasters.insert(std::make_pair(impl_wp,
+                                                 BroadcasterInfo(event_mask, callback, callback_user_data)));
         }
 
-        uint32_t acquired_mask = broadcaster->AddListener (this, event_mask);
+        uint32_t acquired_mask = broadcaster->AddListener (this->shared_from_this(), event_mask);
 
         Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EVENTS));
         if (log)
@@ -136,10 +165,10 @@ Listener::StopListeningForEvents (Broadcaster* broadcaster, uint32_t event_mask)
         // Scope for "locker"
         {
             Mutex::Locker locker(m_broadcasters_mutex);
-            m_broadcasters.erase (broadcaster);
+            m_broadcasters.erase (broadcaster->GetBroadcasterImpl());
         }
         // Remove the broadcaster from our set of broadcasters
-        return broadcaster->RemoveListener (this, event_mask);
+        return broadcaster->RemoveListener (this->shared_from_this(), event_mask);
     }
 
     return false;
@@ -153,7 +182,7 @@ Listener::BroadcasterWillDestruct (Broadcaster *broadcaster)
     // Scope for "broadcasters_locker"
     {
         Mutex::Locker broadcasters_locker(m_broadcasters_mutex);
-        m_broadcasters.erase (broadcaster);
+        m_broadcasters.erase (broadcaster->GetBroadcasterImpl());
     }
 
     // Scope for "event_locker"
@@ -176,11 +205,14 @@ Listener::BroadcasterWillDestruct (Broadcaster *broadcaster)
 }
 
 void
-Listener::BroadcasterManagerWillDestruct (BroadcasterManager *manager)
+Listener::BroadcasterManagerWillDestruct (BroadcasterManagerSP manager_sp)
 {
     // Just need to remove this broadcast manager from the list of managers:
     broadcaster_manager_collection::iterator iter, end_iter = m_broadcaster_managers.end();
-    iter = find(m_broadcaster_managers.begin(), end_iter, manager);
+    BroadcasterManagerWP manager_wp;
+
+    BroadcasterManagerWPMatcher matcher(manager_sp);
+    iter = std::find_if<broadcaster_manager_collection::iterator, BroadcasterManagerWPMatcher>(m_broadcaster_managers.begin(), end_iter, matcher);
     if (iter != end_iter)
         m_broadcaster_managers.erase (iter);
 }
@@ -206,7 +238,8 @@ class EventBroadcasterMatches
 {
 public:
     EventBroadcasterMatches (Broadcaster *broadcaster) :
-        m_broadcaster (broadcaster)    {
+        m_broadcaster (broadcaster)
+    {
     }
 
     bool operator() (const EventSP &event_sp) const
@@ -486,39 +519,19 @@ Listener::WaitForEvent (const TimeValue *timeout, EventSP &event_sp)
     return WaitForEventsInternal (timeout, NULL, NULL, 0, 0, event_sp);
 }
 
-//Listener::broadcaster_collection::iterator
-//Listener::FindBroadcasterWithMask (Broadcaster *broadcaster, uint32_t event_mask, bool exact)
-//{
-//    broadcaster_collection::iterator pos;
-//    broadcaster_collection::iterator end = m_broadcasters.end();
-//    for (pos = m_broadcasters.find (broadcaster);
-//        pos != end && pos->first == broadcaster;
-//        ++pos)
-//    {
-//        if (exact)
-//        {
-//            if ((event_mask & pos->second.event_mask) == event_mask)
-//                return pos;
-//        }
-//        else
-//        {
-//            if (event_mask & pos->second.event_mask)
-//                return pos;
-//        }
-//    }
-//    return end;
-//}
-
 size_t
 Listener::HandleBroadcastEvent (EventSP &event_sp)
 {
     size_t num_handled = 0;
     Mutex::Locker locker(m_broadcasters_mutex);
     Broadcaster *broadcaster = event_sp->GetBroadcaster();
+    if (!broadcaster)
+        return 0;
     broadcaster_collection::iterator pos;
     broadcaster_collection::iterator end = m_broadcasters.end();
-    for (pos = m_broadcasters.find (broadcaster);
-        pos != end && pos->first == broadcaster;
+    Broadcaster::BroadcasterImplSP broadcaster_impl_sp(broadcaster->GetBroadcasterImpl());
+    for (pos = m_broadcasters.find (broadcaster_impl_sp);
+        pos != end && pos->first.lock() == broadcaster_impl_sp;
         ++pos)
     {
         BroadcasterInfo info = pos->second;
@@ -535,28 +548,45 @@ Listener::HandleBroadcastEvent (EventSP &event_sp)
 }
 
 uint32_t
-Listener::StartListeningForEventSpec (BroadcasterManager &manager, 
+Listener::StartListeningForEventSpec (BroadcasterManagerSP manager_sp,
                              const BroadcastEventSpec &event_spec)
 {
+    if (!manager_sp)
+        return 0;
+    
     // The BroadcasterManager mutex must be locked before m_broadcasters_mutex 
     // to avoid violating the lock hierarchy (manager before broadcasters).
-    Mutex::Locker manager_locker(manager.m_manager_mutex);
+    Mutex::Locker manager_locker(manager_sp->m_manager_mutex);
     Mutex::Locker locker(m_broadcasters_mutex);
 
-    uint32_t bits_acquired = manager.RegisterListenerForEvents(*this, event_spec);
+    uint32_t bits_acquired = manager_sp->RegisterListenerForEvents(this->shared_from_this(), event_spec);
     if (bits_acquired)
-        m_broadcaster_managers.push_back(&manager);
-        
+    {
+        broadcaster_manager_collection::iterator iter, end_iter = m_broadcaster_managers.end();
+        BroadcasterManagerWP manager_wp(manager_sp);
+        BroadcasterManagerWPMatcher matcher(manager_sp);
+        iter = std::find_if<broadcaster_manager_collection::iterator, BroadcasterManagerWPMatcher>(m_broadcaster_managers.begin(), end_iter, matcher);
+        if (iter == end_iter)
+            m_broadcaster_managers.push_back(manager_wp);
+    }
+    
     return bits_acquired;
 }
     
 bool
-Listener::StopListeningForEventSpec (BroadcasterManager &manager, 
+Listener::StopListeningForEventSpec (BroadcasterManagerSP manager_sp,
                              const BroadcastEventSpec &event_spec)
 {
+    if (!manager_sp)
+        return false;
+    
     Mutex::Locker locker(m_broadcasters_mutex);
-    return manager.UnregisterListenerForEvents (*this, event_spec);
+    return manager_sp->UnregisterListenerForEvents (this->shared_from_this(), event_spec);
 
 }
     
-
+ListenerSP
+Listener::MakeListener(const char *name)
+{
+    return ListenerSP(new Listener(name));
+}
index 5de6177..3a1e187 100644 (file)
@@ -105,7 +105,7 @@ CommandInterpreter::GetStaticBroadcasterClass ()
 }
 
 CommandInterpreter::CommandInterpreter(Debugger &debugger, ScriptLanguage script_language, bool synchronous_execution)
-    : Broadcaster(&debugger, CommandInterpreter::GetStaticBroadcasterClass().AsCString()),
+    : Broadcaster(debugger.GetBroadcasterManager(), CommandInterpreter::GetStaticBroadcasterClass().AsCString()),
       Properties(OptionValuePropertiesSP(new OptionValueProperties(ConstString("interpreter")))),
       IOHandlerDelegate(IOHandlerDelegate::Completion::LLDBCommand),
       m_debugger(debugger),
index f6d843e..92f6ef9 100644 (file)
@@ -670,9 +670,9 @@ PlatformLinux::DebugProcess (ProcessLaunchInfo &launch_info,
         if (log)
             log->Printf ("PlatformLinux::%s setting up hijacker", __FUNCTION__);
 
-        listener_sp.reset (new Listener("lldb.PlatformLinux.DebugProcess.hijack"));
+        listener_sp = Listener::MakeListener("lldb.PlatformLinux.DebugProcess.hijack");
         launch_info.SetHijackListener (listener_sp);
-        process_sp->HijackProcessEvents (listener_sp.get ());
+        process_sp->HijackProcessEvents (listener_sp);
     }
 
     // Log file actions.
@@ -698,7 +698,7 @@ PlatformLinux::DebugProcess (ProcessLaunchInfo &launch_info,
         // Handle the hijacking of process events.
         if (listener_sp)
         {
-            const StateType state = process_sp->WaitForProcessToStop (NULL, NULL, false, listener_sp.get());
+            const StateType state = process_sp->WaitForProcessToStop (NULL, NULL, false, listener_sp);
 
             if (state == eStateStopped)
             {
index 3482b60..031b000 100644 (file)
@@ -799,13 +799,13 @@ PlatformPOSIX::Attach (ProcessAttachInfo &attach_info,
 
             if (process_sp)
             {
-                auto listener_sp = attach_info.GetHijackListener();
+                ListenerSP listener_sp = attach_info.GetHijackListener();
                 if (listener_sp == nullptr)
                 {
-                    listener_sp.reset(new Listener("lldb.PlatformPOSIX.attach.hijack"));
+                    listener_sp = Listener::MakeListener("lldb.PlatformPOSIX.attach.hijack");
                     attach_info.SetHijackListener(listener_sp);
                 }
-                process_sp->HijackProcessEvents(listener_sp.get());
+                process_sp->HijackProcessEvents(listener_sp);
                 error = process_sp->Attach (attach_info);
             }
         }
index a0ff837..cef5684 100644 (file)
@@ -565,7 +565,7 @@ PlatformWindows::Attach(ProcessAttachInfo &attach_info,
     const char *plugin_name = attach_info.GetProcessPluginName();
     process_sp = target->CreateProcess(attach_info.GetListenerForProcess(debugger), plugin_name, nullptr);
 
-    process_sp->HijackProcessEvents(attach_info.GetHijackListener().get());
+    process_sp->HijackProcessEvents(attach_info.GetHijackListener());
     if (process_sp)
         error = process_sp->Attach (attach_info);
 
index f16ea01..cecc96c 100644 (file)
@@ -714,9 +714,9 @@ PlatformRemoteGDBServer::Attach (ProcessAttachInfo &attach_info,
                         error = process_sp->ConnectRemote(nullptr, connect_url.c_str());
                         if (error.Success())
                         {
-                            auto listener = attach_info.GetHijackListener();
-                            if (listener != nullptr)
-                                process_sp->HijackProcessEvents(listener.get());
+                            ListenerSP listener_sp = attach_info.GetHijackListener();
+                            if (listener_sp)
+                                process_sp->HijackProcessEvents(listener_sp);
                             error = process_sp->Attach(attach_info);
                         }
 
index 769ccd7..69b527a 100644 (file)
@@ -63,12 +63,12 @@ namespace
 
 lldb::ProcessSP
 ProcessFreeBSD::CreateInstance(lldb::TargetSP target_sp,
-                               Listener &listener,
+                               lldb::ListenerSP listener_sp,
                                const FileSpec *crash_file_path)
 {
     lldb::ProcessSP process_sp;
     if (crash_file_path == NULL)
-        process_sp.reset(new ProcessFreeBSD (target_sp, listener, GetFreeBSDSignals()));
+        process_sp.reset(new ProcessFreeBSD (target_sp, listener_sp, GetFreeBSDSignals()));
     return process_sp;
 }
 
@@ -269,8 +269,8 @@ ProcessFreeBSD::SendMessage(const ProcessMessage &message)
 //------------------------------------------------------------------------------
 // Constructors and destructors.
 
-ProcessFreeBSD::ProcessFreeBSD(lldb::TargetSP target_sp, Listener &listener, UnixSignalsSP &unix_signals_sp)
-    : Process(target_sp, listener, unix_signals_sp),
+ProcessFreeBSD::ProcessFreeBSD(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp, UnixSignalsSP &unix_signals_sp)
+    : Process(target_sp, listener_sp, unix_signals_sp),
       m_byte_order(endian::InlHostByteOrder()),
       m_monitor(NULL),
       m_module(NULL),
index 5f93654..a1d255c 100644 (file)
@@ -35,7 +35,7 @@ public:
     //------------------------------------------------------------------
     static lldb::ProcessSP
     CreateInstance(lldb::TargetSP target_sp,
-                   lldb_private::Listener &listener,
+                   lldb::ListenerSP listener_sp,
                    const lldb_private::FileSpec *crash_file_path);
 
     static void
@@ -54,7 +54,7 @@ public:
     // Constructors and destructors
     //------------------------------------------------------------------
     ProcessFreeBSD(lldb::TargetSP target_sp,
-                   lldb_private::Listener &listener,
+                   lldb::ListenerSP listener_sp,
                    lldb::UnixSignalsSP &unix_signals_sp);
 
     ~ProcessFreeBSD();
index 628f76d..f99bb2c 100644 (file)
@@ -132,12 +132,12 @@ ProcessKDP::Terminate()
 
 lldb::ProcessSP
 ProcessKDP::CreateInstance (TargetSP target_sp,
-                            Listener &listener,
+                            ListenerSP listener_sp,
                             const FileSpec *crash_file_path)
 {
     lldb::ProcessSP process_sp;
     if (crash_file_path == NULL)
-        process_sp.reset(new ProcessKDP (target_sp, listener));
+        process_sp.reset(new ProcessKDP (target_sp, listener_sp));
     return process_sp;
 }
 
@@ -178,8 +178,8 @@ ProcessKDP::CanDebug(TargetSP target_sp, bool plugin_specified_by_name)
 //----------------------------------------------------------------------
 // ProcessKDP constructor
 //----------------------------------------------------------------------
-ProcessKDP::ProcessKDP(TargetSP target_sp, Listener &listener) :
-    Process (target_sp, listener),
+ProcessKDP::ProcessKDP(TargetSP target_sp, ListenerSP listener_sp) :
+    Process (target_sp, listener_sp),
     m_comm("lldb.process.kdp-remote.communication"),
     m_async_broadcaster (NULL, "lldb.process.kdp-remote.async-broadcaster"),
     m_dyld_plugin_name (),
@@ -927,13 +927,13 @@ ProcessKDP::AsyncThread (void *arg)
     if (log)
         log->Printf ("ProcessKDP::AsyncThread (arg = %p, pid = %" PRIu64 ") thread starting...", arg, pid);
     
-    Listener listener ("ProcessKDP::AsyncThread");
+    ListenerSP listener_sp (Listener::MakeListener("ProcessKDP::AsyncThread"));
     EventSP event_sp;
     const uint32_t desired_event_mask = eBroadcastBitAsyncContinue |
                                         eBroadcastBitAsyncThreadShouldExit;
     
     
-    if (listener.StartListeningForEvents (&process->m_async_broadcaster, desired_event_mask) == desired_event_mask)
+    if (listener_sp->StartListeningForEvents (&process->m_async_broadcaster, desired_event_mask) == desired_event_mask)
     {
         bool done = false;
         while (!done)
@@ -941,7 +941,7 @@ ProcessKDP::AsyncThread (void *arg)
             if (log)
                 log->Printf ("ProcessKDP::AsyncThread (pid = %" PRIu64 ") listener.WaitForEvent (NULL, event_sp)...",
                              pid);
-            if (listener.WaitForEvent (NULL, event_sp))
+            if (listener_sp->WaitForEvent (NULL, event_sp))
             {
                 uint32_t event_type = event_sp->GetType();
                 if (log)
@@ -981,7 +981,7 @@ ProcessKDP::AsyncThread (void *arg)
                                 // Check to see if we are supposed to exit. There is no way to
                                 // interrupt a running kernel, so all we can do is wait for an
                                 // exception or detach...
-                                if (listener.GetNextEvent(event_sp))
+                                if (listener_sp->GetNextEvent(event_sp))
                                 {
                                     // We got an event, go through the loop again
                                     event_type = event_sp->GetType();
index fe9a4e2..49f6362 100644 (file)
@@ -40,7 +40,7 @@ public:
     //------------------------------------------------------------------
     static lldb::ProcessSP
     CreateInstance (lldb::TargetSP target_sp,
-                    lldb_private::Listener &listener,
+                    lldb::ListenerSP listener_sp,
                     const lldb_private::FileSpec *crash_file_path);
     
     static void
@@ -61,7 +61,7 @@ public:
     //------------------------------------------------------------------
     // Constructors and Destructors
     //------------------------------------------------------------------
-    ProcessKDP(lldb::TargetSP target_sp, lldb_private::Listener &listener);
+    ProcessKDP(lldb::TargetSP target_sp, lldb::ListenerSP listener);
     
     virtual
     ~ProcessKDP();
index 0e6900d..2c3f9fb 100644 (file)
@@ -29,8 +29,8 @@ namespace lldb_private
 //------------------------------------------------------------------------------
 // Constructors and destructors.
 
-ProcessWindows::ProcessWindows(lldb::TargetSP target_sp, Listener &listener)
-    : lldb_private::Process(target_sp, listener)
+ProcessWindows::ProcessWindows(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp)
+    : lldb_private::Process(target_sp, listener_sp)
 {
 }
 
index 2a437c0..0ee42e2 100644 (file)
@@ -25,7 +25,7 @@ public:
     // Constructors and destructors
     //------------------------------------------------------------------
     ProcessWindows(lldb::TargetSP target_sp,
-                   lldb_private::Listener &listener);
+                   lldb::ListenerSP listener_sp);
 
     ~ProcessWindows();
 
index 45ef836..9516040 100644 (file)
@@ -121,9 +121,9 @@ class ProcessWindowsData
 // Static functions.
 
 ProcessSP
-ProcessWindowsLive::CreateInstance(lldb::TargetSP target_sp, Listener &listener, const FileSpec *)
+ProcessWindowsLive::CreateInstance(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp, const FileSpec *)
 {
-    return ProcessSP(new ProcessWindowsLive(target_sp, listener));
+    return ProcessSP(new ProcessWindowsLive(target_sp, listener_sp));
 }
 
 void
@@ -142,8 +142,8 @@ ProcessWindowsLive::Initialize()
 //------------------------------------------------------------------------------
 // Constructors and destructors.
 
-ProcessWindowsLive::ProcessWindowsLive(lldb::TargetSP target_sp, Listener &listener)
-    : lldb_private::ProcessWindows(target_sp, listener)
+ProcessWindowsLive::ProcessWindowsLive(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp)
+    : lldb_private::ProcessWindows(target_sp, listener_sp)
 {
 }
 
index 2429f87..657877f 100644 (file)
@@ -43,7 +43,7 @@ public:
     //------------------------------------------------------------------
     static lldb::ProcessSP
     CreateInstance(lldb::TargetSP target_sp,
-                   lldb_private::Listener &listener,
+                   lldb::ListenerSP listener_sp,
                    const lldb_private::FileSpec *);
 
     static void
@@ -62,7 +62,7 @@ public:
     // Constructors and destructors
     //------------------------------------------------------------------
     ProcessWindowsLive(lldb::TargetSP target_sp,
-                       lldb_private::Listener &listener);
+                       lldb::ListenerSP listener_sp);
 
     ~ProcessWindowsLive();
 
index 1343886..c39f77f 100644 (file)
@@ -538,7 +538,7 @@ ProcessWinMiniDump::Terminate()
 }
 
 lldb::ProcessSP
-ProcessWinMiniDump::CreateInstance(lldb::TargetSP target_sp, Listener &listener, const FileSpec *crash_file)
+ProcessWinMiniDump::CreateInstance(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp, const FileSpec *crash_file)
 {
     lldb::ProcessSP process_sp;
     if (crash_file)
@@ -555,8 +555,8 @@ ProcessWinMiniDump::CanDebug(lldb::TargetSP target_sp, bool plugin_specified_by_
     return true;
 }
 
-ProcessWinMiniDump::ProcessWinMiniDump(lldb::TargetSP target_sp, Listener &listener, const FileSpec &core_file)
-    : ProcessWindows(target_sp, listener), m_impl_up(new Impl(core_file, this))
+ProcessWinMiniDump::ProcessWinMiniDump(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp, const FileSpec &core_file)
+    : ProcessWindows(target_sp, listener_sp), m_impl_up(new Impl(core_file, this))
 {
 }
 
index 4239115..3e1ac4b 100644 (file)
@@ -26,7 +26,7 @@ class ProcessWinMiniDump : public lldb_private::ProcessWindows
   public:
     static lldb::ProcessSP
     CreateInstance (lldb::TargetSP target_sp,
-                    lldb_private::Listener &listener,
+                    lldb::ListenerSP listener_sp,
                     const lldb_private::FileSpec *crash_file_path);
 
     static void
@@ -42,7 +42,7 @@ class ProcessWinMiniDump : public lldb_private::ProcessWindows
     GetPluginDescriptionStatic();
 
     ProcessWinMiniDump(lldb::TargetSP target_sp,
-                       lldb_private::Listener &listener,
+                       lldb::ListenerSP listener_sp,
                        const lldb_private::FileSpec &core_file);
 
     virtual
index a2f73ec..db56cc3 100644 (file)
@@ -57,7 +57,7 @@ ProcessElfCore::Terminate()
 
 
 lldb::ProcessSP
-ProcessElfCore::CreateInstance (lldb::TargetSP target_sp, Listener &listener, const FileSpec *crash_file)
+ProcessElfCore::CreateInstance (lldb::TargetSP target_sp, lldb::ListenerSP listener_sp, const FileSpec *crash_file)
 {
     lldb::ProcessSP process_sp;
     if (crash_file)
@@ -75,7 +75,7 @@ ProcessElfCore::CreateInstance (lldb::TargetSP target_sp, Listener &listener, co
             if (elf_header.Parse(data, &data_offset))
             {
                 if (elf_header.e_type == llvm::ELF::ET_CORE)
-                    process_sp.reset(new ProcessElfCore (target_sp, listener, *crash_file));
+                    process_sp.reset(new ProcessElfCore (target_sp, listener_sp, *crash_file));
             }
         }
     }
@@ -104,9 +104,9 @@ ProcessElfCore::CanDebug(lldb::TargetSP target_sp, bool plugin_specified_by_name
 //----------------------------------------------------------------------
 // ProcessElfCore constructor
 //----------------------------------------------------------------------
-ProcessElfCore::ProcessElfCore(lldb::TargetSP target_sp, Listener &listener,
+ProcessElfCore::ProcessElfCore(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp,
                                const FileSpec &core_file) :
-    Process (target_sp, listener),
+    Process (target_sp, listener_sp),
     m_core_module_sp (),
     m_core_file (core_file),
     m_dyld_plugin_name (),
index 12ce04c..48220f4 100644 (file)
@@ -40,7 +40,7 @@ public:
     //------------------------------------------------------------------
     static lldb::ProcessSP
     CreateInstance (lldb::TargetSP target_sp,
-                    lldb_private::Listener &listener,
+                    lldb::ListenerSP listener_sp,
                     const lldb_private::FileSpec *crash_file_path);
 
     static void
@@ -59,7 +59,7 @@ public:
     // Constructors and Destructors
     //------------------------------------------------------------------
     ProcessElfCore(lldb::TargetSP target_sp,
-                   lldb_private::Listener &listener,
+                   lldb::ListenerSP listener_sp,
                    const lldb_private::FileSpec &core_file);
 
     ~ProcessElfCore() override;
index da04d48..e61999d 100644 (file)
@@ -786,8 +786,8 @@ GDBRemoteCommunicationClient::SendPacketAndWaitForResponse
 
     // In order to stop async notifications from being processed in the middle of the
     // send/receive sequence Hijack the broadcast. Then rebroadcast any events when we are done.
-    static Listener hijack_listener("lldb.NotifyHijacker");
-    HijackBroadcaster(&hijack_listener, eBroadcastBitGdbReadThreadGotNotify);    
+    static ListenerSP hijack_listener_sp(Listener::MakeListener("lldb.NotifyHijacker"));
+    HijackBroadcaster(hijack_listener_sp, eBroadcastBitGdbReadThreadGotNotify);
 
     if (GetSequenceMutex (locker))
     {
@@ -886,7 +886,7 @@ GDBRemoteCommunicationClient::SendPacketAndWaitForResponse
 
     // If a notification event occurred, rebroadcast since it can now be processed safely.
     EventSP event_sp;
-    if (hijack_listener.GetNextEvent(event_sp))
+    if (hijack_listener_sp->GetNextEvent(event_sp))
         BroadcastEvent(event_sp);
 
     return packet_result;
index 6b0637a..e666b85 100644 (file)
@@ -223,11 +223,11 @@ ProcessGDBRemote::Terminate()
 
 
 lldb::ProcessSP
-ProcessGDBRemote::CreateInstance (lldb::TargetSP target_sp, Listener &listener, const FileSpec *crash_file_path)
+ProcessGDBRemote::CreateInstance (lldb::TargetSP target_sp, ListenerSP listener_sp, const FileSpec *crash_file_path)
 {
     lldb::ProcessSP process_sp;
     if (crash_file_path == NULL)
-        process_sp.reset (new ProcessGDBRemote (target_sp, listener));
+        process_sp.reset (new ProcessGDBRemote (target_sp, listener_sp));
     return process_sp;
 }
 
@@ -267,15 +267,15 @@ ProcessGDBRemote::CanDebug (lldb::TargetSP target_sp, bool plugin_specified_by_n
 //----------------------------------------------------------------------
 // ProcessGDBRemote constructor
 //----------------------------------------------------------------------
-ProcessGDBRemote::ProcessGDBRemote(lldb::TargetSP target_sp, Listener &listener) :
-    Process (target_sp, listener),
+ProcessGDBRemote::ProcessGDBRemote(lldb::TargetSP target_sp, ListenerSP listener_sp) :
+    Process (target_sp, listener_sp),
     m_flags (0),
     m_gdb_comm (),
     m_debugserver_pid (LLDB_INVALID_PROCESS_ID),
     m_last_stop_packet_mutex (Mutex::eMutexTypeRecursive),
     m_register_info (),
     m_async_broadcaster (NULL, "lldb.process.gdb-remote.async-broadcaster"),
-    m_async_listener("lldb.process.gdb-remote.async-listener"),
+    m_async_listener_sp(Listener::MakeListener("lldb.process.gdb-remote.async-listener")),
     m_async_thread_state_mutex(Mutex::eMutexTypeRecursive),
     m_thread_ids (),
     m_thread_pcs (),
@@ -303,7 +303,7 @@ ProcessGDBRemote::ProcessGDBRemote(lldb::TargetSP target_sp, Listener &listener)
 
     const uint32_t async_event_mask = eBroadcastBitAsyncContinue | eBroadcastBitAsyncThreadShouldExit;
 
-    if (m_async_listener.StartListeningForEvents(&m_async_broadcaster, async_event_mask) != async_event_mask)
+    if (m_async_listener_sp->StartListeningForEvents(&m_async_broadcaster, async_event_mask) != async_event_mask)
     {
         if (log)
             log->Printf("ProcessGDBRemote::%s failed to listen for m_async_broadcaster events", __FUNCTION__);
@@ -311,7 +311,7 @@ ProcessGDBRemote::ProcessGDBRemote(lldb::TargetSP target_sp, Listener &listener)
 
     const uint32_t gdb_event_mask = Communication::eBroadcastBitReadThreadDidExit |
                                     GDBRemoteCommunication::eBroadcastBitGdbReadThreadGotNotify;
-    if (m_async_listener.StartListeningForEvents(&m_gdb_comm, gdb_event_mask) != gdb_event_mask)
+    if (m_async_listener_sp->StartListeningForEvents(&m_gdb_comm, gdb_event_mask) != gdb_event_mask)
     {
         if (log)
             log->Printf("ProcessGDBRemote::%s failed to listen for m_gdb_comm events", __FUNCTION__);
@@ -1368,10 +1368,10 @@ ProcessGDBRemote::DoResume ()
     if (log)
         log->Printf ("ProcessGDBRemote::Resume()");
 
-    Listener listener ("gdb-remote.resume-packet-sent");
-    if (listener.StartListeningForEvents (&m_gdb_comm, GDBRemoteCommunication::eBroadcastBitRunPacketSent))
+    ListenerSP listener_sp (Listener::MakeListener("gdb-remote.resume-packet-sent"));
+    if (listener_sp->StartListeningForEvents (&m_gdb_comm, GDBRemoteCommunication::eBroadcastBitRunPacketSent))
     {
-        listener.StartListeningForEvents (&m_async_broadcaster, ProcessGDBRemote::eBroadcastBitAsyncThreadDidExit);
+        listener_sp->StartListeningForEvents (&m_async_broadcaster, ProcessGDBRemote::eBroadcastBitAsyncThreadDidExit);
 
         const size_t num_threads = GetThreadList().GetSize();
 
@@ -1603,7 +1603,7 @@ ProcessGDBRemote::DoResume ()
 
             m_async_broadcaster.BroadcastEvent (eBroadcastBitAsyncContinue, new EventDataBytes (continue_packet.GetData(), continue_packet.GetSize()));
 
-            if (listener.WaitForEvent (&timeout, event_sp) == false)
+            if (listener_sp->WaitForEvent (&timeout, event_sp) == false)
             {
                 error.SetErrorString("Resume timed out.");
                 if (log)
@@ -3855,7 +3855,7 @@ ProcessGDBRemote::AsyncThread (void *arg)
     {
         if (log)
             log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64 ") listener.WaitForEvent (NULL, event_sp)...", __FUNCTION__, arg, process->GetID());
-        if (process->m_async_listener.WaitForEvent (NULL, event_sp))
+        if (process->m_async_listener_sp->WaitForEvent (NULL, event_sp))
         {
             const uint32_t event_type = event_sp->GetType();
             if (event_sp->BroadcasterIs (&process->m_async_broadcaster))
index 70633e7..5f02822 100644 (file)
@@ -45,13 +45,13 @@ class ThreadGDBRemote;
 class ProcessGDBRemote : public Process
 {
 public:
-    ProcessGDBRemote(lldb::TargetSP target_sp, Listener &listener);
+    ProcessGDBRemote(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp);
 
     ~ProcessGDBRemote() override;
 
     static lldb::ProcessSP
     CreateInstance (lldb::TargetSP target_sp,
-                    Listener &listener,
+                    lldb::ListenerSP listener_sp,
                     const FileSpec *crash_file_path);
 
     static void
@@ -282,7 +282,7 @@ protected:
     Mutex m_last_stop_packet_mutex;
     GDBRemoteDynamicRegisterInfo m_register_info;
     Broadcaster m_async_broadcaster;
-    Listener m_async_listener;
+    lldb::ListenerSP m_async_listener_sp;
     HostThread m_async_thread;
     Mutex m_async_thread_state_mutex;
     typedef std::vector<lldb::tid_t> tid_collection;
index 43b7418..69006b2 100644 (file)
@@ -65,7 +65,7 @@ ProcessMachCore::Terminate()
 
 
 lldb::ProcessSP
-ProcessMachCore::CreateInstance (lldb::TargetSP target_sp, Listener &listener, const FileSpec *crash_file)
+ProcessMachCore::CreateInstance (lldb::TargetSP target_sp, ListenerSP listener_sp, const FileSpec *crash_file)
 {
     lldb::ProcessSP process_sp;
     if (crash_file)
@@ -81,7 +81,7 @@ ProcessMachCore::CreateInstance (lldb::TargetSP target_sp, Listener &listener, c
             if (ObjectFileMachO::ParseHeader(data, &data_offset, mach_header))
             {
                 if (mach_header.filetype == llvm::MachO::MH_CORE)
-                    process_sp.reset(new ProcessMachCore (target_sp, listener, *crash_file));
+                    process_sp.reset(new ProcessMachCore (target_sp, listener_sp, *crash_file));
             }
         }
         
@@ -122,8 +122,8 @@ ProcessMachCore::CanDebug(lldb::TargetSP target_sp, bool plugin_specified_by_nam
 //----------------------------------------------------------------------
 // ProcessMachCore constructor
 //----------------------------------------------------------------------
-ProcessMachCore::ProcessMachCore(lldb::TargetSP target_sp, Listener &listener, const FileSpec &core_file) :
-    Process (target_sp, listener),
+ProcessMachCore::ProcessMachCore(lldb::TargetSP target_sp, ListenerSP listener_sp, const FileSpec &core_file) :
+    Process (target_sp, listener_sp),
     m_core_aranges (),
     m_core_module_sp (),
     m_core_file (core_file),
index 2de0b77..7b5b6ad 100644 (file)
@@ -30,14 +30,14 @@ public:
     // Constructors and Destructors
     //------------------------------------------------------------------
     ProcessMachCore(lldb::TargetSP target_sp, 
-                    lldb_private::Listener &listener,
+                    lldb::ListenerSP listener,
                     const lldb_private::FileSpec &core_file);
     
     ~ProcessMachCore() override;
     
     static lldb::ProcessSP
     CreateInstance (lldb::TargetSP target_sp, 
-                    lldb_private::Listener &listener, 
+                    lldb::ListenerSP listener,
                     const lldb_private::FileSpec *crash_file_path);
     
     static void
index f9befad..d138d4a 100644 (file)
@@ -657,7 +657,7 @@ ProcessInstanceInfoMatch::Clear()
 }
 
 ProcessSP
-Process::FindPlugin (lldb::TargetSP target_sp, const char *plugin_name, Listener &listener, const FileSpec *crash_file_path)
+Process::FindPlugin (lldb::TargetSP target_sp, const char *plugin_name, ListenerSP listener_sp, const FileSpec *crash_file_path)
 {
     static uint32_t g_process_unique_id = 0;
 
@@ -669,7 +669,7 @@ Process::FindPlugin (lldb::TargetSP target_sp, const char *plugin_name, Listener
         create_callback  = PluginManager::GetProcessCreateCallbackForPluginName (const_plugin_name);
         if (create_callback)
         {
-            process_sp = create_callback(target_sp, listener, crash_file_path);
+            process_sp = create_callback(target_sp, listener_sp, crash_file_path);
             if (process_sp)
             {
                 if (process_sp->CanDebug(target_sp, true))
@@ -685,7 +685,7 @@ Process::FindPlugin (lldb::TargetSP target_sp, const char *plugin_name, Listener
     {
         for (uint32_t idx = 0; (create_callback = PluginManager::GetProcessCreateCallbackAtIndex(idx)) != nullptr; ++idx)
         {
-            process_sp = create_callback(target_sp, listener, crash_file_path);
+            process_sp = create_callback(target_sp, listener_sp, crash_file_path);
             if (process_sp)
             {
                 if (process_sp->CanDebug(target_sp, false))
@@ -708,23 +708,23 @@ Process::GetStaticBroadcasterClass ()
     return class_name;
 }
 
-Process::Process(lldb::TargetSP target_sp, Listener &listener) :
-    Process(target_sp, listener, UnixSignals::Create(HostInfo::GetArchitecture()))
+Process::Process(lldb::TargetSP target_sp, ListenerSP listener_sp) :
+    Process(target_sp, listener_sp, UnixSignals::Create(HostInfo::GetArchitecture()))
 {
     // This constructor just delegates to the full Process constructor,
     // defaulting to using the Host's UnixSignals.
 }
 
-Process::Process(lldb::TargetSP target_sp, Listener &listener, const UnixSignalsSP &unix_signals_sp) :
+Process::Process(lldb::TargetSP target_sp, ListenerSP listener_sp, const UnixSignalsSP &unix_signals_sp) :
     ProcessProperties (this),
     UserID (LLDB_INVALID_PROCESS_ID),
-    Broadcaster (&(target_sp->GetDebugger()), Process::GetStaticBroadcasterClass().AsCString()),
+    Broadcaster ((target_sp->GetDebugger().GetBroadcasterManager()), Process::GetStaticBroadcasterClass().AsCString()),
     m_target_sp (target_sp),
     m_public_state (eStateUnloaded),
     m_private_state (eStateUnloaded),
     m_private_state_broadcaster(nullptr, "lldb.process.internal_state_broadcaster"),
     m_private_state_control_broadcaster(nullptr, "lldb.process.internal_state_control_broadcaster"),
-    m_private_state_listener ("lldb.process.internal_state_listener"),
+    m_private_state_listener_sp (Listener::MakeListener("lldb.process.internal_state_listener")),
     m_private_state_control_wait(),
     m_mod_id (),
     m_process_unique_id(0),
@@ -742,7 +742,7 @@ Process::Process(lldb::TargetSP target_sp, Listener &listener, const UnixSignals
     m_queue_list_stop_id (0),
     m_notifications (),
     m_image_tokens (),
-    m_listener (listener),
+    m_listener_sp (listener_sp),
     m_breakpoint_site_list (),
     m_dynamic_checkers_ap (),
     m_unix_signals_sp (unix_signals_sp),
@@ -792,18 +792,18 @@ Process::Process(lldb::TargetSP target_sp, Listener &listener, const UnixSignals
     m_private_state_control_broadcaster.SetEventName (eBroadcastInternalStateControlPause , "control-pause" );
     m_private_state_control_broadcaster.SetEventName (eBroadcastInternalStateControlResume, "control-resume");
 
-    listener.StartListeningForEvents (this,
+    m_listener_sp->StartListeningForEvents (this,
                                       eBroadcastBitStateChanged |
                                       eBroadcastBitInterrupt |
                                       eBroadcastBitSTDOUT |
                                       eBroadcastBitSTDERR |
                                       eBroadcastBitProfileData);
 
-    m_private_state_listener.StartListeningForEvents(&m_private_state_broadcaster,
+    m_private_state_listener_sp->StartListeningForEvents(&m_private_state_broadcaster,
                                                      eBroadcastBitStateChanged |
                                                      eBroadcastBitInterrupt);
 
-    m_private_state_listener.StartListeningForEvents(&m_private_state_control_broadcaster,
+    m_private_state_listener_sp->StartListeningForEvents(&m_private_state_control_broadcaster,
                                                      eBroadcastInternalStateControlStop |
                                                      eBroadcastInternalStateControlPause |
                                                      eBroadcastInternalStateControlResume);
@@ -904,7 +904,7 @@ Process::Finalize()
 //#ifdef LLDB_CONFIGURATION_DEBUG
 //    StreamFile s(stdout, false);
 //    EventSP event_sp;
-//    while (m_private_state_listener.GetNextEvent(event_sp))
+//    while (m_private_state_listener_sp->GetNextEvent(event_sp))
 //    {
 //        event_sp->Dump (&s);
 //        s.EOL();
@@ -913,7 +913,7 @@ Process::Finalize()
     // We have to be very careful here as the m_private_state_listener might
     // contain events that have ProcessSP values in them which can keep this
     // process around forever. These events need to be cleared out.
-    m_private_state_listener.Clear();
+    m_private_state_listener_sp->Clear();
     m_public_run_lock.TrySetRunning(); // This will do nothing if already locked
     m_public_run_lock.SetStopped();
     m_private_run_lock.TrySetRunning(); // This will do nothing if already locked
@@ -970,7 +970,7 @@ Process::GetNextEvent (EventSP &event_sp)
 {
     StateType state = eStateInvalid;
 
-    if (m_listener.GetNextEventForBroadcaster (this, event_sp) && event_sp)
+    if (m_listener_sp->GetNextEventForBroadcaster (this, event_sp) && event_sp)
         state = Process::ProcessEventData::GetStateFromEvent (event_sp.get());
 
     return state;
@@ -997,7 +997,7 @@ StateType
 Process::WaitForProcessToStop (const TimeValue *timeout,
                                EventSP *event_sp_ptr,
                                bool wait_always,
-                               Listener *hijack_listener,
+                               ListenerSP hijack_listener_sp,
                                Stream *stream,
                                bool use_run_lock)
 {
@@ -1026,7 +1026,7 @@ Process::WaitForProcessToStop (const TimeValue *timeout,
                         __FUNCTION__);
         // We need to toggle the run lock as this won't get done in
         // SetPublicState() if the process is hijacked.
-        if (hijack_listener && use_run_lock)
+        if (hijack_listener_sp && use_run_lock)
             m_public_run_lock.SetStopped();
         return state;
     }
@@ -1034,11 +1034,11 @@ Process::WaitForProcessToStop (const TimeValue *timeout,
     while (state != eStateInvalid)
     {
         EventSP event_sp;
-        state = WaitForStateChangedEvents (timeout, event_sp, hijack_listener);
+        state = WaitForStateChangedEvents (timeout, event_sp, hijack_listener_sp);
         if (event_sp_ptr && event_sp)
             *event_sp_ptr = event_sp;
 
-        bool pop_process_io_handler = hijack_listener != nullptr;
+        bool pop_process_io_handler = (hijack_listener_sp.get() != nullptr);
         Process::HandleProcessStateChangedEvent (event_sp, stream, pop_process_io_handler);
 
         switch (state)
@@ -1049,7 +1049,7 @@ Process::WaitForProcessToStop (const TimeValue *timeout,
         case eStateUnloaded:
             // We need to toggle the run lock as this won't get done in
             // SetPublicState() if the process is hijacked.
-            if (hijack_listener && use_run_lock)
+            if (hijack_listener_sp && use_run_lock)
                 m_public_run_lock.SetStopped();
             return state;
         case eStateStopped:
@@ -1059,7 +1059,7 @@ Process::WaitForProcessToStop (const TimeValue *timeout,
             {
                 // We need to toggle the run lock as this won't get done in
                 // SetPublicState() if the process is hijacked.
-                if (hijack_listener && use_run_lock)
+                if (hijack_listener_sp && use_run_lock)
                     m_public_run_lock.SetStopped();
                 return state;
             }
@@ -1295,11 +1295,11 @@ Process::WaitForState(const TimeValue *timeout,
 }
 
 bool
-Process::HijackProcessEvents (Listener *listener)
+Process::HijackProcessEvents (ListenerSP listener_sp)
 {
-    if (listener != nullptr)
+    if (listener_sp)
     {
-        return HijackBroadcaster(listener, eBroadcastBitStateChanged | eBroadcastBitInterrupt);
+        return HijackBroadcaster(listener_sp, eBroadcastBitStateChanged | eBroadcastBitInterrupt);
     }
     else
         return false;
@@ -1312,7 +1312,7 @@ Process::RestoreProcessEvents ()
 }
 
 StateType
-Process::WaitForStateChangedEvents (const TimeValue *timeout, EventSP &event_sp, Listener *hijack_listener)
+Process::WaitForStateChangedEvents (const TimeValue *timeout, EventSP &event_sp, ListenerSP hijack_listener_sp)
 {
     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
 
@@ -1320,15 +1320,15 @@ Process::WaitForStateChangedEvents (const TimeValue *timeout, EventSP &event_sp,
         log->Printf ("Process::%s (timeout = %p, event_sp)...", __FUNCTION__,
                      static_cast<const void*>(timeout));
 
-    Listener *listener = hijack_listener;
-    if (listener == nullptr)
-        listener = &m_listener;
+    ListenerSP listener_sp = hijack_listener_sp;
+    if (!listener_sp)
+        listener_sp = m_listener_sp;
 
     StateType state = eStateInvalid;
-    if (listener->WaitForEventForBroadcasterWithType (timeout,
-                                                      this,
-                                                      eBroadcastBitStateChanged | eBroadcastBitInterrupt,
-                                                      event_sp))
+    if (listener_sp->WaitForEventForBroadcasterWithType (timeout,
+                                                         this,
+                                                         eBroadcastBitStateChanged | eBroadcastBitInterrupt,
+                                                         event_sp))
     {
         if (event_sp && event_sp->GetType() == eBroadcastBitStateChanged)
             state = Process::ProcessEventData::GetStateFromEvent(event_sp.get());
@@ -1352,7 +1352,7 @@ Process::PeekAtStateChangedEvents ()
         log->Printf ("Process::%s...", __FUNCTION__);
 
     Event *event_ptr;
-    event_ptr = m_listener.PeekAtNextEventForBroadcasterWithType (this,
+    event_ptr = m_listener_sp->PeekAtNextEventForBroadcasterWithType (this,
                                                                   eBroadcastBitStateChanged);
     if (log)
     {
@@ -1381,7 +1381,7 @@ Process::WaitForStateChangedEventsPrivate (const TimeValue *timeout, EventSP &ev
                      static_cast<const void*>(timeout));
 
     StateType state = eStateInvalid;
-    if (m_private_state_listener.WaitForEventForBroadcasterWithType (timeout,
+    if (m_private_state_listener_sp->WaitForEventForBroadcasterWithType (timeout,
                                                                      &m_private_state_broadcaster,
                                                                      eBroadcastBitStateChanged | eBroadcastBitInterrupt,
                                                                      event_sp))
@@ -1408,9 +1408,9 @@ Process::WaitForEventsPrivate (const TimeValue *timeout, EventSP &event_sp, bool
                      static_cast<const void*>(timeout));
 
     if (control_only)
-        return m_private_state_listener.WaitForEventForBroadcaster(timeout, &m_private_state_control_broadcaster, event_sp);
+        return m_private_state_listener_sp->WaitForEventForBroadcaster(timeout, &m_private_state_control_broadcaster, event_sp);
     else
-        return m_private_state_listener.WaitForEvent(timeout, event_sp);
+        return m_private_state_listener_sp->WaitForEvent(timeout, event_sp);
 }
 
 bool
@@ -1690,7 +1690,8 @@ Process::StateChangedIsExternallyHijacked()
 {
     if (IsHijackedForEvent(eBroadcastBitStateChanged))
     {
-        if (strcmp(m_hijacking_listeners.back()->GetName(), "lldb.Process.ResumeSynchronous.hijack"))
+        const char *hijacking_name = GetHijackingListenerName();
+        if (hijacking_name && strcmp(hijacking_name, "lldb.Process.ResumeSynchronous.hijack"))
             return true;
     }
     return false;
@@ -1763,13 +1764,13 @@ Process::ResumeSynchronous (Stream *stream)
         return error;
     }
 
-    ListenerSP listener_sp (new Listener("lldb.Process.ResumeSynchronous.hijack"));
-    HijackProcessEvents(listener_sp.get());
+    ListenerSP listener_sp (Listener::MakeListener("lldb.Process.ResumeSynchronous.hijack"));
+    HijackProcessEvents(listener_sp);
 
     Error error = PrivateResume();
     if (error.Success())
     {
-        StateType state = WaitForProcessToStop(nullptr, nullptr, true, listener_sp.get(), stream);
+        StateType state = WaitForProcessToStop (NULL, NULL, true, listener_sp, stream);
         const bool must_be_alive = false; // eStateExited is ok, so this must be false
         if (!StateIsStoppedState(state, must_be_alive))
             error.SetErrorStringWithFormat("process not in stopped state after synchronous resume: %s", StateAsCString(state));
@@ -3065,8 +3066,8 @@ Process::LoadCore ()
     Error error = DoLoadCore();
     if (error.Success())
     {
-        Listener listener ("lldb.process.load_core_listener");
-        HijackProcessEvents(&listener);
+        ListenerSP listener_sp (Listener::MakeListener("lldb.process.load_core_listener"));
+        HijackProcessEvents(listener_sp);
 
         if (PrivateStateThreadIsValid ())
             ResumePrivateStateThread ();
@@ -3091,7 +3092,7 @@ Process::LoadCore ()
 
         // Wait indefinitely for a stopped event since we just posted one above...
         lldb::EventSP event_sp;
-        listener.WaitForEvent(nullptr, event_sp);
+        listener_sp->WaitForEvent (nullptr, event_sp);
         StateType state = ProcessEventData::GetStateFromEvent(event_sp.get());
 
         if (!StateIsStoppedState (state, false))
@@ -3216,10 +3217,13 @@ Process::AttachCompletionHandler::GetExitString ()
     return m_exit_string.c_str();
 }
 
-Listener &
+ListenerSP
 ProcessAttachInfo::GetListenerForProcess (Debugger &debugger)
 {
-    return (m_listener_sp ? *m_listener_sp : debugger.GetListener());
+    if (m_listener_sp)
+        return m_listener_sp;
+    else
+        return debugger.GetListener();
 }
 
 Error
@@ -3599,8 +3603,8 @@ Process::Halt (bool clear_thread_plans, bool use_run_lock)
     // own.
     m_clear_thread_plans_on_stop |= clear_thread_plans;
     
-    Listener halt_listener ("lldb.process.halt_listener");
-    HijackProcessEvents(&halt_listener);
+    ListenerSP halt_listener_sp (Listener::MakeListener("lldb.process.halt_listener"));
+    HijackProcessEvents(halt_listener_sp);
 
     EventSP event_sp;
     
@@ -3620,7 +3624,7 @@ Process::Halt (bool clear_thread_plans, bool use_run_lock)
     TimeValue timeout_time;
     timeout_time = TimeValue::Now();
     timeout_time.OffsetWithSeconds(10);
-    StateType state = WaitForProcessToStop(&timeout_time, &event_sp, true, &halt_listener,
+    StateType state = WaitForProcessToStop(&timeout_time, &event_sp, true, halt_listener_sp,
                                            nullptr, use_run_lock);
     RestoreProcessEvents();
 
@@ -3645,8 +3649,8 @@ Process::StopForDestroyOrDetach(lldb::EventSP &exit_event_sp)
         if (log)
             log->Printf("Process::%s() About to stop.", __FUNCTION__);
 
-        ListenerSP listener_sp (new Listener("lldb.Process.StopForDestroyOrDetach.hijack"));
-        HijackProcessEvents(listener_sp.get());
+        ListenerSP listener_sp (Listener::MakeListener("lldb.Process.StopForDestroyOrDetach.hijack"));
+        HijackProcessEvents(listener_sp);
 
         SendAsyncInterrupt();
 
@@ -3654,7 +3658,7 @@ Process::StopForDestroyOrDetach(lldb::EventSP &exit_event_sp)
         TimeValue timeout (TimeValue::Now());
         timeout.OffsetWithSeconds(10);
 
-        StateType state = WaitForProcessToStop (&timeout, &exit_event_sp, true, listener_sp.get());
+        StateType state = WaitForProcessToStop (&timeout, &exit_event_sp, true, listener_sp);
 
         RestoreProcessEvents();
 
@@ -5323,7 +5327,7 @@ Process::RunThreadPlan (ExecutionContext &exe_ctx,
         return eExpressionStoppedForDebug;
     }
 
-    Listener listener("lldb.process.listener.run-thread-plan");
+    ListenerSP listener_sp(Listener::MakeListener("lldb.process.listener.run-thread-plan"));
 
     lldb::EventSP event_to_broadcast_sp;
 
@@ -5334,7 +5338,7 @@ Process::RunThreadPlan (ExecutionContext &exe_ctx,
         // If the event needs to propagate beyond the hijacker (e.g., the process exits during execution), then the event
         // is put into event_to_broadcast_sp for rebroadcasting.
 
-        ProcessEventHijacker run_thread_plan_hijacker (*this, &listener);
+        ProcessEventHijacker run_thread_plan_hijacker (*this, listener_sp);
 
         if (log)
         {
@@ -5424,7 +5428,7 @@ Process::RunThreadPlan (ExecutionContext &exe_ctx,
         // Are there cases where we might want to run the remaining events here, and then try to
         // call the function?  That's probably being too tricky for our own good.
 
-        Event *other_events = listener.PeekAtNextEvent();
+        Event *other_events = listener_sp->PeekAtNextEvent();
         if (other_events != nullptr)
         {
             errors.Printf("Calling RunThreadPlan with pending events on the queue.");
@@ -5483,7 +5487,7 @@ Process::RunThreadPlan (ExecutionContext &exe_ctx,
                 TimeValue resume_timeout = TimeValue::Now();
                 resume_timeout.OffsetWithMicroSeconds(500000);
 
-                got_event = listener.WaitForEvent(&resume_timeout, event_sp);
+                got_event = listener_sp->WaitForEvent(&resume_timeout, event_sp);
                 if (!got_event)
                 {
                     if (log)
@@ -5605,7 +5609,7 @@ Process::RunThreadPlan (ExecutionContext &exe_ctx,
             }
             else
 #endif
-            got_event = listener.WaitForEvent (timeout_ptr, event_sp);
+            got_event = listener_sp->WaitForEvent (timeout_ptr, event_sp);
 
             if (got_event)
             {
@@ -5805,7 +5809,7 @@ Process::RunThreadPlan (ExecutionContext &exe_ctx,
                         real_timeout = TimeValue::Now();
                         real_timeout.OffsetWithMicroSeconds(500000);
 
-                        got_event = listener.WaitForEvent(&real_timeout, event_sp);
+                        got_event = listener_sp->WaitForEvent(&real_timeout, event_sp);
 
                         if (got_event)
                         {
index 3102036..c9c53e9 100644 (file)
@@ -517,11 +517,11 @@ ProcessLaunchInfo::ConvertArgumentsForLaunchingInShell (Error &error,
     return false;
 }
 
-Listener &
+ListenerSP
 ProcessLaunchInfo::GetListenerForProcess (Debugger &debugger)
 {
     if (m_listener_sp)
-        return *m_listener_sp;
+        return m_listener_sp;
     else
         return debugger.GetListener();
 }
index 7455c20..acb84e5 100644 (file)
@@ -70,7 +70,7 @@ Target::GetStaticBroadcasterClass ()
 
 Target::Target(Debugger &debugger, const ArchSpec &target_arch, const lldb::PlatformSP &platform_sp, bool is_dummy_target) :
     TargetProperties (this),
-    Broadcaster (&debugger, Target::GetStaticBroadcasterClass().AsCString()),
+    Broadcaster (debugger.GetBroadcasterManager(), Target::GetStaticBroadcasterClass().AsCString()),
     ExecutionContextScope (),
     m_debugger (debugger),
     m_platform_sp (platform_sp),
@@ -194,10 +194,10 @@ Target::DeleteCurrentProcess ()
 }
 
 const lldb::ProcessSP &
-Target::CreateProcess (Listener &listener, const char *plugin_name, const FileSpec *crash_file)
+Target::CreateProcess (ListenerSP listener_sp, const char *plugin_name, const FileSpec *crash_file)
 {
     DeleteCurrentProcess ();
-    m_process_sp = Process::FindPlugin(shared_from_this(), plugin_name, listener, crash_file);
+    m_process_sp = Process::FindPlugin(shared_from_this(), plugin_name, listener_sp, crash_file);
     return m_process_sp;
 }
 
@@ -3072,12 +3072,12 @@ Target::Launch (ProcessLaunchInfo &launch_info, Stream *stream)
             ListenerSP hijack_listener_sp (launch_info.GetHijackListener());
             if (!hijack_listener_sp)
             {
-                hijack_listener_sp.reset(new Listener("lldb.Target.Launch.hijack"));
+                hijack_listener_sp = Listener::MakeListener("lldb.Target.Launch.hijack");
                 launch_info.SetHijackListener(hijack_listener_sp);
-                m_process_sp->HijackProcessEvents(hijack_listener_sp.get());
+                m_process_sp->HijackProcessEvents(hijack_listener_sp);
             }
 
-            StateType state = m_process_sp->WaitForProcessToStop(nullptr, nullptr, false, hijack_listener_sp.get(), nullptr);
+            StateType state = m_process_sp->WaitForProcessToStop(nullptr, nullptr, false, hijack_listener_sp, nullptr);
             
             if (state == eStateStopped)
             {
@@ -3088,7 +3088,7 @@ Target::Launch (ProcessLaunchInfo &launch_info, Stream *stream)
                         error = m_process_sp->PrivateResume();
                         if (error.Success())
                         {
-                            state = m_process_sp->WaitForProcessToStop(nullptr, nullptr, true, hijack_listener_sp.get(), stream);
+                            state = m_process_sp->WaitForProcessToStop(nullptr, nullptr, true, hijack_listener_sp, stream);
                             const bool must_be_alive = false; // eStateExited is ok, so this must be false
                             if (!StateIsStoppedState(state, must_be_alive))
                             {
@@ -3182,7 +3182,7 @@ Target::Attach (ProcessAttachInfo &attach_info, Stream *stream)
     const bool async = attach_info.GetAsync();
     if (!async)
     {
-        hijack_listener_sp.reset (new Listener ("lldb.Target.Attach.attach.hijack"));
+        hijack_listener_sp = Listener::MakeListener("lldb.Target.Attach.attach.hijack");
         attach_info.SetHijackListener (hijack_listener_sp);
     }
 
@@ -3205,7 +3205,7 @@ Target::Attach (ProcessAttachInfo &attach_info, Stream *stream)
             }
         }
         if (hijack_listener_sp)
-            process_sp->HijackProcessEvents (hijack_listener_sp.get ());
+            process_sp->HijackProcessEvents (hijack_listener_sp);
         error = process_sp->Attach (attach_info);
     }
 
@@ -3217,7 +3217,7 @@ Target::Attach (ProcessAttachInfo &attach_info, Stream *stream)
         }
         else
         {
-            state = process_sp->WaitForProcessToStop (nullptr, nullptr, false, attach_info.GetHijackListener ().get (), stream);
+            state = process_sp->WaitForProcessToStop (nullptr, nullptr, false, attach_info.GetHijackListener(), stream);
             process_sp->RestoreProcessEvents ();
 
             if (state != eStateStopped)
index ffec758..5f1a439 100644 (file)
@@ -43,7 +43,7 @@ TargetList::GetStaticBroadcasterClass ()
 // TargetList constructor
 //----------------------------------------------------------------------
 TargetList::TargetList(Debugger &debugger) :
-    Broadcaster(&debugger, TargetList::GetStaticBroadcasterClass().AsCString()),
+    Broadcaster(debugger.GetBroadcasterManager(), TargetList::GetStaticBroadcasterClass().AsCString()),
     m_target_list(),
     m_target_list_mutex (Mutex::eMutexTypeRecursive),
     m_selected_target_idx (0)
index fd3df8f..b455094 100644 (file)
@@ -274,7 +274,7 @@ Thread::GetStaticBroadcasterClass ()
 Thread::Thread (Process &process, lldb::tid_t tid, bool use_invalid_index_id) :
     ThreadProperties (false),
     UserID (tid),
-    Broadcaster(&process.GetTarget().GetDebugger(), Thread::GetStaticBroadcasterClass().AsCString()),
+    Broadcaster(process.GetTarget().GetDebugger().GetBroadcasterManager(), Thread::GetStaticBroadcasterClass().AsCString()),
     m_process_wp (process.shared_from_this()),
     m_stop_info_sp (),
     m_stop_info_stop_id (0),