fix for SH-367: mesh viewer lock up: Problem removing object.cache - errorcode: 13
parent
da244c7cce
commit
57065fe5a9
|
|
@ -101,10 +101,18 @@ S32 LLDir::deleteFilesInDir(const std::string &dirname, const std::string &mask)
|
|||
{
|
||||
if (0 != LLFile::remove(fullpath))
|
||||
{
|
||||
retry_count++;
|
||||
result = errno;
|
||||
llwarns << "Problem removing " << fullpath << " - errorcode: "
|
||||
<< result << " attempt " << retry_count << llendl;
|
||||
ms_sleep(1000);
|
||||
|
||||
if(retry_count >= 5)
|
||||
{
|
||||
llwarns << "Failed to remove " << fullpath << llendl ;
|
||||
return count ;
|
||||
}
|
||||
|
||||
ms_sleep(100);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -113,8 +121,7 @@ S32 LLDir::deleteFilesInDir(const std::string &dirname, const std::string &mask)
|
|||
llwarns << "Successfully removed " << fullpath << llendl;
|
||||
}
|
||||
break;
|
||||
}
|
||||
retry_count++;
|
||||
}
|
||||
}
|
||||
count++;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -325,6 +325,8 @@ void LLVOCache::removeCache(ELLPath location)
|
|||
return ;
|
||||
}
|
||||
|
||||
llinfos << "about to remove the object cache due to settings." << llendl ;
|
||||
|
||||
std::string delem = gDirUtilp->getDirDelimiter();
|
||||
std::string mask = delem + "*";
|
||||
std::string cache_dir = gDirUtilp->getExpandedFilename(location, object_cache_dirname);
|
||||
|
|
@ -343,6 +345,8 @@ void LLVOCache::removeCache()
|
|||
return ;
|
||||
}
|
||||
|
||||
llinfos << "about to remove the object cache due to some error." << llendl ;
|
||||
|
||||
std::string delem = gDirUtilp->getDirDelimiter();
|
||||
std::string mask = delem + "*";
|
||||
gDirUtilp->deleteFilesInDir(mObjectCacheDirName, mask);
|
||||
|
|
@ -351,6 +355,43 @@ void LLVOCache::removeCache()
|
|||
writeCacheHeader();
|
||||
}
|
||||
|
||||
void LLVOCache::removeEntry(HeaderEntryInfo* entry)
|
||||
{
|
||||
llassert_always(mInitialized) ;
|
||||
if(mReadOnly)
|
||||
{
|
||||
return ;
|
||||
}
|
||||
if(!entry)
|
||||
{
|
||||
return ;
|
||||
}
|
||||
|
||||
header_entry_queue_t::iterator iter = mHeaderEntryQueue.find(entry) ;
|
||||
if(iter != mHeaderEntryQueue.end())
|
||||
{
|
||||
removeFromCache(entry->mHandle) ;
|
||||
mHandleEntryMap.erase(entry->mHandle) ;
|
||||
mHeaderEntryQueue.erase(iter) ;
|
||||
delete entry ;
|
||||
|
||||
writeCacheHeader() ;
|
||||
readCacheHeader() ;
|
||||
mNumEntries = mHandleEntryMap.size() ;
|
||||
}
|
||||
}
|
||||
|
||||
void LLVOCache::removeEntry(U64 handle)
|
||||
{
|
||||
handle_entry_map_t::iterator iter = mHandleEntryMap.find(handle) ;
|
||||
if(iter == mHandleEntryMap.end()) //no cache
|
||||
{
|
||||
return ;
|
||||
}
|
||||
HeaderEntryInfo* entry = iter->second ;
|
||||
removeEntry(entry) ;
|
||||
}
|
||||
|
||||
void LLVOCache::clearCacheInMemory()
|
||||
{
|
||||
if(!mHeaderEntryQueue.empty())
|
||||
|
|
@ -388,30 +429,6 @@ void LLVOCache::removeFromCache(U64 handle)
|
|||
LLAPRFile::remove(filename, mLocalAPRFilePoolp);
|
||||
}
|
||||
|
||||
BOOL LLVOCache::checkRead(LLAPRFile* apr_file, void* src, S32 n_bytes)
|
||||
{
|
||||
if(!check_read(apr_file, src, n_bytes))
|
||||
{
|
||||
delete apr_file ;
|
||||
removeCache() ;
|
||||
return FALSE ;
|
||||
}
|
||||
|
||||
return TRUE ;
|
||||
}
|
||||
|
||||
BOOL LLVOCache::checkWrite(LLAPRFile* apr_file, void* src, S32 n_bytes)
|
||||
{
|
||||
if(!check_write(apr_file, src, n_bytes))
|
||||
{
|
||||
delete apr_file ;
|
||||
removeCache() ;
|
||||
return FALSE ;
|
||||
}
|
||||
|
||||
return TRUE ;
|
||||
}
|
||||
|
||||
void LLVOCache::readCacheHeader()
|
||||
{
|
||||
if(!mEnabled)
|
||||
|
|
@ -422,43 +439,45 @@ void LLVOCache::readCacheHeader()
|
|||
//clear stale info.
|
||||
clearCacheInMemory();
|
||||
|
||||
bool success = true ;
|
||||
if (LLAPRFile::isExist(mHeaderFileName, mLocalAPRFilePoolp))
|
||||
{
|
||||
LLAPRFile* apr_file = new LLAPRFile(mHeaderFileName, APR_READ|APR_BINARY, mLocalAPRFilePoolp);
|
||||
LLAPRFile apr_file(mHeaderFileName, APR_READ|APR_BINARY, mLocalAPRFilePoolp);
|
||||
|
||||
//read the meta element
|
||||
if(!checkRead(apr_file, &mMetaInfo, sizeof(HeaderMetaInfo)))
|
||||
success = check_read(&apr_file, &mMetaInfo, sizeof(HeaderMetaInfo)) ;
|
||||
|
||||
if(success)
|
||||
{
|
||||
return ;
|
||||
}
|
||||
|
||||
HeaderEntryInfo* entry ;
|
||||
mNumEntries = 0 ;
|
||||
while(mNumEntries < MAX_NUM_OBJECT_ENTRIES)
|
||||
{
|
||||
entry = new HeaderEntryInfo() ;
|
||||
if(!checkRead(apr_file, entry, sizeof(HeaderEntryInfo)))
|
||||
HeaderEntryInfo* entry ;
|
||||
mNumEntries = 0 ;
|
||||
while(mNumEntries < MAX_NUM_OBJECT_ENTRIES)
|
||||
{
|
||||
delete entry ;
|
||||
return ;
|
||||
}
|
||||
else if(!entry->mTime) //end of the cache.
|
||||
{
|
||||
delete entry ;
|
||||
return ;
|
||||
}
|
||||
entry = new HeaderEntryInfo() ;
|
||||
success = check_read(&apr_file, entry, sizeof(HeaderEntryInfo));
|
||||
|
||||
if(!success || !entry->mTime) //failed or end of the cache
|
||||
{
|
||||
delete entry ;
|
||||
break ;
|
||||
}
|
||||
|
||||
entry->mIndex = mNumEntries++ ;
|
||||
mHeaderEntryQueue.insert(entry) ;
|
||||
mHandleEntryMap[entry->mHandle] = entry ;
|
||||
entry->mIndex = mNumEntries++ ;
|
||||
mHeaderEntryQueue.insert(entry) ;
|
||||
mHandleEntryMap[entry->mHandle] = entry ;
|
||||
}
|
||||
}
|
||||
|
||||
delete apr_file ;
|
||||
}
|
||||
else
|
||||
{
|
||||
writeCacheHeader() ;
|
||||
}
|
||||
|
||||
if(!success)
|
||||
{
|
||||
removeCache() ; //failed to read header, clear the cache
|
||||
}
|
||||
return ;
|
||||
}
|
||||
|
||||
void LLVOCache::writeCacheHeader()
|
||||
|
|
@ -468,48 +487,47 @@ void LLVOCache::writeCacheHeader()
|
|||
return ;
|
||||
}
|
||||
|
||||
LLAPRFile* apr_file = new LLAPRFile(mHeaderFileName, APR_CREATE|APR_WRITE|APR_BINARY, mLocalAPRFilePoolp);
|
||||
|
||||
//write the meta element
|
||||
if(!checkWrite(apr_file, &mMetaInfo, sizeof(HeaderMetaInfo)))
|
||||
bool success = true ;
|
||||
{
|
||||
return ;
|
||||
}
|
||||
LLAPRFile apr_file(mHeaderFileName, APR_CREATE|APR_WRITE|APR_BINARY, mLocalAPRFilePoolp);
|
||||
|
||||
mNumEntries = 0 ;
|
||||
for(header_entry_queue_t::iterator iter = mHeaderEntryQueue.begin() ; iter != mHeaderEntryQueue.end(); ++iter)
|
||||
{
|
||||
(*iter)->mIndex = mNumEntries++ ;
|
||||
if(!checkWrite(apr_file, (void*)*iter, sizeof(HeaderEntryInfo)))
|
||||
//write the meta element
|
||||
success = check_write(&apr_file, &mMetaInfo, sizeof(HeaderMetaInfo)) ;
|
||||
|
||||
mNumEntries = 0 ;
|
||||
for(header_entry_queue_t::iterator iter = mHeaderEntryQueue.begin() ; success && iter != mHeaderEntryQueue.end(); ++iter)
|
||||
{
|
||||
return ;
|
||||
(*iter)->mIndex = mNumEntries++ ;
|
||||
success = check_write(&apr_file, (void*)*iter, sizeof(HeaderEntryInfo));
|
||||
}
|
||||
}
|
||||
|
||||
mNumEntries = mHeaderEntryQueue.size() ;
|
||||
if(mNumEntries < MAX_NUM_OBJECT_ENTRIES)
|
||||
{
|
||||
HeaderEntryInfo* entry = new HeaderEntryInfo() ;
|
||||
for(S32 i = mNumEntries ; i < MAX_NUM_OBJECT_ENTRIES ; i++)
|
||||
|
||||
mNumEntries = mHeaderEntryQueue.size() ;
|
||||
if(success && mNumEntries < MAX_NUM_OBJECT_ENTRIES)
|
||||
{
|
||||
//fill the cache with the default entry.
|
||||
if(!checkWrite(apr_file, entry, sizeof(HeaderEntryInfo)))
|
||||
HeaderEntryInfo* entry = new HeaderEntryInfo() ;
|
||||
for(S32 i = mNumEntries ; success && i < MAX_NUM_OBJECT_ENTRIES ; i++)
|
||||
{
|
||||
mReadOnly = TRUE ; //disable the cache.
|
||||
return ;
|
||||
//fill the cache with the default entry.
|
||||
success = check_write(&apr_file, entry, sizeof(HeaderEntryInfo)) ;
|
||||
}
|
||||
delete entry ;
|
||||
}
|
||||
delete entry ;
|
||||
}
|
||||
delete apr_file ;
|
||||
|
||||
if(!success)
|
||||
{
|
||||
clearCacheInMemory() ;
|
||||
mReadOnly = TRUE ; //disable the cache.
|
||||
}
|
||||
return ;
|
||||
}
|
||||
|
||||
BOOL LLVOCache::updateEntry(const HeaderEntryInfo* entry)
|
||||
{
|
||||
LLAPRFile* apr_file = new LLAPRFile(mHeaderFileName, APR_WRITE|APR_BINARY, mLocalAPRFilePoolp);
|
||||
apr_file->seek(APR_SET, entry->mIndex * sizeof(HeaderEntryInfo) + sizeof(HeaderMetaInfo)) ;
|
||||
LLAPRFile apr_file(mHeaderFileName, APR_WRITE|APR_BINARY, mLocalAPRFilePoolp);
|
||||
apr_file.seek(APR_SET, entry->mIndex * sizeof(HeaderEntryInfo) + sizeof(HeaderMetaInfo)) ;
|
||||
|
||||
return checkWrite(apr_file, (void*)entry, sizeof(HeaderEntryInfo)) ;
|
||||
return check_write(&apr_file, (void*)entry, sizeof(HeaderEntryInfo)) ;
|
||||
}
|
||||
|
||||
void LLVOCache::readFromCache(U64 handle, const LLUUID& id, LLVOCacheEntry::vocache_entry_map_t& cache_entry_map)
|
||||
|
|
@ -526,43 +544,51 @@ void LLVOCache::readFromCache(U64 handle, const LLUUID& id, LLVOCacheEntry::voca
|
|||
return ;
|
||||
}
|
||||
|
||||
std::string filename;
|
||||
getObjectCacheFilename(handle, filename);
|
||||
LLAPRFile* apr_file = new LLAPRFile(filename, APR_READ|APR_BINARY, mLocalAPRFilePoolp);
|
||||
|
||||
LLUUID cache_id ;
|
||||
if(!checkRead(apr_file, cache_id.mData, UUID_BYTES))
|
||||
bool success = true ;
|
||||
{
|
||||
return ;
|
||||
}
|
||||
if(cache_id != id)
|
||||
{
|
||||
llinfos << "Cache ID doesn't match for this region, discarding"<< llendl;
|
||||
std::string filename;
|
||||
getObjectCacheFilename(handle, filename);
|
||||
LLAPRFile apr_file(filename, APR_READ|APR_BINARY, mLocalAPRFilePoolp);
|
||||
|
||||
LLUUID cache_id ;
|
||||
success = check_read(&apr_file, cache_id.mData, UUID_BYTES) ;
|
||||
|
||||
if(success)
|
||||
{
|
||||
if(cache_id != id)
|
||||
{
|
||||
llinfos << "Cache ID doesn't match for this region, discarding"<< llendl;
|
||||
success = false ;
|
||||
}
|
||||
|
||||
delete apr_file ;
|
||||
return ;
|
||||
}
|
||||
|
||||
S32 num_entries;
|
||||
if(!checkRead(apr_file, &num_entries, sizeof(S32)))
|
||||
{
|
||||
return ;
|
||||
if(success)
|
||||
{
|
||||
S32 num_entries;
|
||||
success = check_read(&apr_file, &num_entries, sizeof(S32)) ;
|
||||
|
||||
for (S32 i = 0; success && i < num_entries; i++)
|
||||
{
|
||||
LLVOCacheEntry* entry = new LLVOCacheEntry(&apr_file);
|
||||
if (!entry->getLocalID())
|
||||
{
|
||||
llwarns << "Aborting cache file load for " << filename << ", cache file corruption!" << llendl;
|
||||
delete entry ;
|
||||
success = false ;
|
||||
}
|
||||
cache_entry_map[entry->getLocalID()] = entry;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (S32 i = 0; i < num_entries; i++)
|
||||
if(!success)
|
||||
{
|
||||
LLVOCacheEntry* entry = new LLVOCacheEntry(apr_file);
|
||||
if (!entry->getLocalID())
|
||||
if(cache_entry_map.empty())
|
||||
{
|
||||
llwarns << "Aborting cache file load for " << filename << ", cache file corruption!" << llendl;
|
||||
delete entry ;
|
||||
break;
|
||||
removeEntry(iter->second) ;
|
||||
}
|
||||
cache_entry_map[entry->getLocalID()] = entry;
|
||||
}
|
||||
num_entries = cache_entry_map.size() ;
|
||||
|
||||
delete apr_file ;
|
||||
return ;
|
||||
}
|
||||
|
||||
|
|
@ -636,33 +662,31 @@ void LLVOCache::writeToCache(U64 handle, const LLUUID& id, const LLVOCacheEntry:
|
|||
}
|
||||
|
||||
//write to cache file
|
||||
std::string filename;
|
||||
getObjectCacheFilename(handle, filename);
|
||||
LLAPRFile* apr_file = new LLAPRFile(filename, APR_CREATE|APR_WRITE|APR_BINARY, mLocalAPRFilePoolp);
|
||||
bool success = true ;
|
||||
{
|
||||
std::string filename;
|
||||
getObjectCacheFilename(handle, filename);
|
||||
LLAPRFile apr_file(filename, APR_CREATE|APR_WRITE|APR_BINARY, mLocalAPRFilePoolp);
|
||||
|
||||
if(!checkWrite(apr_file, (void*)id.mData, UUID_BYTES))
|
||||
{
|
||||
return ;
|
||||
}
|
||||
|
||||
S32 num_entries = cache_entry_map.size() ;
|
||||
if(!checkWrite(apr_file, &num_entries, sizeof(S32)))
|
||||
{
|
||||
return ;
|
||||
}
|
||||
|
||||
for (LLVOCacheEntry::vocache_entry_map_t::const_iterator iter = cache_entry_map.begin(); iter != cache_entry_map.end(); ++iter)
|
||||
{
|
||||
if(!iter->second->writeToFile(apr_file))
|
||||
success = check_write(&apr_file, (void*)id.mData, UUID_BYTES) ;
|
||||
|
||||
if(success)
|
||||
{
|
||||
//failed
|
||||
delete apr_file ;
|
||||
removeCache() ;
|
||||
return ;
|
||||
S32 num_entries = cache_entry_map.size() ;
|
||||
success = check_write(&apr_file, &num_entries, sizeof(S32));
|
||||
|
||||
for (LLVOCacheEntry::vocache_entry_map_t::const_iterator iter = cache_entry_map.begin(); success && iter != cache_entry_map.end(); ++iter)
|
||||
{
|
||||
success = iter->second->writeToFile(&apr_file) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
delete apr_file ;
|
||||
if(!success)
|
||||
{
|
||||
removeEntry(entry) ;
|
||||
}
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -111,6 +111,7 @@ public:
|
|||
|
||||
void readFromCache(U64 handle, const LLUUID& id, LLVOCacheEntry::vocache_entry_map_t& cache_entry_map) ;
|
||||
void writeToCache(U64 handle, const LLUUID& id, const LLVOCacheEntry::vocache_entry_map_t& cache_entry_map, BOOL dirty_cache) ;
|
||||
void removeEntry(U64 handle) ;
|
||||
|
||||
void setReadOnly(BOOL read_only) {mReadOnly = read_only;}
|
||||
|
||||
|
|
@ -123,10 +124,9 @@ private:
|
|||
void writeCacheHeader();
|
||||
void clearCacheInMemory();
|
||||
void removeCache() ;
|
||||
void removeEntry(HeaderEntryInfo* entry) ;
|
||||
void purgeEntries();
|
||||
BOOL updateEntry(const HeaderEntryInfo* entry);
|
||||
BOOL checkRead(LLAPRFile* apr_file, void* src, S32 n_bytes) ;
|
||||
BOOL checkWrite(LLAPRFile* apr_file, void* src, S32 n_bytes) ;
|
||||
|
||||
private:
|
||||
BOOL mEnabled;
|
||||
|
|
|
|||
|
|
@ -388,10 +388,12 @@ U32 LLVOVolume::processUpdateMessage(LLMessageSystem *mesgsys,
|
|||
// There's something bogus in the data that we're unpacking.
|
||||
dp->dumpBufferToLog();
|
||||
llwarns << "Flushing cache files" << llendl;
|
||||
std::string mask;
|
||||
mask = gDirUtilp->getDirDelimiter() + "*.slc";
|
||||
gDirUtilp->deleteFilesInDir(gDirUtilp->getExpandedFilename(LL_PATH_CACHE,""), mask);
|
||||
// llerrs << "Bogus TE data in " << getID() << ", crashing!" << llendl;
|
||||
|
||||
if(LLVOCache::hasInstance() && getRegion())
|
||||
{
|
||||
LLVOCache::getInstance()->removeEntry(getRegion()->getHandle()) ;
|
||||
}
|
||||
|
||||
llwarns << "Bogus TE data in " << getID() << llendl;
|
||||
}
|
||||
else
|
||||
|
|
|
|||
Loading…
Reference in New Issue