diff options
| author | Xiaohong Bao <bao@lindenlab.com> | 2011-10-10 16:31:56 -0600 | 
|---|---|---|
| committer | Xiaohong Bao <bao@lindenlab.com> | 2011-10-10 16:31:56 -0600 | 
| commit | 897972636d0fdd0c6dc76e1a337bb43e1aa9bc0c (patch) | |
| tree | 74503db3d9c77ae4b3a93166edbe921f523d6f03 /indra | |
| parent | 5ef05e151d24e15a175d4f78ff17b6abdd36bbc4 (diff) | |
fix for SH-2464: Crash on exit in LLPrivateMemoryPoolManager::freeMem
Diffstat (limited to 'indra')
| -rw-r--r-- | indra/llcommon/llmemory.cpp | 41 | ||||
| -rw-r--r-- | indra/llcommon/llmemory.h | 1 | 
2 files changed, 40 insertions, 2 deletions
| diff --git a/indra/llcommon/llmemory.cpp b/indra/llcommon/llmemory.cpp index 8c02ad8290..7d340483b7 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 ; +std::vector<LLPrivateMemoryPool*> LLPrivateMemoryPoolManager::sDanglingPoolList ;  LLPrivateMemoryPoolManager::LLPrivateMemoryPoolManager(BOOL enabled)   { @@ -1797,7 +1798,7 @@ LLPrivateMemoryPoolManager::~LLPrivateMemoryPoolManager()  		S32 k = 0 ;  		for(mem_allocation_info_t::iterator iter = sMemAllocationTracker.begin() ; iter != sMemAllocationTracker.end() ; ++iter)  		{ -			llinfos << k++ << ", " << iter->second << llendl ; +			llinfos << k++ << ", " << (U32)iter->first << " : " << iter->second << llendl ;  		}  		sMemAllocationTracker.clear() ;  	} @@ -1817,7 +1818,17 @@ LLPrivateMemoryPoolManager::~LLPrivateMemoryPoolManager()  	{  		if(mPoolList[i])  		{ -			delete mPoolList[i] ; +			if(mPoolList[i]->isEmpty()) +			{ +				delete mPoolList[i] ; +			} +			else +			{ +				//can not delete this pool because it has alloacted memory to be freed. +				//move it to the dangling list. +				sDanglingPoolList.push_back(mPoolList[i]) ;				 +			} +  			mPoolList[i] = NULL ;  		}  	} @@ -1953,6 +1964,32 @@ void  LLPrivateMemoryPoolManager::freeMem(LLPrivateMemoryPool* poolp, void* addr  	}  	else  	{ +		if(!sInstance) //the private memory manager is destroyed, try the dangling list +		{ +			for(S32 i = 0 ; i < sDanglingPoolList.size(); i++) +			{ +				if(sDanglingPoolList[i]->findChunk((char*)addr)) +				{ +					sDanglingPoolList[i]->freeMem(addr) ; +					if(sDanglingPoolList[i]->isEmpty()) +					{ +						delete sDanglingPoolList[i] ; +						 +						if(i < sDanglingPoolList.size() - 1) +						{ +							sDanglingPoolList[i] = sDanglingPoolList[sDanglingPoolList.size() - 1] ; +						} +						sDanglingPoolList.pop_back() ; +					} + +					addr = NULL ; +					break ; +				} +			} +		} + +		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 db753f0d8b..25e6c68e88 100644 --- a/indra/llcommon/llmemory.h +++ b/indra/llcommon/llmemory.h @@ -399,6 +399,7 @@ private:  	std::vector<LLPrivateMemoryPool*> mPoolList ;  	BOOL mPrivatePoolEnabled; +	static std::vector<LLPrivateMemoryPool*> sDanglingPoolList ;  public:  	//debug and statistics info.  	void updateStatistics() ; | 
