From cadc8dc4a3c6f5d7a431e671857d09e0b5eac4a4 Mon Sep 17 00:00:00 2001
From: Steve Bennetts <steve@lindenlab.com>
Date: Tue, 27 Oct 2009 16:31:07 -0700
Subject: [PATCH] Fix for gInventory cleanup on shutdown, includes making
 LLNavigationBar a LLSingleton and explicitly destroying it with the rest of
 the UI.

---
 indra/newview/llappviewer.cpp      |  2 ++
 indra/newview/llinventorymodel.cpp |  8 +++++---
 indra/newview/llnavigationbar.cpp  | 13 +------------
 indra/newview/llnavigationbar.h    |  9 +++------
 indra/newview/llviewerwindow.cpp   |  6 +++++-
 5 files changed, 16 insertions(+), 22 deletions(-)

diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 4610437f084..e184d99ffc5 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -1349,6 +1349,8 @@ bool LLAppViewer::cleanup()
 	if( gViewerWindow)
 		gViewerWindow->shutdownViews();
 	
+	// Cleanup Inventory after the UI since it will delete any remaining observers
+	// (Deleted observers should have already removed themselves)
 	gInventory.cleanupInventory();
 	
 	// Clean up selection managers after UI is destroyed, as UI may be observing them.
diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp
index e49be83fbc7..1d7cbde0d56 100644
--- a/indra/newview/llinventorymodel.cpp
+++ b/indra/newview/llinventorymodel.cpp
@@ -182,10 +182,12 @@ LLInventoryModel::~LLInventoryModel()
 void LLInventoryModel::cleanupInventory()
 {
 	empty();
-	for (observer_list_t::iterator iter = mObservers.begin();
-		 iter != mObservers.end(); )
+	// Deleting one observer might erase others from the list, so always pop off the front
+	while (!mObservers.empty())
 	{
-		LLInventoryObserver* observer = *iter++;
+		observer_list_t::iterator iter = mObservers.begin();
+		LLInventoryObserver* observer = *iter;
+		mObservers.erase(iter);
 		delete observer;
 	}
 	mObservers.clear();
diff --git a/indra/newview/llnavigationbar.cpp b/indra/newview/llnavigationbar.cpp
index b91e23eace4..3802d13f8b8 100644
--- a/indra/newview/llnavigationbar.cpp
+++ b/indra/newview/llnavigationbar.cpp
@@ -164,16 +164,7 @@ void LLTeleportHistoryMenuItem::onMouseLeave(S32 x, S32 y, MASK mask)
 - Load navbar height from saved settings (as it's done for status bar) or think of a better way.
 */
 
-S32 NAVIGATION_BAR_HEIGHT = 60; // *HACK
-LLNavigationBar* LLNavigationBar::sInstance = 0;
-
-LLNavigationBar* LLNavigationBar::getInstance()
-{
-	if (!sInstance)
-		sInstance = new LLNavigationBar();
-
-	return sInstance;
-}
+S32 NAVIGATION_BAR_HEIGHT = 60; // *HACK, used in llviewerwindow.cpp
 
 LLNavigationBar::LLNavigationBar()
 :	mTeleportHistoryMenu(NULL),
@@ -198,8 +189,6 @@ LLNavigationBar::LLNavigationBar()
 LLNavigationBar::~LLNavigationBar()
 {
 	mTeleportFinishConnection.disconnect();
-	sInstance = 0;
-
 	LLSearchHistory::getInstance()->save();
 }
 
diff --git a/indra/newview/llnavigationbar.h b/indra/newview/llnavigationbar.h
index 8a65cd24fac..f1a1b85a867 100644
--- a/indra/newview/llnavigationbar.h
+++ b/indra/newview/llnavigationbar.h
@@ -47,12 +47,12 @@ class LLSearchComboBox;
  * Web browser-like navigation bar.
  */ 
 class LLNavigationBar
-:	public LLPanel
+	:	public LLPanel, public LLSingleton<LLNavigationBar>
 {
 	LOG_CLASS(LLNavigationBar);
-
+	
 public:
-	static LLNavigationBar* getInstance();
+	LLNavigationBar();
 	virtual ~LLNavigationBar();
 	
 	/*virtual*/ void	draw();
@@ -65,7 +65,6 @@ class LLNavigationBar
 	void showFavoritesPanel(BOOL visible);
 	
 private:
-	LLNavigationBar();
 
 	void rebuildTeleportHistoryMenu();
 	void showTeleportHistoryMenu();
@@ -91,8 +90,6 @@ class LLNavigationBar
 
 	void fillSearchComboBox();
 
-	static LLNavigationBar *sInstance;
-	
 	LLMenuGL*					mTeleportHistoryMenu;
 	LLButton*					mBtnBack;
 	LLButton*					mBtnForward;
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index c659e58e476..f141d33729a 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -1637,7 +1637,11 @@ void LLViewerWindow::shutdownViews()
 	// DEV-40930: Clear sModalStack. Otherwise, any LLModalDialog left open
 	// will crump with LL_ERRS.
 	LLModalDialog::shutdownModals();
-
+	
+	// destroy the nav bar, not currently part of gViewerWindow
+	// *TODO: Make LLNavigationBar part of gViewerWindow
+	delete LLNavigationBar::getInstance();
+	
 	// Delete all child views.
 	delete mRootView;
 	mRootView = NULL;
-- 
GitLab