Skip to content
Snippets Groups Projects
Commit 4682264e authored by Xiaohong Bao's avatar Xiaohong Bao
Browse files

EXT-8447: FIXED: crash at...

EXT-8447: FIXED: crash at LLTextureCache::writeEntryToHeaderImmediately(int,LLTextureCache::Entry &,bool) [secondlife-bin lltexturecache.cpp]
parent 0e673902
No related branches found
No related tags found
No related merge requests found
...@@ -417,7 +417,11 @@ apr_pool_t* LLAPRFile::getAPRFilePool(apr_pool_t* pool) ...@@ -417,7 +417,11 @@ apr_pool_t* LLAPRFile::getAPRFilePool(apr_pool_t* pool)
// File I/O // File I/O
S32 LLAPRFile::read(void *buf, S32 nbytes) S32 LLAPRFile::read(void *buf, S32 nbytes)
{ {
llassert_always(mFile) ; if(!mFile)
{
llwarns << "apr mFile is removed by somebody else. Can not read." << llendl ;
return 0;
}
apr_size_t sz = nbytes; apr_size_t sz = nbytes;
apr_status_t s = apr_file_read(mFile, buf, &sz); apr_status_t s = apr_file_read(mFile, buf, &sz);
...@@ -435,7 +439,11 @@ S32 LLAPRFile::read(void *buf, S32 nbytes) ...@@ -435,7 +439,11 @@ S32 LLAPRFile::read(void *buf, S32 nbytes)
S32 LLAPRFile::write(const void *buf, S32 nbytes) S32 LLAPRFile::write(const void *buf, S32 nbytes)
{ {
llassert_always(mFile) ; if(!mFile)
{
llwarns << "apr mFile is removed by somebody else. Can not write." << llendl ;
return 0;
}
apr_size_t sz = nbytes; apr_size_t sz = nbytes;
apr_status_t s = apr_file_write(mFile, buf, &sz); apr_status_t s = apr_file_write(mFile, buf, &sz);
......
...@@ -998,7 +998,11 @@ LLAPRFile* LLTextureCache::openHeaderEntriesFile(bool readonly, S32 offset) ...@@ -998,7 +998,11 @@ LLAPRFile* LLTextureCache::openHeaderEntriesFile(bool readonly, S32 offset)
void LLTextureCache::closeHeaderEntriesFile() void LLTextureCache::closeHeaderEntriesFile()
{ {
llassert_always(mHeaderAPRFile != NULL); if(!mHeaderAPRFile)
{
return ;
}
delete mHeaderAPRFile; delete mHeaderAPRFile;
mHeaderAPRFile = NULL; mHeaderAPRFile = NULL;
} }
...@@ -1115,7 +1119,7 @@ S32 LLTextureCache::openAndReadEntry(const LLUUID& id, Entry& entry, bool create ...@@ -1115,7 +1119,7 @@ S32 LLTextureCache::openAndReadEntry(const LLUUID& id, Entry& entry, bool create
} }
//mHeaderMutex is locked before calling this. //mHeaderMutex is locked before calling this.
void LLTextureCache::writeEntryToHeaderImmediately(S32 idx, Entry& entry, bool write_header) void LLTextureCache::writeEntryToHeaderImmediately(S32& idx, Entry& entry, bool write_header)
{ {
LLAPRFile* aprfile ; LLAPRFile* aprfile ;
S32 bytes_written ; S32 bytes_written ;
...@@ -1124,7 +1128,13 @@ void LLTextureCache::writeEntryToHeaderImmediately(S32 idx, Entry& entry, bool w ...@@ -1124,7 +1128,13 @@ void LLTextureCache::writeEntryToHeaderImmediately(S32 idx, Entry& entry, bool w
{ {
aprfile = openHeaderEntriesFile(false, 0); aprfile = openHeaderEntriesFile(false, 0);
bytes_written = aprfile->write((U8*)&mHeaderEntriesInfo, sizeof(EntriesInfo)) ; bytes_written = aprfile->write((U8*)&mHeaderEntriesInfo, sizeof(EntriesInfo)) ;
llassert_always(bytes_written == sizeof(EntriesInfo)); if(bytes_written != sizeof(EntriesInfo))
{
clearCorruptedCache() ; //clear the cache.
idx = -1 ;//mark the idx invalid.
return ;
}
mHeaderAPRFile->seek(APR_SET, offset); mHeaderAPRFile->seek(APR_SET, offset);
} }
else else
...@@ -1132,19 +1142,31 @@ void LLTextureCache::writeEntryToHeaderImmediately(S32 idx, Entry& entry, bool w ...@@ -1132,19 +1142,31 @@ void LLTextureCache::writeEntryToHeaderImmediately(S32 idx, Entry& entry, bool w
aprfile = openHeaderEntriesFile(false, offset); aprfile = openHeaderEntriesFile(false, offset);
} }
bytes_written = aprfile->write((void*)&entry, (S32)sizeof(Entry)); bytes_written = aprfile->write((void*)&entry, (S32)sizeof(Entry));
llassert_always(bytes_written == sizeof(Entry)); if(bytes_written != sizeof(Entry))
{
clearCorruptedCache() ; //clear the cache.
idx = -1 ;//mark the idx invalid.
return ;
}
closeHeaderEntriesFile(); closeHeaderEntriesFile();
mUpdatedEntryMap.erase(idx) ; mUpdatedEntryMap.erase(idx) ;
} }
//mHeaderMutex is locked before calling this. //mHeaderMutex is locked before calling this.
void LLTextureCache::readEntryFromHeaderImmediately(S32 idx, Entry& entry) void LLTextureCache::readEntryFromHeaderImmediately(S32& idx, Entry& entry)
{ {
S32 offset = sizeof(EntriesInfo) + idx * sizeof(Entry); S32 offset = sizeof(EntriesInfo) + idx * sizeof(Entry);
LLAPRFile* aprfile = openHeaderEntriesFile(true, offset); LLAPRFile* aprfile = openHeaderEntriesFile(true, offset);
S32 bytes_read = aprfile->read((void*)&entry, (S32)sizeof(Entry)); S32 bytes_read = aprfile->read((void*)&entry, (S32)sizeof(Entry));
llassert_always(bytes_read == sizeof(Entry));
closeHeaderEntriesFile(); closeHeaderEntriesFile();
if(bytes_read != sizeof(Entry))
{
clearCorruptedCache() ; //clear the cache.
idx = -1 ;//mark the idx invalid.
}
} }
//mHeaderMutex is locked before calling this. //mHeaderMutex is locked before calling this.
...@@ -1169,7 +1191,7 @@ void LLTextureCache::updateEntryTimeStamp(S32 idx, Entry& entry) ...@@ -1169,7 +1191,7 @@ void LLTextureCache::updateEntryTimeStamp(S32 idx, Entry& entry)
} }
//update an existing entry, write to header file immediately. //update an existing entry, write to header file immediately.
bool LLTextureCache::updateEntry(S32 idx, Entry& entry, S32 new_image_size, S32 new_data_size) bool LLTextureCache::updateEntry(S32& idx, Entry& entry, S32 new_image_size, S32 new_data_size)
{ {
S32 new_body_size = llmax(0, new_data_size - TEXTURE_CACHE_ENTRY_SIZE) ; S32 new_body_size = llmax(0, new_data_size - TEXTURE_CACHE_ENTRY_SIZE) ;
...@@ -1240,6 +1262,10 @@ U32 LLTextureCache::openAndReadEntries(std::vector<Entry>& entries) ...@@ -1240,6 +1262,10 @@ U32 LLTextureCache::openAndReadEntries(std::vector<Entry>& entries)
{ {
aprfile = openHeaderEntriesFile(false, 0); aprfile = openHeaderEntriesFile(false, 0);
updatedHeaderEntriesFile() ; updatedHeaderEntriesFile() ;
if(!aprfile)
{
return 0;
}
aprfile->seek(APR_SET, (S32)sizeof(EntriesInfo)); aprfile->seek(APR_SET, (S32)sizeof(EntriesInfo));
} }
for (U32 idx=0; idx<num_entries; idx++) for (U32 idx=0; idx<num_entries; idx++)
...@@ -1281,7 +1307,11 @@ void LLTextureCache::writeEntriesAndClose(const std::vector<Entry>& entries) ...@@ -1281,7 +1307,11 @@ void LLTextureCache::writeEntriesAndClose(const std::vector<Entry>& entries)
for (S32 idx=0; idx<num_entries; idx++) for (S32 idx=0; idx<num_entries; idx++)
{ {
S32 bytes_written = aprfile->write((void*)(&entries[idx]), (S32)sizeof(Entry)); S32 bytes_written = aprfile->write((void*)(&entries[idx]), (S32)sizeof(Entry));
llassert_always(bytes_written == sizeof(Entry)); if(bytes_written != sizeof(Entry))
{
clearCorruptedCache() ; //clear the cache.
return ;
}
} }
closeHeaderEntriesFile(); closeHeaderEntriesFile();
} }
...@@ -1307,7 +1337,11 @@ void LLTextureCache::updatedHeaderEntriesFile() ...@@ -1307,7 +1337,11 @@ void LLTextureCache::updatedHeaderEntriesFile()
//entriesInfo //entriesInfo
mHeaderAPRFile->seek(APR_SET, 0); mHeaderAPRFile->seek(APR_SET, 0);
S32 bytes_written = mHeaderAPRFile->write((U8*)&mHeaderEntriesInfo, sizeof(EntriesInfo)) ; S32 bytes_written = mHeaderAPRFile->write((U8*)&mHeaderEntriesInfo, sizeof(EntriesInfo)) ;
llassert_always(bytes_written == sizeof(EntriesInfo)); if(bytes_written != sizeof(EntriesInfo))
{
clearCorruptedCache() ; //clear the cache.
return ;
}
//write each updated entry //write each updated entry
S32 entry_size = (S32)sizeof(Entry) ; S32 entry_size = (S32)sizeof(Entry) ;
...@@ -1323,7 +1357,11 @@ void LLTextureCache::updatedHeaderEntriesFile() ...@@ -1323,7 +1357,11 @@ void LLTextureCache::updatedHeaderEntriesFile()
} }
bytes_written = mHeaderAPRFile->write((void*)(&iter->second), entry_size); bytes_written = mHeaderAPRFile->write((void*)(&iter->second), entry_size);
llassert_always(bytes_written == entry_size); if(bytes_written != entry_size)
{
clearCorruptedCache() ; //clear the cache.
return ;
}
} }
mUpdatedEntryMap.clear() ; mUpdatedEntryMap.clear() ;
} }
...@@ -1444,6 +1482,29 @@ void LLTextureCache::readHeaderCache() ...@@ -1444,6 +1482,29 @@ void LLTextureCache::readHeaderCache()
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
//the header mutex is locked before calling this.
void LLTextureCache::clearCorruptedCache()
{
llwarns << "the texture cache is corrupted, need to be cleared." << llendl ;
closeHeaderEntriesFile();//close possible file handler
purgeAllTextures(false) ; //clear the cache.
if (!mReadOnly) //regenerate the directory tree if not exists.
{
LLFile::mkdir(mTexturesDirName);
const char* subdirs = "0123456789abcdef";
for (S32 i=0; i<16; i++)
{
std::string dirname = mTexturesDirName + gDirUtilp->getDirDelimiter() + subdirs[i];
LLFile::mkdir(dirname);
}
}
return ;
}
void LLTextureCache::purgeAllTextures(bool purge_directories) void LLTextureCache::purgeAllTextures(bool purge_directories)
{ {
if (!mReadOnly) if (!mReadOnly)
...@@ -1472,11 +1533,14 @@ void LLTextureCache::purgeAllTextures(bool purge_directories) ...@@ -1472,11 +1533,14 @@ void LLTextureCache::purgeAllTextures(bool purge_directories)
mTexturesSizeTotal = 0; mTexturesSizeTotal = 0;
mFreeList.clear(); mFreeList.clear();
mTexturesSizeTotal = 0; mTexturesSizeTotal = 0;
mUpdatedEntryMap.clear();
// Info with 0 entries // Info with 0 entries
mHeaderEntriesInfo.mVersion = sHeaderCacheVersion; mHeaderEntriesInfo.mVersion = sHeaderCacheVersion;
mHeaderEntriesInfo.mEntries = 0; mHeaderEntriesInfo.mEntries = 0;
writeEntriesHeader(); writeEntriesHeader();
llinfos << "The entire texture cache is cleared." << llendl ;
} }
void LLTextureCache::purgeTextures(bool validate) void LLTextureCache::purgeTextures(bool validate)
...@@ -1644,7 +1708,8 @@ S32 LLTextureCache::setHeaderCacheEntry(const LLUUID& id, Entry& entry, S32 imag ...@@ -1644,7 +1708,8 @@ S32 LLTextureCache::setHeaderCacheEntry(const LLUUID& id, Entry& entry, S32 imag
{ {
updateEntry(idx, entry, imagesize, datasize); updateEntry(idx, entry, imagesize, datasize);
} }
else // retry
if(idx < 0) // retry
{ {
readHeaderCache(); // We couldn't write an entry, so refresh the LRU readHeaderCache(); // We couldn't write an entry, so refresh the LRU
......
...@@ -154,6 +154,7 @@ class LLTextureCache : public LLWorkerThread ...@@ -154,6 +154,7 @@ class LLTextureCache : public LLWorkerThread
private: private:
void setDirNames(ELLPath location); void setDirNames(ELLPath location);
void readHeaderCache(); void readHeaderCache();
void clearCorruptedCache();
void purgeAllTextures(bool purge_directories); void purgeAllTextures(bool purge_directories);
void purgeTextures(bool validate); void purgeTextures(bool validate);
LLAPRFile* openHeaderEntriesFile(bool readonly, S32 offset); LLAPRFile* openHeaderEntriesFile(bool readonly, S32 offset);
...@@ -161,12 +162,12 @@ class LLTextureCache : public LLWorkerThread ...@@ -161,12 +162,12 @@ class LLTextureCache : public LLWorkerThread
void readEntriesHeader(); void readEntriesHeader();
void writeEntriesHeader(); void writeEntriesHeader();
S32 openAndReadEntry(const LLUUID& id, Entry& entry, bool create); S32 openAndReadEntry(const LLUUID& id, Entry& entry, bool create);
bool updateEntry(S32 idx, Entry& entry, S32 new_image_size, S32 new_body_size); bool updateEntry(S32& idx, Entry& entry, S32 new_image_size, S32 new_body_size);
void updateEntryTimeStamp(S32 idx, Entry& entry) ; void updateEntryTimeStamp(S32 idx, Entry& entry) ;
U32 openAndReadEntries(std::vector<Entry>& entries); U32 openAndReadEntries(std::vector<Entry>& entries);
void writeEntriesAndClose(const std::vector<Entry>& entries); void writeEntriesAndClose(const std::vector<Entry>& entries);
void readEntryFromHeaderImmediately(S32 idx, Entry& entry) ; void readEntryFromHeaderImmediately(S32& idx, Entry& entry) ;
void writeEntryToHeaderImmediately(S32 idx, Entry& entry, bool write_header = false) ; void writeEntryToHeaderImmediately(S32& idx, Entry& entry, bool write_header = false) ;
void removeEntry(S32 idx, Entry& entry, std::string& filename); void removeEntry(S32 idx, Entry& entry, std::string& filename);
void removeCachedTexture(const LLUUID& id) ; void removeCachedTexture(const LLUUID& id) ;
S32 getHeaderCacheEntry(const LLUUID& id, Entry& entry); S32 getHeaderCacheEntry(const LLUUID& id, Entry& entry);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment