summaryrefslogtreecommitdiff
path: root/indra/llcommon/llmemory.cpp
diff options
context:
space:
mode:
authorXiaohong Bao <bao@lindenlab.com>2011-10-10 16:31:56 -0600
committerXiaohong Bao <bao@lindenlab.com>2011-10-10 16:31:56 -0600
commit897972636d0fdd0c6dc76e1a337bb43e1aa9bc0c (patch)
tree74503db3d9c77ae4b3a93166edbe921f523d6f03 /indra/llcommon/llmemory.cpp
parent5ef05e151d24e15a175d4f78ff17b6abdd36bbc4 (diff)
fix for SH-2464: Crash on exit in LLPrivateMemoryPoolManager::freeMem
Diffstat (limited to 'indra/llcommon/llmemory.cpp')
-rw-r--r--indra/llcommon/llmemory.cpp41
1 files changed, 39 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) ;
}
}