From 0fc5ab7f183496212db22f59bfa5c388ff25f054 Mon Sep 17 00:00:00 2001 From: brad kittenbrink <brad@lindenlab.com> Date: Wed, 21 Oct 2009 19:08:25 -0700 Subject: Workaround for DEV-35406 lleventhost crash on shutdown. The fix deletes all LLEventPumps boost::signal objects prior to unloading any dlls. reviewed by Nat. --- indra/llcommon/llevents.cpp | 24 +++++++++++++++++++++--- indra/llcommon/llevents.h | 11 ++++++++++- indra/newview/llappviewer.cpp | 7 ++++--- 3 files changed, 35 insertions(+), 7 deletions(-) diff --git a/indra/llcommon/llevents.cpp b/indra/llcommon/llevents.cpp index a6421ac696..4bdfe5a867 100644 --- a/indra/llcommon/llevents.cpp +++ b/indra/llcommon/llevents.cpp @@ -126,6 +126,16 @@ void LLEventPumps::flush() } } +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) + { + pmi->second->reset(); + } +} + std::string LLEventPumps::registerNew(const LLEventPump& pump, const std::string& name, bool tweak) { std::pair<PumpMap::iterator, bool> inserted = @@ -242,6 +252,7 @@ LLEventPumps::~LLEventPumps() LLEventPump::LLEventPump(const std::string& name, bool tweak): // Register every new instance with LLEventPumps mName(LLEventPumps::instance().registerNew(*this, name, tweak)), + mSignal(new LLStandardSignal()), mEnabled(true) {} @@ -264,6 +275,13 @@ std::string LLEventPump::inventName(const std::string& pfx) return STRINGIZE(pfx << suffix++); } +void LLEventPump::reset() +{ + mSignal.reset(); + mConnections.clear(); + //mDeps.clear(); +} + LLBoundListener LLEventPump::listen_impl(const std::string& name, const LLEventListener& listener, const NameList& after, const NameList& before) @@ -405,7 +423,7 @@ LLBoundListener LLEventPump::listen_impl(const std::string& name, const LLEventL } // Now that newNode has a value that places it appropriately in mSignal, // connect it. - LLBoundListener bound = mSignal.connect(newNode, listener); + LLBoundListener bound = mSignal->connect(newNode, listener); mConnections[name] = bound; return bound; } @@ -445,7 +463,7 @@ bool LLEventStream::post(const LLSD& event) // Let caller know if any one listener handled the event. This is mostly // useful when using LLEventStream as a listener for an upstream // LLEventPump. - return mSignal(event); + return (*mSignal)(event); } /***************************************************************************** @@ -476,7 +494,7 @@ void LLEventQueue::flush() mEventQueue.clear(); for ( ; ! queue.empty(); queue.pop_front()) { - mSignal(queue.front()); + (*mSignal)(queue.front()); } } diff --git a/indra/llcommon/llevents.h b/indra/llcommon/llevents.h index b999bfafa7..64e5cb5da7 100644 --- a/indra/llcommon/llevents.h +++ b/indra/llcommon/llevents.h @@ -202,6 +202,12 @@ public: */ void flush(); + /** + * Reset all known LLEventPump instances + * workaround for DEV-35406 crash on shutdown + */ + void reset(); + private: friend class LLEventPump; /** @@ -504,6 +510,8 @@ private: /// flush queued events virtual void flush() {} + virtual void reset(); + private: virtual LLBoundListener listen_impl(const std::string& name, const LLEventListener&, const NameList& after, @@ -512,7 +520,8 @@ private: protected: /// implement the dispatching - LLStandardSignal mSignal; + boost::scoped_ptr<LLStandardSignal> mSignal; + /// valve open? bool mEnabled; /// Map of named listeners. This tracks the listeners that actually exist diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 5b769dcab4..923a66ee8e 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -1206,6 +1206,9 @@ bool LLAppViewer::mainLoop() bool LLAppViewer::cleanup() { + // workaround for DEV-35406 crash on shutdown + LLEventPumps::instance().reset(); + // *TODO - generalize this and move DSO wrangling to a helper class -brad std::set<struct apr_dso_handle_t *>::const_iterator i; for(i = mPlugins.begin(); i != mPlugins.end(); ++i) @@ -1214,9 +1217,7 @@ bool LLAppViewer::cleanup() apr_status_t rv = apr_dso_sym((apr_dso_handle_sym_t*)&ll_plugin_stop_func, *i, "ll_plugin_stop"); ll_plugin_stop_func(); - // *NOTE - disabled unloading as partial solution to DEV-35406 crash on shutdown - //rv = apr_dso_unload(*i); - (void)rv; + rv = apr_dso_unload(*i); } mPlugins.clear(); -- cgit v1.2.3