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