diff options
Diffstat (limited to 'lldb/source/Core')
-rw-r--r-- | lldb/source/Core/Broadcaster.cpp | 168 | ||||
-rw-r--r-- | lldb/source/Core/Communication.cpp | 17 | ||||
-rw-r--r-- | lldb/source/Core/Debugger.cpp | 25 | ||||
-rw-r--r-- | lldb/source/Core/Event.cpp | 22 | ||||
-rw-r--r-- | lldb/source/Core/IOHandler.cpp | 2 | ||||
-rw-r--r-- | lldb/source/Core/Listener.cpp | 136 |
6 files changed, 229 insertions, 141 deletions
diff --git a/lldb/source/Core/Broadcaster.cpp b/lldb/source/Core/Broadcaster.cpp index 84a42ae3d7e..6494e3d85bc 100644 --- a/lldb/source/Core/Broadcaster.cpp +++ b/lldb/source/Core/Broadcaster.cpp @@ -15,23 +15,31 @@ // 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(); } diff --git a/lldb/source/Core/Communication.cpp b/lldb/source/Core/Communication.cpp index ab2b293f8c3..557fb95df69 100644 --- a/lldb/source/Core/Communication.cpp +++ b/lldb/source/Core/Communication.cpp @@ -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 diff --git a/lldb/source/Core/Debugger.cpp b/lldb/source/Core/Debugger.cpp index f348bb00790..57313a45d37 100644 --- a/lldb/source/Core/Debugger.cpp +++ b/lldb/source/Core/Debugger.cpp @@ -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(); } diff --git a/lldb/source/Core/Event.cpp b/lldb/source/Core/Event.cpp index 293a322257e..8e2006330b5 100644 --- a/lldb/source/Core/Event.cpp +++ b/lldb/source/Core/Event.cpp @@ -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 = ", diff --git a/lldb/source/Core/IOHandler.cpp b/lldb/source/Core/IOHandler.cpp index 47d00e9184c..ea5624a5220 100644 --- a/lldb/source/Core/IOHandler.cpp +++ b/lldb/source/Core/IOHandler.cpp @@ -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()); diff --git a/lldb/source/Core/Listener.cpp b/lldb/source/Core/Listener.cpp index 34475498d48..d13a203d2da 100644 --- a/lldb/source/Core/Listener.cpp +++ b/lldb/source/Core/Listener.cpp @@ -23,6 +23,24 @@ 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)); +} |