From d1b840a0137dee05d424c477de0ba757be89af6d Mon Sep 17 00:00:00 2001 From: Aleric Inglewood Date: Mon, 25 Oct 2010 14:59:48 +0200 Subject: Validate textures starting with 00 too. --- linden/indra/newview/lltexturecache.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linden/indra/newview') diff --git a/linden/indra/newview/lltexturecache.cpp b/linden/indra/newview/lltexturecache.cpp index a9b7f81..b0d8412 100644 --- a/linden/indra/newview/lltexturecache.cpp +++ b/linden/indra/newview/lltexturecache.cpp @@ -1345,7 +1345,7 @@ void LLTextureCache::purgeTextures(bool validate) if (validate) { validate_idx = gSavedSettings.getU32("CacheValidateCounter"); - U32 next_idx = (++validate_idx) % 256; + U32 next_idx = (validate_idx + 1) % 256; gSavedSettings.setU32("CacheValidateCounter", next_idx); LL_DEBUGS("TextureCache") << "TEXTURE CACHE: Validating: " << validate_idx << LL_ENDL; } -- cgit v1.1 From 17e2c3f8999d93bb59deb7ac0c289ed2157a3f5e Mon Sep 17 00:00:00 2001 From: Aleric Inglewood Date: Mon, 25 Oct 2010 16:02:36 +0200 Subject: Fix possible crash on llassert_always(purge_list.size() >= entries_to_purge) This horrible noobish code checked if num_entries > sCacheMaxEntries and then goes on to assign (num_entries-empty_entries) - sCacheMaxEntries to an U32 entries_to_purge. Obviously this can lead to an abitrary large value of entries_to_purge with as result a crash due to the llassert_always. This bug must have been extremely rare since it only happens when someone decreases their cache size and has more empty entries in their entries file than the total number of entries minus the new cache size. --- linden/indra/newview/lltexturecache.cpp | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) (limited to 'linden/indra/newview') diff --git a/linden/indra/newview/lltexturecache.cpp b/linden/indra/newview/lltexturecache.cpp index b0d8412..ae0a63f 100644 --- a/linden/indra/newview/lltexturecache.cpp +++ b/linden/indra/newview/lltexturecache.cpp @@ -1172,7 +1172,7 @@ 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 sCacheMaxEntries) + if (num_entries - empty_entries > sCacheMaxEntries) { // 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; + 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) + // We can exit the following loop with the given condition, since if we'd reach the end of the lru set we'd have: + // purge_list.size() = lru.size() = num_entries - empty_entries = entries_to_purge + sCacheMaxEntries >= entries_to_purge + for (std::set::iterator iter = lru.begin(); purge_list.size() < entries_to_purge; ++iter) { - for (std::set::iterator iter = lru.begin(); iter != lru.end(); ++iter) - { - purge_list.push_back(iter->second); - if (purge_list.size() >= entries_to_purge) - break; - } + purge_list.insert(iter->second); } - llassert_always(purge_list.size() >= entries_to_purge); } else { @@ -1227,7 +1223,7 @@ 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) { mHeaderMutex.unlock(); removeFromCache(*iter); -- cgit v1.1 From b22b6bb6b16fcc0d908aa7899a80650ec1fe511d Mon Sep 17 00:00:00 2001 From: Aleric Inglewood Date: Mon, 25 Oct 2010 17:33:38 +0200 Subject: Fixed a locking issue with regard to texture cache purging. Releasing a lock in the middle of a critical area isn't very smart. --- linden/indra/newview/lltexturecache.cpp | 20 +++++++++++++------- linden/indra/newview/lltexturecache.h | 1 + 2 files changed, 14 insertions(+), 7 deletions(-) (limited to 'linden/indra/newview') diff --git a/linden/indra/newview/lltexturecache.cpp b/linden/indra/newview/lltexturecache.cpp index ae0a63f..56f3719 100644 --- a/linden/indra/newview/lltexturecache.cpp +++ b/linden/indra/newview/lltexturecache.cpp @@ -1225,9 +1225,7 @@ void LLTextureCache::readHeaderCache() { for (std::set::iterator iter = purge_list.begin(); iter != purge_list.end(); ++iter) { - mHeaderMutex.unlock(); - removeFromCache(*iter); - mHeaderMutex.lock(); + removeFromCacheLocked(*iter); } // If we removed any entries, we need to rebuild the entries list, // write the header, and call this again @@ -1246,7 +1244,7 @@ void LLTextureCache::readHeaderCache() writeEntriesAndClose(new_entries); mHeaderMutex.unlock(); // unlock the mutex before calling again readHeaderCache(); // repeat with new entries file - mHeaderMutex.lock(); + return; } else { @@ -1611,7 +1609,6 @@ bool LLTextureCache::removeHeaderCacheEntry(const LLUUID& id) { if (!mReadOnly) { - LLMutexLock lock(&mHeaderMutex); Entry entry; S32 idx = openAndReadEntry(id, entry, false); if (idx >= 0) @@ -1628,17 +1625,26 @@ bool LLTextureCache::removeHeaderCacheEntry(const LLUUID& id) return false; } -void LLTextureCache::removeFromCache(const LLUUID& id) +void LLTextureCache::removeFromCacheLocked(const LLUUID& id) { //llwarns << "Removing texture from cache: " << id << llendl; if (!mReadOnly) { removeHeaderCacheEntry(id); - LLMutexLock lock(&mHeaderMutex); LLAPRFile::remove(getTextureFileName(id)); } } +void LLTextureCache::removeFromCache(const LLUUID& id) +{ + //llwarns << "Removing texture from cache: " << id << llendl; + if (!mReadOnly) + { + LLMutexLock lock(&mHeaderMutex); + LLTextureCache::removeFromCacheLocked(id); + } +} + ////////////////////////////////////////////////////////////////////////////// LLTextureCache::ReadResponder::ReadResponder() diff --git a/linden/indra/newview/lltexturecache.h b/linden/indra/newview/lltexturecache.h index 45804c2..c859b9a 100644 --- a/linden/indra/newview/lltexturecache.h +++ b/linden/indra/newview/lltexturecache.h @@ -158,6 +158,7 @@ private: S32 getHeaderCacheEntry(const LLUUID& id, S32& imagesize); S32 setHeaderCacheEntry(const LLUUID& id, S32 imagesize); bool removeHeaderCacheEntry(const LLUUID& id); + void removeFromCacheLocked(const LLUUID& id); private: // Internal -- cgit v1.1 From 03852da89ad24c9e1edcf9cb50dbda31dd3ab43a Mon Sep 17 00:00:00 2001 From: Aleric Inglewood Date: Mon, 25 Oct 2010 17:37:46 +0200 Subject: IMP-667: WARNING: remove: Attempting to remove filename: /ramdisk/imprudence/cache/textures/*/*.texture This turned out to be a simple matter of trying to remove non-existant files: A texture with a 'body size' of 0 doesn't have a texture body file. --- linden/indra/newview/lltexturecache.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'linden/indra/newview') diff --git a/linden/indra/newview/lltexturecache.cpp b/linden/indra/newview/lltexturecache.cpp index 56f3719..a1a9a39 100644 --- a/linden/indra/newview/lltexturecache.cpp +++ b/linden/indra/newview/lltexturecache.cpp @@ -1382,7 +1382,15 @@ void LLTextureCache::purgeTextures(bool validate) { purge_count++; LL_DEBUGS("TextureCache") << "PURGING: " << filename << LL_ENDL; - LLAPRFile::remove(filename); + if (entries[idx].mBodySize > 0) + { + LLAPRFile::remove(filename); + } + else if (LLAPRFile::isExist(filename)) // Sanity check. Shouldn't exist. + { + LL_WARNS("TextureCache") << "Entry has zero body size but existing " << filename << ". Deleting file too..." << LL_ENDL; + LLAPRFile::remove(filename); + } cache_size -= entries[idx].mBodySize; mTexturesSizeTotal -= entries[idx].mBodySize; entries[idx].mBodySize = 0; -- cgit v1.1