From 0637fe27bc9f07208a1703349a304b27fc08a535 Mon Sep 17 00:00:00 2001
From: Xiaohong Bao <bao@lindenlab.com>
Date: Tue, 25 Oct 2011 22:53:40 -0600
Subject: [PATCH] fix for SH-2624: crash at
 LLPrivateMemoryPoolManager::freeMem: ASSERT (!addr)

---
 indra/llcommon/llmemory.cpp   | 22 ++++++++++++++--------
 indra/llcommon/llmemory.h     |  8 ++++----
 indra/newview/llappviewer.cpp |  5 +++--
 3 files changed, 21 insertions(+), 14 deletions(-)

diff --git a/indra/llcommon/llmemory.cpp b/indra/llcommon/llmemory.cpp
index 7d340483b7c..7167d705af4 100644
--- a/indra/llcommon/llmemory.cpp
+++ b/indra/llcommon/llmemory.cpp
@@ -1773,6 +1773,7 @@ void LLPrivateMemoryPool::LLChunkHashElement::remove(LLPrivateMemoryPool::LLMemo
 //class LLPrivateMemoryPoolManager
 //--------------------------------------------------------------------
 LLPrivateMemoryPoolManager* LLPrivateMemoryPoolManager::sInstance = NULL ;
+BOOL LLPrivateMemoryPoolManager::sPrivatePoolEnabled = FALSE ;
 std::vector<LLPrivateMemoryPool*> LLPrivateMemoryPoolManager::sDanglingPoolList ;
 
 LLPrivateMemoryPoolManager::LLPrivateMemoryPoolManager(BOOL enabled) 
@@ -1784,7 +1785,7 @@ LLPrivateMemoryPoolManager::LLPrivateMemoryPoolManager(BOOL enabled)
 		mPoolList[i] = NULL ;
 	}
 
-	mPrivatePoolEnabled = enabled ;
+	sPrivatePoolEnabled = enabled ;
 }
 
 LLPrivateMemoryPoolManager::~LLPrivateMemoryPoolManager() 
@@ -1866,7 +1867,7 @@ void LLPrivateMemoryPoolManager::destroyClass()
 
 LLPrivateMemoryPool* LLPrivateMemoryPoolManager::newPool(S32 type) 
 {
-	if(!mPrivatePoolEnabled)
+	if(!sPrivatePoolEnabled)
 	{
 		return NULL ;
 	}
@@ -1964,7 +1965,11 @@ void  LLPrivateMemoryPoolManager::freeMem(LLPrivateMemoryPool* poolp, void* addr
 	}
 	else
 	{
-		if(!sInstance) //the private memory manager is destroyed, try the dangling list
+		if(!sPrivatePoolEnabled)
+		{
+			free(addr) ; //private pool is disabled.
+		}
+		else if(!sInstance) //the private memory manager is destroyed, try the dangling list
 		{
 			for(S32 i = 0 ; i < sDanglingPoolList.size(); i++)
 			{
@@ -1985,12 +1990,13 @@ void  LLPrivateMemoryPoolManager::freeMem(LLPrivateMemoryPool* poolp, void* addr
 					addr = NULL ;
 					break ;
 				}
-			}
+			}		
+			llassert_always(!addr) ; //addr should be release before hitting here!
+		}
+		else
+		{
+			llerrs << "private pool is used before initialized.!" << llendl ;
 		}
-
-		llassert_always(!addr) ; //addr should be release before hitting here!
-
-		free(addr) ;
 	}	
 }
 
diff --git a/indra/llcommon/llmemory.h b/indra/llcommon/llmemory.h
index 25e6c68e88f..7646bcfc252 100644
--- a/indra/llcommon/llmemory.h
+++ b/indra/llcommon/llmemory.h
@@ -394,11 +394,11 @@ class LL_COMMON_API LLPrivateMemoryPoolManager
 	LLPrivateMemoryPool* newPool(S32 type) ;
 	void deletePool(LLPrivateMemoryPool* pool) ;
 
-private:
-	static LLPrivateMemoryPoolManager* sInstance ;
-	std::vector<LLPrivateMemoryPool*> mPoolList ;
-	BOOL mPrivatePoolEnabled;
+private:	
+	std::vector<LLPrivateMemoryPool*> mPoolList ;	
 
+	static LLPrivateMemoryPoolManager* sInstance ;
+	static BOOL sPrivatePoolEnabled;
 	static std::vector<LLPrivateMemoryPool*> sDanglingPoolList ;
 public:
 	//debug and statistics info.
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 152ee34bbc5..97a7afb354f 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -2003,6 +2003,8 @@ bool LLAppViewer::initThreads()
 	static const bool enable_threads = true;
 #endif
 
+	LLImage::initClass();
+
 	LLVFSThread::initClass(enable_threads && false);
 	LLLFSThread::initClass(enable_threads && false);
 
@@ -2012,8 +2014,7 @@ bool LLAppViewer::initThreads()
 	LLAppViewer::sTextureFetch = new LLTextureFetch(LLAppViewer::getTextureCache(),
 													sImageDecodeThread,
 													enable_threads && true,
-													app_metrics_qa_mode);
-	LLImage::initClass();
+													app_metrics_qa_mode);	
 
 	if (LLFastTimer::sLog || LLFastTimer::sMetricLog)
 	{
-- 
GitLab