From 6a8b63e9de7ee78db2e24ed77f855c1e19790af2 Mon Sep 17 00:00:00 2001 From: Xiaohong Bao Date: Sun, 7 Mar 2010 21:18:10 -0700 Subject: partial fix for EXT-5711: Some textures loading from cache seems jammed. This fix should be able to improve the speed of loading texturs from cache noticeably (30% or more). More fix to come. --- indra/newview/lltexturecache.cpp | 78 ++++++++++++++++++++++++++++++++++------ 1 file changed, 68 insertions(+), 10 deletions(-) (limited to 'indra/newview/lltexturecache.cpp') diff --git a/indra/newview/lltexturecache.cpp b/indra/newview/lltexturecache.cpp index 3116c8feb0..4649b9cbef 100644 --- a/indra/newview/lltexturecache.cpp +++ b/indra/newview/lltexturecache.cpp @@ -751,6 +751,7 @@ LLTextureCache::LLTextureCache(bool threaded) LLTextureCache::~LLTextureCache() { clearDeleteList() ; + writeUpdatedEntries() ; } ////////////////////////////////////////////////////////////////////////////// @@ -758,6 +759,9 @@ LLTextureCache::~LLTextureCache() //virtual S32 LLTextureCache::update(U32 max_time_ms) { + static LLFrameTimer timer ; + static const F32 MAX_TIME_INTERVAL = 300.f ; //seconds. + S32 res; res = LLWorkerThread::update(max_time_ms); @@ -793,6 +797,12 @@ S32 LLTextureCache::update(U32 max_time_ms) responder->completed(success); } + if(!res && timer.getElapsedTimeF32() > MAX_TIME_INTERVAL) + { + timer.reset() ; + writeUpdatedEntries() ; + } + return res; } @@ -1083,6 +1093,8 @@ S32 LLTextureCache::openAndReadEntry(const LLUUID& id, Entry& entry, bool create entry.init(id, time(NULL)); // Update Header writeEntriesHeader(); + + //the new entry, write immediately. // Write Entry S32 offset = sizeof(EntriesInfo) + idx * sizeof(Entry); LLAPRFile* aprfile = openHeaderEntriesFile(false, offset); @@ -1098,12 +1110,20 @@ S32 LLTextureCache::openAndReadEntry(const LLUUID& id, Entry& entry, bool create // Remove this entry from the LRU if it exists mLRU.erase(id); // Read the entry - S32 offset = sizeof(EntriesInfo) + idx * sizeof(Entry); - LLAPRFile* aprfile = openHeaderEntriesFile(true, offset); - S32 bytes_read = aprfile->read((void*)&entry, (S32)sizeof(Entry)); - llassert_always(bytes_read == sizeof(Entry)); + idx_entry_map_t::iterator iter = mUpdatedEntryMap.find(idx) ; + if(iter != mUpdatedEntryMap.end()) + { + entry = iter->second ; + } + else + { + S32 offset = sizeof(EntriesInfo) + idx * sizeof(Entry); + LLAPRFile* aprfile = openHeaderEntriesFile(true, offset); + S32 bytes_read = aprfile->read((void*)&entry, (S32)sizeof(Entry)); + llassert_always(bytes_read == sizeof(Entry)); + closeHeaderEntriesFile(); + } llassert_always(entry.mImageSize == 0 || entry.mImageSize == -1 || entry.mImageSize > entry.mBodySize); - closeHeaderEntriesFile(); } return idx; } @@ -1121,12 +1141,8 @@ void LLTextureCache::writeEntryAndClose(S32 idx, Entry& entry) mTexturesSizeMap[entry.mID] = entry.mBodySize; } // llinfos << "Updating TE: " << idx << ": " << id << " Size: " << entry.mBodySize << " Time: " << entry.mTime << llendl; - S32 offset = sizeof(EntriesInfo) + idx * sizeof(Entry); - LLAPRFile* aprfile = openHeaderEntriesFile(false, offset); - S32 bytes_written = aprfile->write((void*)&entry, (S32)sizeof(Entry)); - llassert_always(bytes_written == sizeof(Entry)); mHeaderEntriesMaxWriteIdx = llmax(mHeaderEntriesMaxWriteIdx, idx); - closeHeaderEntriesFile(); + mUpdatedEntryMap[idx] = entry ; } } } @@ -1141,6 +1157,7 @@ U32 LLTextureCache::openAndReadEntries(std::vector& entries) mTexturesSizeTotal = 0; LLAPRFile* aprfile = openHeaderEntriesFile(false, (S32)sizeof(EntriesInfo)); + updatedHeaderEntriesFile() ; for (U32 idx=0; idx& entries) } } +void LLTextureCache::writeUpdatedEntries() +{ + lockHeaders() ; + if (!mReadOnly && !mUpdatedEntryMap.empty()) + { + openHeaderEntriesFile(false, 0); + updatedHeaderEntriesFile() ; + closeHeaderEntriesFile(); + } + unlockHeaders() ; +} + +//mHeaderMutex is locked and mHeaderAPRFile is created before calling this. +void LLTextureCache::updatedHeaderEntriesFile() +{ + if (!mReadOnly && !mUpdatedEntryMap.empty() && mHeaderAPRFile) + { + //entriesInfo + mHeaderAPRFile->seek(APR_SET, 0); + S32 bytes_written = mHeaderAPRFile->write((U8*)&mHeaderEntriesInfo, sizeof(EntriesInfo)) ; + llassert_always(bytes_written == sizeof(EntriesInfo)); + + //write each updated entry + S32 entry_size = (S32)sizeof(Entry) ; + S32 prev_idx = -1 ; + S32 delta_idx ; + for (idx_entry_map_t::iterator iter = mUpdatedEntryMap.begin(); iter != mUpdatedEntryMap.end(); ++iter) + { + delta_idx = iter->first - prev_idx - 1; + prev_idx = iter->first ; + if(delta_idx) + { + mHeaderAPRFile->seek(APR_CUR, delta_idx * entry_size); + } + + bytes_written = mHeaderAPRFile->write((void*)(&iter->second), entry_size); + llassert_always(bytes_written == entry_size); + } + mUpdatedEntryMap.clear() ; + } +} //---------------------------------------------------------------------------- // Called from either the main thread or the worker thread -- cgit v1.2.3 From fdfc59da9bd8767001fb1b137da0c3a354c87a92 Mon Sep 17 00:00:00 2001 From: Xiaohong Bao Date: Wed, 10 Mar 2010 17:34:49 -0700 Subject: debug code for EXT-6093: crash at LLTextureCache::updateTextureEntryList [secondlife-bin lltexturecache.cpp:847] --- indra/newview/lltexturecache.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'indra/newview/lltexturecache.cpp') diff --git a/indra/newview/lltexturecache.cpp b/indra/newview/lltexturecache.cpp index 4649b9cbef..49770030c6 100644 --- a/indra/newview/lltexturecache.cpp +++ b/indra/newview/lltexturecache.cpp @@ -1140,6 +1140,10 @@ void LLTextureCache::writeEntryAndClose(S32 idx, Entry& entry) { mTexturesSizeMap[entry.mID] = entry.mBodySize; } + else if(mTexturesSizeMap.find(entry.mID) != mTexturesSizeMap.end() && mTexturesSizeMap[entry.mID] > 0) + { + llerrs << "mTexturesSizeMap / mHeaderIDMap corrupted." << llendl ; + } // llinfos << "Updating TE: " << idx << ": " << id << " Size: " << entry.mBodySize << " Time: " << entry.mTime << llendl; mHeaderEntriesMaxWriteIdx = llmax(mHeaderEntriesMaxWriteIdx, idx); mUpdatedEntryMap[idx] = entry ; @@ -1450,6 +1454,10 @@ void LLTextureCache::purgeTextures(bool validate) time_idx_set.insert(std::make_pair(entries[idx].mTime, idx)); // llinfos << "TIME: " << entries[idx].mTime << " TEX: " << entries[idx].mID << " IDX: " << idx << " Size: " << entries[idx].mImageSize << llendl; } + else + { + llerrs << "mTexturesSizeMap / mHeaderIDMap corrupted." << llendl ; + } } } -- cgit v1.2.3 From f8dc23fc84e624845181315bbadcbdc1f804c628 Mon Sep 17 00:00:00 2001 From: Xiaohong Bao Date: Wed, 17 Mar 2010 12:39:39 -0600 Subject: fix for EXT-6093: crash at LLTextureCache::updateTextureEntryList[secondlife-bin lltexturecache.cpp:847]; EXT-5711: Some textures loading from cache seems jammed; EXT-5599: Viewer crashes consistently, in Linden Homes region. --- indra/newview/lltexturecache.cpp | 268 +++++++++++++++++++++++---------------- 1 file changed, 162 insertions(+), 106 deletions(-) (limited to 'indra/newview/lltexturecache.cpp') diff --git a/indra/newview/lltexturecache.cpp b/indra/newview/lltexturecache.cpp index 49770030c6..48207dfd4d 100644 --- a/indra/newview/lltexturecache.cpp +++ b/indra/newview/lltexturecache.cpp @@ -550,7 +550,7 @@ bool LLTextureCacheRemoteWorker::doWrite() S32 cur_imagesize = 0; // Checks if this image is already in the entry list idx = mCache->getHeaderCacheEntry(mID, cur_imagesize); - if (idx >= 0 && (cur_imagesize >= 0)) + if (idx >= 0 && (cur_imagesize > 0)) { alreadyCached = true; // already there and non empty } @@ -846,9 +846,8 @@ bool LLTextureCache::updateTextureEntryList(const LLUUID& id, S32 bodysize) S32 idx = openAndReadEntry(id, entry, false); if (idx < 0) { - llwarns << "Failed to open entry: " << id << llendl; - removeHeaderCacheEntry(id); - LLAPRFile::remove(getTextureFileName(id), getLocalAPRFilePool()); + llwarns << "Failed to open entry: " << id << llendl; + removeCachedTexture(id) ; return false; } else if (oldbodysize != entry.mBodySize) @@ -857,11 +856,7 @@ bool LLTextureCache::updateTextureEntryList(const LLUUID& id, S32 bodysize) llerrs << "Entry mismatch in mTextureSizeMap / mHeaderIDMap" << " idx=" << idx << " oldsize=" << oldbodysize << " entrysize=" << entry.mBodySize << llendl; } - entry.mBodySize = bodysize; - writeEntryAndClose(idx, entry); - - mTexturesSizeTotal -= oldbodysize; - mTexturesSizeTotal += bodysize; + updateEntry(idx, entry, entry.mImageSize, bodysize); if (mTexturesSizeTotal > sCacheMaxTexturesSize) { @@ -1002,7 +997,10 @@ 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->seek(APR_SET, offset); + if(offset > 0) + { + mHeaderAPRFile->seek(APR_SET, offset); + } return mHeaderAPRFile; } @@ -1034,8 +1032,7 @@ void LLTextureCache::writeEntriesHeader() } } -static S32 mHeaderEntriesMaxWriteIdx = 0; - +//mHeaderMutex is locked before calling this. S32 LLTextureCache::openAndReadEntry(const LLUUID& id, Entry& entry, bool create) { S32 idx = -1; @@ -1075,8 +1072,7 @@ S32 LLTextureCache::openAndReadEntry(const LLUUID& id, Entry& entry, bool create if (iter3 != mHeaderIDMap.end() && iter3->second >= 0) { idx = iter3->second; - mHeaderIDMap.erase(oldid); - mTexturesSizeMap.erase(oldid); + removeCachedTexture(oldid) ;//remove the existing cached texture to release the entry index. break; } } @@ -1086,22 +1082,9 @@ S32 LLTextureCache::openAndReadEntry(const LLUUID& id, Entry& entry, bool create } if (idx >= 0) { - // Set the header index - mHeaderIDMap[id] = idx; - llassert_always(mTexturesSizeMap.erase(id) == 0); - // Initialize the entry (will get written later) - entry.init(id, time(NULL)); - // Update Header - writeEntriesHeader(); - - //the new entry, write immediately. - // Write Entry - S32 offset = sizeof(EntriesInfo) + idx * sizeof(Entry); - LLAPRFile* aprfile = openHeaderEntriesFile(false, offset); - S32 bytes_written = aprfile->write((void*)&entry, (S32)sizeof(Entry)); - llassert_always(bytes_written == sizeof(Entry)); - mHeaderEntriesMaxWriteIdx = llmax(mHeaderEntriesMaxWriteIdx, idx); - closeHeaderEntriesFile(); + entry.mID = id ; + entry.mImageSize = -1 ; //mark it is a brand-new entry. + entry.mBodySize = 0 ; } } } @@ -1117,36 +1100,108 @@ S32 LLTextureCache::openAndReadEntry(const LLUUID& id, Entry& entry, bool create } else { - S32 offset = sizeof(EntriesInfo) + idx * sizeof(Entry); - LLAPRFile* aprfile = openHeaderEntriesFile(true, offset); - S32 bytes_read = aprfile->read((void*)&entry, (S32)sizeof(Entry)); - llassert_always(bytes_read == sizeof(Entry)); - closeHeaderEntriesFile(); + readEntryFromHeaderImmediately(idx, entry) ; } - llassert_always(entry.mImageSize == 0 || entry.mImageSize == -1 || entry.mImageSize > entry.mBodySize); + llassert_always(entry.mImageSize > entry.mBodySize); } return idx; } -void LLTextureCache::writeEntryAndClose(S32 idx, Entry& entry) +//mHeaderMutex is locked before calling this. +void LLTextureCache::writeEntryToHeaderImmediately(S32 idx, Entry& entry, bool write_header) +{ + LLAPRFile* aprfile ; + S32 bytes_written ; + S32 offset = sizeof(EntriesInfo) + idx * sizeof(Entry); + if(write_header) + { + aprfile = openHeaderEntriesFile(false, 0); + bytes_written = aprfile->write((U8*)&mHeaderEntriesInfo, sizeof(EntriesInfo)) ; + llassert_always(bytes_written == sizeof(EntriesInfo)); + mHeaderAPRFile->seek(APR_SET, offset); + } + else + { + aprfile = openHeaderEntriesFile(false, offset); + } + bytes_written = aprfile->write((void*)&entry, (S32)sizeof(Entry)); + llassert_always(bytes_written == sizeof(Entry)); + closeHeaderEntriesFile(); + mUpdatedEntryMap.erase(idx) ; +} + +//mHeaderMutex is locked before calling this. +void LLTextureCache::readEntryFromHeaderImmediately(S32 idx, Entry& entry) +{ + S32 offset = sizeof(EntriesInfo) + idx * sizeof(Entry); + LLAPRFile* aprfile = openHeaderEntriesFile(true, offset); + S32 bytes_read = aprfile->read((void*)&entry, (S32)sizeof(Entry)); + llassert_always(bytes_read == sizeof(Entry)); + closeHeaderEntriesFile(); +} + +//mHeaderMutex is locked before calling this. +//update an existing entry time stamp, delay writing. +void LLTextureCache::updateEntryTimeStamp(S32 idx, Entry& entry) { + static const U32 MAX_ENTRIES_WITHOUT_TIME_STAMP = (U32)LLTextureCache::sCacheMaxEntries * 0.75f ; + + if(mHeaderEntriesInfo.mEntries < MAX_ENTRIES_WITHOUT_TIME_STAMP) + { + return ; //there are enough empty entry index space, no need to stamp time. + } + if (idx >= 0) { if (!mReadOnly) { - entry.mTime = time(NULL); - llassert_always(entry.mImageSize == 0 || entry.mImageSize == -1 || entry.mImageSize > entry.mBodySize); - if (entry.mBodySize > 0) + llassert_always(entry.mImageSize > entry.mBodySize); + + entry.mTime = time(NULL); + mUpdatedEntryMap[idx] = entry ; + } + } +} + +//mHeaderMutex is locked before calling this. +//update an existing entry, write to header file immediately. +void LLTextureCache::updateEntry(S32 idx, Entry& entry, S32 new_image_size, S32 new_body_size) +{ + llassert_always(new_image_size > -1) ; + + if(new_image_size == entry.mImageSize && new_body_size == entry.mBodySize) + { + updateEntryTimeStamp(idx, entry) ; //nothing changed. + } + else if (idx >= 0) + { + if (!mReadOnly) + { + llassert_always(new_image_size > new_body_size) ; + + bool update_header = false ; + if(entry.mImageSize < 0) //is a brand-new entry { - mTexturesSizeMap[entry.mID] = entry.mBodySize; - } - else if(mTexturesSizeMap.find(entry.mID) != mTexturesSizeMap.end() && mTexturesSizeMap[entry.mID] > 0) + mHeaderIDMap[entry.mID] = idx; + mTexturesSizeMap[entry.mID] = new_body_size ; + mTexturesSizeTotal += new_body_size ; + + // Update Header + update_header = true ; + } + else if (entry.mBodySize != new_body_size) { - llerrs << "mTexturesSizeMap / mHeaderIDMap corrupted." << llendl ; + //already in mHeaderIDMap. + mTexturesSizeMap[entry.mID] = new_body_size ; + mTexturesSizeTotal -= entry.mBodySize ; + mTexturesSizeTotal += new_body_size ; } -// llinfos << "Updating TE: " << idx << ": " << id << " Size: " << entry.mBodySize << " Time: " << entry.mTime << llendl; - mHeaderEntriesMaxWriteIdx = llmax(mHeaderEntriesMaxWriteIdx, idx); - mUpdatedEntryMap[idx] = entry ; + entry.mTime = time(NULL); + entry.mImageSize = new_image_size ; + entry.mBodySize = new_body_size ; + +// llinfos << "Updating TE: " << idx << ": " << id << " Size: " << entry.mBodySize << " Time: " << entry.mTime << llendl; + writeEntryToHeaderImmediately(idx, entry, update_header) ; } } } @@ -1160,8 +1215,9 @@ U32 LLTextureCache::openAndReadEntries(std::vector& entries) mFreeList.clear(); mTexturesSizeTotal = 0; - LLAPRFile* aprfile = openHeaderEntriesFile(false, (S32)sizeof(EntriesInfo)); + LLAPRFile* aprfile = openHeaderEntriesFile(true, 0); updatedHeaderEntriesFile() ; + aprfile->seek(APR_SET, (S32)sizeof(EntriesInfo)); for (U32 idx=0; idx& entries) } entries.push_back(entry); // llinfos << "ENTRY: " << entry.mTime << " TEX: " << entry.mID << " IDX: " << idx << " Size: " << entry.mImageSize << llendl; - if (entry.mImageSize < 0) + if(entry.mImageSize > entry.mBodySize) { - mFreeList.insert(idx); + mHeaderIDMap[entry.mID] = idx; + mTexturesSizeMap[entry.mID] = entry.mBodySize; + mTexturesSizeTotal += entry.mBodySize; } else { - mHeaderIDMap[entry.mID] = idx; - if (entry.mBodySize > 0) - { - mTexturesSizeMap[entry.mID] = entry.mBodySize; - mTexturesSizeTotal += entry.mBodySize; - } - llassert_always(entry.mImageSize == 0 || entry.mImageSize > entry.mBodySize); + mFreeList.insert(idx); } } closeHeaderEntriesFile(); @@ -1207,7 +1259,6 @@ void LLTextureCache::writeEntriesAndClose(const std::vector& entries) S32 bytes_written = aprfile->write((void*)(&entries[idx]), (S32)sizeof(Entry)); llassert_always(bytes_written == sizeof(Entry)); } - mHeaderEntriesMaxWriteIdx = llmax(mHeaderEntriesMaxWriteIdx, num_entries-1); closeHeaderEntriesFile(); } } @@ -1280,12 +1331,11 @@ void LLTextureCache::readHeaderCache() U32 empty_entries = 0; typedef std::pair lru_data_t; std::set lru; - std::set purge_list; + std::set purge_list; for (U32 i=0; i entry.mImageSize) { // Shouldn't happen, failsafe only - llwarns << "Bad entry: " << i << ": " << id << ": BodySize: " << entry.mBodySize << llendl; - purge_list.insert(entry.mID); - entry.mImageSize = -1; // empty/available + llwarns << "Bad entry: " << i << ": " << entry.mID << ": BodySize: " << entry.mBodySize << llendl; + purge_list.insert(i); } } } @@ -1315,14 +1364,9 @@ void LLTextureCache::readHeaderCache() { for (std::set::iterator iter = lru.begin(); iter != lru.end(); ++iter) { - 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; - } + purge_list.insert(iter->second); + if (purge_list.size() >= entries_to_purge) + break; } } llassert_always(purge_list.size() >= entries_to_purge); @@ -1332,9 +1376,7 @@ void LLTextureCache::readHeaderCache() S32 lru_entries = (S32)((F32)sCacheMaxEntries * TEXTURE_CACHE_LRU_SIZE); for (std::set::iterator iter = lru.begin(); iter != lru.end(); ++iter) { - S32 idx = iter->second; - const LLUUID& id = entries[idx].mID; - mLRU.insert(id); + mLRU.insert(entries[iter->second].mID); // llinfos << "LRU: " << iter->first << " : " << iter->second << llendl; if (--lru_entries <= 0) break; @@ -1343,12 +1385,9 @@ void LLTextureCache::readHeaderCache() if (purge_list.size() > 0) { - for (std::set::iterator iter = purge_list.begin(); iter != purge_list.end(); ++iter) + for (std::set::iterator iter = purge_list.begin(); iter != purge_list.end(); ++iter) { - const LLUUID& id = *iter; - bool res = removeHeaderCacheEntry(id); // sets entry size on disk to -1 - llassert_always(res); - LLAPRFile::remove(getTextureFileName(id), getLocalAPRFilePool()); + removeEntry(*iter, entries[*iter], getTextureFileName(entries[*iter].mID)); } // If we removed any entries, we need to rebuild the entries list, // write the header, and call this again @@ -1356,13 +1395,14 @@ void LLTextureCache::readHeaderCache() for (U32 i=0; i=0) + if (entry.mImageSize > 0) { new_entries.push_back(entry); } } llassert_always(new_entries.size() <= sCacheMaxEntries); mHeaderEntriesInfo.mEntries = new_entries.size(); + writeEntriesHeader(); writeEntriesAndClose(new_entries); mHeaderMutex.unlock(); // unlock the mutex before calling again readHeaderCache(); // repeat with new entries file @@ -1370,7 +1410,7 @@ void LLTextureCache::readHeaderCache() } else { - writeEntriesAndClose(entries); + //entries are not changed, nothing here. } } } @@ -1435,7 +1475,6 @@ void LLTextureCache::purgeTextures(bool validate) U32 num_entries = openAndReadEntries(entries); if (!num_entries) { - writeEntriesAndClose(entries); return; // nothing to purge } @@ -1509,11 +1548,8 @@ void LLTextureCache::purgeTextures(bool validate) { purge_count++; LL_DEBUGS("TextureCache") << "PURGING: " << filename << LL_ENDL; - LLAPRFile::remove(filename, getLocalAPRFilePool()); + removeEntry(idx, entries[idx], filename) ; cache_size -= entries[idx].mBodySize; - mTexturesSizeTotal -= entries[idx].mBodySize; - entries[idx].mBodySize = 0; - mTexturesSizeMap.erase(entries[idx].mID); } } @@ -1568,7 +1604,7 @@ S32 LLTextureCache::getHeaderCacheEntry(const LLUUID& id, S32& imagesize) if (idx >= 0) { imagesize = entry.mImageSize; - writeEntryAndClose(idx, entry); // updates time + updateEntryTimeStamp(idx, entry); // updates time } return idx; } @@ -1582,8 +1618,7 @@ S32 LLTextureCache::setHeaderCacheEntry(const LLUUID& id, S32 imagesize) S32 idx = openAndReadEntry(id, entry, true); if (idx >= 0) { - entry.mImageSize = imagesize; - writeEntryAndClose(idx, entry); + updateEntry(idx, entry, imagesize, entry.mBodySize); mHeaderMutex.unlock(); } else // retry @@ -1722,34 +1757,55 @@ void LLTextureCache::addCompleted(Responder* responder, bool success) ////////////////////////////////////////////////////////////////////////////// -// Called from MAIN thread (endWork()) -// Ensure that mHeaderMutex is locked first! -bool LLTextureCache::removeHeaderCacheEntry(const LLUUID& id) +//called after mHeaderMutex is locked. +void LLTextureCache::removeCachedTexture(const LLUUID& id) { - Entry entry; - S32 idx = openAndReadEntry(id, entry, false); - if (idx >= 0) + if(mTexturesSizeMap.find(id) != mTexturesSizeMap.end()) + { + mTexturesSizeTotal -= mTexturesSizeMap[id] ; + mTexturesSizeMap.erase(id); + } + mHeaderIDMap.erase(id); + LLAPRFile::remove(getTextureFileName(id), getLocalAPRFilePool()); +} + +//called after mHeaderMutex is locked. +void LLTextureCache::removeEntry(S32 idx, Entry& entry, std::string& filename) +{ + if(idx >= 0) //valid entry { entry.mImageSize = -1; entry.mBodySize = 0; - writeEntryAndClose(idx, entry); - mFreeList.insert(idx); - mHeaderIDMap.erase(id); - mTexturesSizeMap.erase(id); - return true; + mHeaderIDMap.erase(entry.mID); + mTexturesSizeMap.erase(entry.mID); + + mTexturesSizeTotal -= entry.mBodySize; + mFreeList.insert(idx); } - return false; + + LLAPRFile::remove(filename, getLocalAPRFilePool()); } -void LLTextureCache::removeFromCache(const LLUUID& id) +bool LLTextureCache::removeFromCache(const LLUUID& id) { //llwarns << "Removing texture from cache: " << id << llendl; + bool ret = false ; if (!mReadOnly) { - LLMutexLock lock(&mHeaderMutex); - removeHeaderCacheEntry(id); - LLAPRFile::remove(getTextureFileName(id), getLocalAPRFilePool()); + lockHeaders() ; + + Entry entry; + S32 idx = openAndReadEntry(id, entry, false); + removeEntry(idx, entry, getTextureFileName(id)) ; + if (idx >= 0) + { + writeEntryToHeaderImmediately(idx, entry); + ret = true; + } + + unlockHeaders() ; } + return ret ; } ////////////////////////////////////////////////////////////////////////////// -- cgit v1.2.3 From 8e1f7ecaf3b1eebc1ca60ecb6e04412f39083d82 Mon Sep 17 00:00:00 2001 From: Xiaohong Bao Date: Wed, 17 Mar 2010 14:43:17 -0600 Subject: more for lltexturecache.cpp: fix the crash due to deleting the entries header file after clearing the texture cache. --- indra/newview/lltexturecache.cpp | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'indra/newview/lltexturecache.cpp') diff --git a/indra/newview/lltexturecache.cpp b/indra/newview/lltexturecache.cpp index 48207dfd4d..54ac3850fd 100644 --- a/indra/newview/lltexturecache.cpp +++ b/indra/newview/lltexturecache.cpp @@ -1020,6 +1020,12 @@ void LLTextureCache::readEntriesHeader() LLAPRFile::readEx(mHeaderEntriesFileName, (U8*)&mHeaderEntriesInfo, 0, sizeof(EntriesInfo), getLocalAPRFilePool()); } + else //create an empty entries header. + { + mHeaderEntriesInfo.mVersion = sHeaderCacheVersion ; + mHeaderEntriesInfo.mEntries = 0 ; + writeEntriesHeader() ; + } } void LLTextureCache::writeEntriesHeader() @@ -1438,6 +1444,7 @@ void LLTextureCache::purgeAllTextures(bool purge_directories) } if (purge_directories) { + gDirUtilp->deleteFilesInDir(mTexturesDirName,mask); LLFile::rmdir(mTexturesDirName); } } -- cgit v1.2.3 From af721d3f54c02e6d6202b0165978db72134eb14f Mon Sep 17 00:00:00 2001 From: "Nyx (Neal Orman)" Date: Thu, 18 Mar 2010 16:10:24 -0400 Subject: fixing linux build errors from bao's checkin for EXT-6093 viewer wouldn't compile under linux, due to gcc being paranoid about a few things. Fixed them up and got them reviewed. Code reviewed by bao. --- indra/newview/lltexturecache.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'indra/newview/lltexturecache.cpp') diff --git a/indra/newview/lltexturecache.cpp b/indra/newview/lltexturecache.cpp index 54ac3850fd..7a0712f8aa 100644 --- a/indra/newview/lltexturecache.cpp +++ b/indra/newview/lltexturecache.cpp @@ -1150,7 +1150,7 @@ void LLTextureCache::readEntryFromHeaderImmediately(S32 idx, Entry& entry) //update an existing entry time stamp, delay writing. void LLTextureCache::updateEntryTimeStamp(S32 idx, Entry& entry) { - static const U32 MAX_ENTRIES_WITHOUT_TIME_STAMP = (U32)LLTextureCache::sCacheMaxEntries * 0.75f ; + static const U32 MAX_ENTRIES_WITHOUT_TIME_STAMP = (U32)(LLTextureCache::sCacheMaxEntries * 0.75f) ; if(mHeaderEntriesInfo.mEntries < MAX_ENTRIES_WITHOUT_TIME_STAMP) { @@ -1393,7 +1393,8 @@ void LLTextureCache::readHeaderCache() { for (std::set::iterator iter = purge_list.begin(); iter != purge_list.end(); ++iter) { - removeEntry(*iter, entries[*iter], getTextureFileName(entries[*iter].mID)); + std::string tex_filename = getTextureFileName(entries[*iter].mID); + removeEntry((S32)*iter, entries[*iter], tex_filename); } // If we removed any entries, we need to rebuild the entries list, // write the header, and call this again @@ -1803,7 +1804,8 @@ bool LLTextureCache::removeFromCache(const LLUUID& id) Entry entry; S32 idx = openAndReadEntry(id, entry, false); - removeEntry(idx, entry, getTextureFileName(id)) ; + std::string tex_filename = getTextureFileName(id); + removeEntry(idx, entry, tex_filename) ; if (idx >= 0) { writeEntryToHeaderImmediately(idx, entry); -- cgit v1.2.3