From 6daf19c442c2dff80407b5657f640ef01a509feb Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Sat, 29 Dec 2018 10:15:28 -0500 Subject: [PATCH] SL-793: Add LLEventPumps::clear() method to disconnect all listeners. This is like the existing reset() method, except that reset() is specifically intended for shutdown: it disables every existing LLEventPump in such a way that it cannot be subsequently reused. (The original idea was to disconnect listeners in DLLs unloaded at shutdown.) clear() forcibly disconnects all existing listeners, but leaves LLEventPumps ready for reuse. This is useful (e.g.) for test programs to reset the state of LLEventPumps between individual test functions. --- indra/llcommon/llevents.cpp | 31 +++++++++++++++++++++++++------ indra/llcommon/llevents.h | 7 ++++++- 2 files changed, 31 insertions(+), 7 deletions(-) diff --git a/indra/llcommon/llevents.cpp b/indra/llcommon/llevents.cpp index dce97b5411..5d4dbd9126 100644 --- a/indra/llcommon/llevents.cpp +++ b/indra/llcommon/llevents.cpp @@ -45,6 +45,7 @@ #include // external library headers #include +#include #if LL_WINDOWS #pragma warning (push) #pragma warning (disable : 4701) // compiler thinks might use uninitialized var, but no @@ -154,13 +155,23 @@ void LLEventPumps::flush() } } +void LLEventPumps::clear() +{ + // Clear every known LLEventPump instance. Leave it up to each instance to + // decide what to do with the clear() call. + for (PumpMap::value_type& pair : mPumpMap) + { + pair.second->clear(); + } +} + void LLEventPumps::reset() { // Reset every known LLEventPump instance. Leave it up to each instance to // decide what to do with the reset() call. - for (PumpMap::iterator pmi = mPumpMap.begin(), pmend = mPumpMap.end(); pmi != pmend; ++pmi) + for (PumpMap::value_type& pair : mPumpMap) { - pmi->second->reset(); + pair.second->reset(); } } @@ -283,7 +294,7 @@ LLEventPump::LLEventPump(const std::string& name, bool tweak): // Register every new instance with LLEventPumps mRegistry(LLEventPumps::instance().getHandle()), mName(mRegistry.get()->registerNew(*this, name, tweak)), - mSignal(new LLStandardSignal()), + mSignal(boost::make_shared()), mEnabled(true) {} @@ -311,6 +322,14 @@ std::string LLEventPump::inventName(const std::string& pfx) return STRINGIZE(pfx << suffix++); } +void LLEventPump::clear() +{ + // Destroy the original LLStandardSignal instance, replacing it with a + // whole new one. + mSignal = boost::make_shared(); + mConnections.clear(); +} + void LLEventPump::reset() { mSignal.reset(); @@ -546,16 +565,16 @@ bool LLEventStream::post(const LLSD& event) bool LLEventMailDrop::post(const LLSD& event) { bool posted = false; - + if (!mSignal->empty()) posted = LLEventStream::post(event); - + if (!posted) { // if the event was not handled we will save it for later so that it can // be posted to any future listeners when they attach. mEventHistory.push_back(event); } - + return posted; } diff --git a/indra/llcommon/llevents.h b/indra/llcommon/llevents.h index 1d51c660ed..78174cea82 100644 --- a/indra/llcommon/llevents.h +++ b/indra/llcommon/llevents.h @@ -263,6 +263,11 @@ public: */ void flush(); + /** + * Disconnect listeners from all known LLEventPump instances + */ + void clear(); + /** * Reset all known LLEventPump instances * workaround for DEV-35406 crash on shutdown @@ -586,7 +591,7 @@ private: friend class LLEventPumps; /// flush queued events virtual void flush() {} - + virtual void clear(); virtual void reset();