From 63195e76cae04f4eb98a3ce3230caae17fa79eca Mon Sep 17 00:00:00 2001 From: angela Date: Tue, 10 Nov 2009 22:46:58 +0800 Subject: check for NULL to prevent crashing --- indra/newview/lltexturecache.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'indra/newview/lltexturecache.cpp') diff --git a/indra/newview/lltexturecache.cpp b/indra/newview/lltexturecache.cpp index 69a2d1d7a6..6a4b967487 100644 --- a/indra/newview/lltexturecache.cpp +++ b/indra/newview/lltexturecache.cpp @@ -1543,6 +1543,8 @@ bool LLTextureCache::readComplete(handle_t handle, bool abort) handle_map_t::iterator iter = mReaders.find(handle); llassert_always(iter != mReaders.end() || abort); LLTextureCacheWorker* worker = iter->second; + if (!worker) + return false; bool res = worker->complete(); if (res || abort) { -- cgit v1.2.3 From a7fa9c49366dc1d22ee7aeea21c26cd40f2bc7f0 Mon Sep 17 00:00:00 2001 From: Steve Bennetts Date: Thu, 12 Nov 2009 00:07:07 -0800 Subject: Better fix for edge case where abort call to readComplete() can cause a crash. --- indra/newview/lltexturecache.cpp | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) (limited to 'indra/newview/lltexturecache.cpp') diff --git a/indra/newview/lltexturecache.cpp b/indra/newview/lltexturecache.cpp index 6a4b967487..9be342c424 100644 --- a/indra/newview/lltexturecache.cpp +++ b/indra/newview/lltexturecache.cpp @@ -1541,23 +1541,24 @@ bool LLTextureCache::readComplete(handle_t handle, bool abort) { lockWorkers(); handle_map_t::iterator iter = mReaders.find(handle); - llassert_always(iter != mReaders.end() || abort); - LLTextureCacheWorker* worker = iter->second; - if (!worker) - return false; - bool res = worker->complete(); - if (res || abort) + LLTextureCacheWorker* worker = NULL; + bool complete = false; + if (iter != mReaders.end()) { - mReaders.erase(handle); + worker = iter->second; + complete = worker->complete(); + } + if (worker && (complete || abort)) + { + mReaders.erase(iter); unlockWorkers(); worker->scheduleDelete(); - return true; } else { unlockWorkers(); - return false; } + return (complete || abort); } LLTextureCache::handle_t LLTextureCache::writeToCache(const LLUUID& id, U32 priority, -- cgit v1.2.3 From f67a8ad12ee4984a37d8ac7e551cdcc03ed5ecd3 Mon Sep 17 00:00:00 2001 From: Steve Bennetts Date: Fri, 13 Nov 2009 22:54:55 -0800 Subject: Mutex lock fix for texture cache. Also a fix for texture purging when reducing the cache size. --- indra/newview/lltexturecache.cpp | 58 +++++++++++++++++++++++----------------- 1 file changed, 33 insertions(+), 25 deletions(-) (limited to 'indra/newview/lltexturecache.cpp') diff --git a/indra/newview/lltexturecache.cpp b/indra/newview/lltexturecache.cpp index 9be342c424..2e2f342cca 100644 --- a/indra/newview/lltexturecache.cpp +++ b/indra/newview/lltexturecache.cpp @@ -834,9 +834,9 @@ bool LLTextureCache::updateTextureEntryList(const LLUUID& id, S32 bodysize) S32 idx = openAndReadEntry(id, entry, false); if (idx < 0) { - // TODO: change to llwarns - llerrs << "Failed to open entry: " << id << llendl; - removeFromCache(id); + llwarns << "Failed to open entry: " << id << llendl; + removeHeaderCacheEntry(id); + LLAPRFile::remove(getTextureFileName(id), getLocalAPRFilePool()); return false; } else if (oldbodysize != entry.mBodySize) @@ -1212,9 +1212,9 @@ void LLTextureCache::readHeaderCache() if (num_entries) { U32 empty_entries = 0; - typedef std::pair lru_data_t; + typedef std::pair lru_data_t; std::set lru; - std::vector purge_list; + std::vector purge_list; for (U32 i=0; i 0) { if (entry.mBodySize > entry.mImageSize) { // Shouldn't happen, failsafe only llwarns << "Bad entry: " << i << ": " << id << ": BodySize: " << entry.mBodySize << llendl; - purge_list.push_back(id); + purge_list.push_back(i); } } } @@ -1243,6 +1243,7 @@ void LLTextureCache::readHeaderCache() // Special case: cache size was reduced, need to remove entries // Note: After we prune entries, we will call this again and create the LRU U32 entries_to_purge = (num_entries-empty_entries) - sCacheMaxEntries; + llinfos << "Texture Cache Entries: " << num_entries << " Max: " << sCacheMaxEntries << " Empty: " << empty_entries << " Purging: " << entries_to_purge << llendl; if (entries_to_purge > 0) { for (std::set::iterator iter = lru.begin(); iter != lru.end(); ++iter) @@ -1252,13 +1253,17 @@ void LLTextureCache::readHeaderCache() break; } } + llassert_always(entries_to_purge <= 0); + llassert_always(purge_list.size() == entries_to_purge); } else { S32 lru_entries = (S32)((F32)sCacheMaxEntries * TEXTURE_CACHE_LRU_SIZE); for (std::set::iterator iter = lru.begin(); iter != lru.end(); ++iter) { - mLRU.insert(iter->second); + S32 idx = iter->second; + const LLUUID& id = entries[idx].mID; + mLRU.insert(id); // llinfos << "LRU: " << iter->first << " : " << iter->second << llendl; if (--lru_entries <= 0) break; @@ -1267,9 +1272,14 @@ void LLTextureCache::readHeaderCache() if (purge_list.size() > 0) { - for (std::vector::iterator iter = purge_list.begin(); iter != purge_list.end(); ++iter) + for (std::vector::iterator iter = purge_list.begin(); iter != purge_list.end(); ++iter) { - removeFromCache(*iter); + S32 idx = *iter; + const LLUUID& id = entries[idx].mID; + entries[idx].mImageSize = -1; // set cached entry size to -1 + bool res = removeHeaderCacheEntry(id); // sets entry size on disk to -1 + llassert_always(res); + LLAPRFile::remove(getTextureFileName(id), getLocalAPRFilePool()); } // If we removed any entries, we need to rebuild the entries list, // write the header, and call this again @@ -1307,6 +1317,7 @@ void LLTextureCache::purgeAllTextures(bool purge_directories) for (S32 i=0; i<16; i++) { std::string dirname = mTexturesDirName + delem + subdirs[i]; + llinfos << "Deleting files in directory: " << dirname << llendl; gDirUtilp->deleteFilesInDir(dirname,mask); if (purge_directories) { @@ -1624,24 +1635,20 @@ void LLTextureCache::addCompleted(Responder* responder, bool success) ////////////////////////////////////////////////////////////////////////////// // Called from MAIN thread (endWork()) - +// Ensuere that mHeaderMutex is locked first! bool LLTextureCache::removeHeaderCacheEntry(const LLUUID& id) { - if (!mReadOnly) + Entry entry; + S32 idx = openAndReadEntry(id, entry, false); + if (idx >= 0) { - LLMutexLock lock(&mHeaderMutex); - Entry entry; - S32 idx = openAndReadEntry(id, entry, false); - if (idx >= 0) - { - entry.mImageSize = -1; - entry.mBodySize = 0; - writeEntryAndClose(idx, entry); - mFreeList.insert(idx); - mHeaderIDMap.erase(id); - mTexturesSizeMap.erase(id); - return true; - } + entry.mImageSize = -1; + entry.mBodySize = 0; + writeEntryAndClose(idx, entry); + mFreeList.insert(idx); + mHeaderIDMap.erase(id); + mTexturesSizeMap.erase(id); + return true; } return false; } @@ -1651,6 +1658,7 @@ void LLTextureCache::removeFromCache(const LLUUID& id) //llwarns << "Removing texture from cache: " << id << llendl; if (!mReadOnly) { + LLMutexLock lock(&mHeaderMutex); removeHeaderCacheEntry(id); LLAPRFile::remove(getTextureFileName(id), getLocalAPRFilePool()); } -- cgit v1.2.3 From 637b6673bcceb90783b674ed90217143ecb48fe3 Mon Sep 17 00:00:00 2001 From: Steve Bennetts Date: Sat, 14 Nov 2009 10:22:32 -0800 Subject: More texture cache fixes, including a possible deadlock when the cache was getting purged. Significantly reduced spurrious warnings and delition of non sin-based texture fetch comptabable sided cache files. --- indra/newview/lltexturecache.cpp | 43 ++++++++++++++++++++++++---------------- 1 file changed, 26 insertions(+), 17 deletions(-) (limited to 'indra/newview/lltexturecache.cpp') diff --git a/indra/newview/lltexturecache.cpp b/indra/newview/lltexturecache.cpp index 2e2f342cca..4f199e9da4 100644 --- a/indra/newview/lltexturecache.cpp +++ b/indra/newview/lltexturecache.cpp @@ -1002,7 +1002,7 @@ void LLTextureCache::closeHeaderEntriesFile() void LLTextureCache::readEntriesHeader() { // mHeaderEntriesInfo initializes to default values so safe not to read it - llassert_always(mHeaderAPRFile == NULL); + llassert_always(mHeaderAPRFile == NULL); if (LLAPRFile::isExist(mHeaderEntriesFileName, getLocalAPRFilePool())) { LLAPRFile::readEx(mHeaderEntriesFileName, (U8*)&mHeaderEntriesInfo, 0, sizeof(EntriesInfo), @@ -1192,7 +1192,7 @@ void LLTextureCache::writeEntriesAndClose(const std::vector& entries) // Called from either the main thread or the worker thread void LLTextureCache::readHeaderCache() { - LLMutexLock lock(&mHeaderMutex); + mHeaderMutex.lock(); mLRU.clear(); // always clear the LRU @@ -1214,14 +1214,14 @@ void LLTextureCache::readHeaderCache() U32 empty_entries = 0; typedef std::pair lru_data_t; std::set lru; - std::vector purge_list; + std::set purge_list; for (U32 i=0; i::iterator iter = lru.begin(); iter != lru.end(); ++iter) { - purge_list.push_back(iter->second); - if (--entries_to_purge <= 0) - break; + S32 idx = iter->second; + if (entries[idx].mImageSize >= 0) + { + purge_list.insert(entries[idx].mID); + entries[idx].mImageSize = -1; + if (purge_list.size() >= entries_to_purge) + break; + } } } - llassert_always(entries_to_purge <= 0); - llassert_always(purge_list.size() == entries_to_purge); + llassert_always(purge_list.size() >= entries_to_purge); } else { @@ -1272,11 +1277,9 @@ void LLTextureCache::readHeaderCache() if (purge_list.size() > 0) { - for (std::vector::iterator iter = purge_list.begin(); iter != purge_list.end(); ++iter) + for (std::set::iterator iter = purge_list.begin(); iter != purge_list.end(); ++iter) { - S32 idx = *iter; - const LLUUID& id = entries[idx].mID; - entries[idx].mImageSize = -1; // set cached entry size to -1 + const LLUUID& id = *iter; bool res = removeHeaderCacheEntry(id); // sets entry size on disk to -1 llassert_always(res); LLAPRFile::remove(getTextureFileName(id), getLocalAPRFilePool()); @@ -1295,7 +1298,9 @@ void LLTextureCache::readHeaderCache() llassert_always(new_entries.size() <= sCacheMaxEntries); mHeaderEntriesInfo.mEntries = new_entries.size(); writeEntriesAndClose(new_entries); + mHeaderMutex.unlock(); // unlock the mutex before calling again readHeaderCache(); // repeat with new entries file + mHeaderMutex.lock(); } else { @@ -1303,6 +1308,7 @@ void LLTextureCache::readHeaderCache() } } } + mHeaderMutex.unlock(); } ////////////////////////////////////////////////////////////////////////////// @@ -1348,9 +1354,12 @@ void LLTextureCache::purgeTextures(bool validate) return; } - // *FIX:Mani - watchdog off. - LLAppViewer::instance()->pauseMainloopTimeout(); - + if (!mThreaded) + { + // *FIX:Mani - watchdog off. + LLAppViewer::instance()->pauseMainloopTimeout(); + } + LLMutexLock lock(&mHeaderMutex); llinfos << "TEXTURE CACHE: Purging." << llendl; -- cgit v1.2.3 From 651541a899f8674e06501686de4fc4715ff0d044 Mon Sep 17 00:00:00 2001 From: Steve Bennetts Date: Sun, 15 Nov 2009 22:39:48 -0800 Subject: Fixed a deadlock causing textrue caching to stall. --- indra/newview/lltexturecache.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'indra/newview/lltexturecache.cpp') diff --git a/indra/newview/lltexturecache.cpp b/indra/newview/lltexturecache.cpp index 4f199e9da4..c33c652935 100644 --- a/indra/newview/lltexturecache.cpp +++ b/indra/newview/lltexturecache.cpp @@ -1506,7 +1506,7 @@ S32 LLTextureCache::getHeaderCacheEntry(const LLUUID& id, S32& imagesize) // Writes imagesize to the header, updates timestamp S32 LLTextureCache::setHeaderCacheEntry(const LLUUID& id, S32 imagesize) { - LLMutexLock lock(&mHeaderMutex); + mHeaderMutex.lock(); llassert_always(imagesize >= 0); Entry entry; S32 idx = openAndReadEntry(id, entry, true); @@ -1514,11 +1514,15 @@ S32 LLTextureCache::setHeaderCacheEntry(const LLUUID& id, S32 imagesize) { entry.mImageSize = imagesize; writeEntryAndClose(idx, entry); + mHeaderMutex.unlock(); } else // retry { + mHeaderMutex.unlock(); readHeaderCache(); // We couldn't write an entry, so refresh the LRU + mHeaderMutex.lock(); llassert_always(!mLRU.empty() || mHeaderEntriesInfo.mEntries < sCacheMaxEntries); + mHeaderMutex.unlock(); idx = setHeaderCacheEntry(id, imagesize); // assert above ensures no inf. recursion } return idx; @@ -1644,7 +1648,7 @@ void LLTextureCache::addCompleted(Responder* responder, bool success) ////////////////////////////////////////////////////////////////////////////// // Called from MAIN thread (endWork()) -// Ensuere that mHeaderMutex is locked first! +// Ensure that mHeaderMutex is locked first! bool LLTextureCache::removeHeaderCacheEntry(const LLUUID& id) { Entry entry; -- cgit v1.2.3 From d8e1af97361a81dd571ccb64b859ae1e5157339e Mon Sep 17 00:00:00 2001 From: Steve Bennetts Date: Mon, 16 Nov 2009 16:48:58 -0800 Subject: Increasing texture cache version to force cache clear of possibly corrupted texture caches from previous 2.0 versions. Enabling Admin menu in God Mode independent of Advanced menu. --- indra/newview/lltexturecache.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/newview/lltexturecache.cpp') diff --git a/indra/newview/lltexturecache.cpp b/indra/newview/lltexturecache.cpp index c33c652935..845e71378a 100644 --- a/indra/newview/lltexturecache.cpp +++ b/indra/newview/lltexturecache.cpp @@ -917,7 +917,7 @@ BOOL LLTextureCache::isInLocal(const LLUUID& id) //static const S32 MAX_REASONABLE_FILE_SIZE = 512*1024*1024; // 512 MB -F32 LLTextureCache::sHeaderCacheVersion = 1.3f; +F32 LLTextureCache::sHeaderCacheVersion = 1.4f; U32 LLTextureCache::sCacheMaxEntries = MAX_REASONABLE_FILE_SIZE / TEXTURE_CACHE_ENTRY_SIZE; S64 LLTextureCache::sCacheMaxTexturesSize = 0; // no limit const char* entries_filename = "texture.entries"; -- cgit v1.2.3