Skip to content
Snippets Groups Projects
Commit f36bd31b authored by Xiaohong Bao's avatar Xiaohong Bao
Browse files
parents 0a3493db 4682264e
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)
// File I/O
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_status_t s = apr_file_read(mFile, buf, &sz);
......@@ -435,7 +439,11 @@ S32 LLAPRFile::read(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_status_t s = apr_file_write(mFile, buf, &sz);
......
......@@ -998,7 +998,11 @@ LLAPRFile* LLTextureCache::openHeaderEntriesFile(bool readonly, S32 offset)
void LLTextureCache::closeHeaderEntriesFile()
{
llassert_always(mHeaderAPRFile != NULL);
if(!mHeaderAPRFile)
{
return ;
}
delete mHeaderAPRFile;
mHeaderAPRFile = NULL;
}
......@@ -1115,7 +1119,7 @@ S32 LLTextureCache::openAndReadEntry(const LLUUID& id, Entry& entry, bool create
}
//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 ;
S32 bytes_written ;
......@@ -1124,7 +1128,13 @@ void LLTextureCache::writeEntryToHeaderImmediately(S32 idx, Entry& entry, bool w
{
aprfile = openHeaderEntriesFile(false, 0);
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);
}
else
......@@ -1132,19 +1142,31 @@ void LLTextureCache::writeEntryToHeaderImmediately(S32 idx, Entry& entry, bool w
aprfile = openHeaderEntriesFile(false, offset);
}
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();
mUpdatedEntryMap.erase(idx) ;
}
//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);
LLAPRFile* aprfile = openHeaderEntriesFile(true, offset);
S32 bytes_read = aprfile->read((void*)&entry, (S32)sizeof(Entry));
llassert_always(bytes_read == sizeof(Entry));
closeHeaderEntriesFile();
if(bytes_read != sizeof(Entry))
{
clearCorruptedCache() ; //clear the cache.
idx = -1 ;//mark the idx invalid.
}
}
//mHeaderMutex is locked before calling this.
......@@ -1169,7 +1191,7 @@ void LLTextureCache::updateEntryTimeStamp(S32 idx, Entry& entry)
}
//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) ;
......@@ -1240,6 +1262,10 @@ U32 LLTextureCache::openAndReadEntries(std::vector<Entry>& entries)
{
aprfile = openHeaderEntriesFile(false, 0);
updatedHeaderEntriesFile() ;
if(!aprfile)
{
return 0;
}
aprfile->seek(APR_SET, (S32)sizeof(EntriesInfo));
}
for (U32 idx=0; idx<num_entries; idx++)
......@@ -1281,7 +1307,11 @@ void LLTextureCache::writeEntriesAndClose(const std::vector<Entry>& entries)
for (S32 idx=0; idx<num_entries; idx++)
{
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();
}
......@@ -1307,7 +1337,11 @@ void LLTextureCache::updatedHeaderEntriesFile()
//entriesInfo
mHeaderAPRFile->seek(APR_SET, 0);
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
S32 entry_size = (S32)sizeof(Entry) ;
......@@ -1323,7 +1357,11 @@ void LLTextureCache::updatedHeaderEntriesFile()
}
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() ;
}
......@@ -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)
{
if (!mReadOnly)
......@@ -1472,11 +1533,14 @@ void LLTextureCache::purgeAllTextures(bool purge_directories)
mTexturesSizeTotal = 0;
mFreeList.clear();
mTexturesSizeTotal = 0;
mUpdatedEntryMap.clear();
// Info with 0 entries
mHeaderEntriesInfo.mVersion = sHeaderCacheVersion;
mHeaderEntriesInfo.mEntries = 0;
writeEntriesHeader();
llinfos << "The entire texture cache is cleared." << llendl ;
}
void LLTextureCache::purgeTextures(bool validate)
......@@ -1644,7 +1708,8 @@ S32 LLTextureCache::setHeaderCacheEntry(const LLUUID& id, Entry& entry, S32 imag
{
updateEntry(idx, entry, imagesize, datasize);
}
else // retry
if(idx < 0) // retry
{
readHeaderCache(); // We couldn't write an entry, so refresh the LRU
......
......@@ -154,6 +154,7 @@ class LLTextureCache : public LLWorkerThread
private:
void setDirNames(ELLPath location);
void readHeaderCache();
void clearCorruptedCache();
void purgeAllTextures(bool purge_directories);
void purgeTextures(bool validate);
LLAPRFile* openHeaderEntriesFile(bool readonly, S32 offset);
......@@ -161,12 +162,12 @@ class LLTextureCache : public LLWorkerThread
void readEntriesHeader();
void writeEntriesHeader();
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) ;
U32 openAndReadEntries(std::vector<Entry>& entries);
void writeEntriesAndClose(const std::vector<Entry>& entries);
void readEntryFromHeaderImmediately(S32 idx, Entry& entry) ;
void writeEntryToHeaderImmediately(S32 idx, Entry& entry, bool write_header = false) ;
void readEntryFromHeaderImmediately(S32& idx, Entry& entry) ;
void writeEntryToHeaderImmediately(S32& idx, Entry& entry, bool write_header = false) ;
void removeEntry(S32 idx, Entry& entry, std::string& filename);
void removeCachedTexture(const LLUUID& id) ;
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