summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
authorandreykproductengine <andreykproductengine@lindenlab.com>2019-11-26 17:21:43 +0200
committerandreykproductengine <andreykproductengine@lindenlab.com>2019-11-26 17:21:43 +0200
commitd3f389a38c8c5a2e394ad5f4ee44128e0e2b2dd3 (patch)
treef4997f15c807daaa6901fcd3a73eaf806abcb619 /indra
parent3d88b2587ddcabab49d95a249fd630c685873621 (diff)
SL-12326 Textures' apr pool crash fix
Diffstat (limited to 'indra')
-rw-r--r--indra/newview/lltexturecache.cpp31
-rw-r--r--indra/newview/lltexturecache.h7
2 files changed, 26 insertions, 12 deletions
diff --git a/indra/newview/lltexturecache.cpp b/indra/newview/lltexturecache.cpp
index f3bb574191..e2deb7ce1d 100644
--- a/indra/newview/lltexturecache.cpp
+++ b/indra/newview/lltexturecache.cpp
@@ -838,6 +838,7 @@ LLTextureCache::LLTextureCache(bool threaded)
mFastCachePoolp(NULL),
mFastCachePadBuffer(NULL)
{
+ mHeaderAPRFilePoolp = new LLVolatileAPRPool(); // is_local = true, because this pool is for headers, headers are under own mutex
}
LLTextureCache::~LLTextureCache()
@@ -846,6 +847,7 @@ LLTextureCache::~LLTextureCache()
writeUpdatedEntries() ;
delete mFastCachep;
delete mFastCachePoolp;
+ delete mHeaderAPRFilePoolp;
ll_aligned_free_16(mFastCachePadBuffer);
}
@@ -1014,10 +1016,11 @@ void LLTextureCache::purgeCache(ELLPath location, bool remove_dir)
if(LLFile::isdir(mTexturesDirName))
{
std::string file_name = gDirUtilp->getExpandedFilename(location, entries_filename);
- LLAPRFile::remove(file_name, getLocalAPRFilePool());
+ // mHeaderAPRFilePoolp because we are under header mutex, and can be in main thread
+ LLAPRFile::remove(file_name, mHeaderAPRFilePoolp);
file_name = gDirUtilp->getExpandedFilename(location, cache_filename);
- LLAPRFile::remove(file_name, getLocalAPRFilePool());
+ LLAPRFile::remove(file_name, mHeaderAPRFilePoolp);
purgeAllTextures(true);
}
@@ -1094,7 +1097,7 @@ LLAPRFile* LLTextureCache::openHeaderEntriesFile(bool readonly, S32 offset)
{
llassert_always(mHeaderAPRFile == NULL);
apr_int32_t flags = readonly ? APR_READ|APR_BINARY : APR_READ|APR_WRITE|APR_BINARY;
- mHeaderAPRFile = new LLAPRFile(mHeaderEntriesFileName, flags, getLocalAPRFilePool());
+ mHeaderAPRFile = new LLAPRFile(mHeaderEntriesFileName, flags, mHeaderAPRFilePoolp);
if(offset > 0)
{
mHeaderAPRFile->seek(APR_SET, offset);
@@ -1117,10 +1120,10 @@ void LLTextureCache::readEntriesHeader()
{
// mHeaderEntriesInfo initializes to default values so safe not to read it
llassert_always(mHeaderAPRFile == NULL);
- if (LLAPRFile::isExist(mHeaderEntriesFileName, getLocalAPRFilePool()))
+ if (LLAPRFile::isExist(mHeaderEntriesFileName, mHeaderAPRFilePoolp))
{
LLAPRFile::readEx(mHeaderEntriesFileName, (U8*)&mHeaderEntriesInfo, 0, sizeof(EntriesInfo),
- getLocalAPRFilePool());
+ mHeaderAPRFilePoolp);
}
else //create an empty entries header.
{
@@ -1152,7 +1155,7 @@ void LLTextureCache::writeEntriesHeader()
if (!mReadOnly)
{
LLAPRFile::writeEx(mHeaderEntriesFileName, (U8*)&mHeaderEntriesInfo, 0, sizeof(EntriesInfo),
- getLocalAPRFilePool());
+ mHeaderAPRFilePoolp);
}
}
@@ -1832,7 +1835,8 @@ void LLTextureCache::purgeTextures(bool validate)
if (uuididx == validate_idx)
{
LL_DEBUGS("TextureCache") << "Validating: " << filename << "Size: " << entries[idx].mBodySize << LL_ENDL;
- S32 bodysize = LLAPRFile::size(filename, getLocalAPRFilePool());
+ // mHeaderAPRFilePoolp because this is under header mutex in main thread
+ S32 bodysize = LLAPRFile::size(filename, mHeaderAPRFilePoolp);
if (bodysize != entries[idx].mBodySize)
{
LL_WARNS("TextureCache") << "TEXTURE CACHE BODY HAS BAD SIZE: " << bodysize << " != " << entries[idx].mBodySize
@@ -2231,7 +2235,7 @@ void LLTextureCache::openFastCache(bool first_time)
{
mFastCachePadBuffer = (U8*)ll_aligned_malloc_16(TEXTURE_FAST_CACHE_ENTRY_SIZE);
}
- mFastCachePoolp = new LLVolatileAPRPool();
+ mFastCachePoolp = new LLVolatileAPRPool(); // is_local= true by default, so not thread safe by default
if (LLAPRFile::isExist(mFastCacheFileName, mFastCachePoolp))
{
mFastCachep = new LLAPRFile(mFastCacheFileName, APR_READ|APR_WRITE|APR_BINARY, mFastCachePoolp) ;
@@ -2315,7 +2319,9 @@ void LLTextureCache::removeCachedTexture(const LLUUID& id)
mTexturesSizeMap.erase(id);
}
mHeaderIDMap.erase(id);
- LLAPRFile::remove(getTextureFileName(id), getLocalAPRFilePool());
+ // We are inside header's mutex so mHeaderAPRFilePoolp is safe to use,
+ // but getLocalAPRFilePool() is not safe, it might be in use by worker
+ LLAPRFile::remove(getTextureFileName(id), mHeaderAPRFilePoolp);
}
//called after mHeaderMutex is locked.
@@ -2327,7 +2333,10 @@ void LLTextureCache::removeEntry(S32 idx, Entry& entry, std::string& filename)
{
if (entry.mBodySize == 0) // Always attempt to remove when mBodySize > 0.
{
- if (LLAPRFile::isExist(filename, getLocalAPRFilePool())) // Sanity check. Shouldn't exist when body size is 0.
+ // Sanity check. Shouldn't exist when body size is 0.
+ // We are inside header's mutex so mHeaderAPRFilePoolp is safe to use,
+ // but getLocalAPRFilePool() is not safe, it might be in use by worker
+ if (LLAPRFile::isExist(filename, mHeaderAPRFilePoolp))
{
LL_WARNS("TextureCache") << "Entry has body size of zero but file " << filename << " exists. Deleting this file, too." << LL_ENDL;
}
@@ -2347,7 +2356,7 @@ void LLTextureCache::removeEntry(S32 idx, Entry& entry, std::string& filename)
if (file_maybe_exists)
{
- LLAPRFile::remove(filename, getLocalAPRFilePool());
+ LLAPRFile::remove(filename, mHeaderAPRFilePoolp);
}
}
diff --git a/indra/newview/lltexturecache.h b/indra/newview/lltexturecache.h
index da59290930..6046f2b9df 100644
--- a/indra/newview/lltexturecache.h
+++ b/indra/newview/lltexturecache.h
@@ -139,7 +139,7 @@ public:
U32 getEntries() { return mHeaderEntriesInfo.mEntries; }
U32 getMaxEntries() { return sCacheMaxEntries; };
BOOL isInCache(const LLUUID& id) ;
- BOOL isInLocal(const LLUUID& id) ;
+ BOOL isInLocal(const LLUUID& id) ; //not thread safe at the moment
protected:
// Accessed by LLTextureCacheWorker
@@ -190,6 +190,11 @@ private:
LLMutex mFastCacheMutex;
LLAPRFile* mHeaderAPRFile;
LLVolatileAPRPool* mFastCachePoolp;
+
+ // mLocalAPRFilePoolp is not thread safe and is meant only for workers
+ // howhever mHeaderEntriesFileName is accessed not from workers' threads
+ // so it needs own pool (not thread safe by itself, relies onto header's mutex)
+ LLVolatileAPRPool* mHeaderAPRFilePoolp;
typedef std::map<handle_t, LLTextureCacheWorker*> handle_map_t;
handle_map_t mReaders;