1
0
forked from 0ad/0ad

gracefully handle the case where the file cache is full of data still referenced elsewhere.

fixes #832

This was SVN commit r9437.
This commit is contained in:
janwas 2011-05-04 22:19:38 +00:00
parent 002c40ede4
commit dcec9c4ca9
2 changed files with 19 additions and 15 deletions

View File

@ -182,9 +182,11 @@ public:
{
shared_ptr<u8> discardedData; size_t discardedSize;
bool removed = m_cache.remove_least_valuable(&discardedData, &discardedSize);
// only false if cache is empty, which can't be the case because
// allocation failed.
ENSURE(removed);
// the cache is empty, and allocation still failed.
// apparently the cache is full of data that's still
// referenced, so we can't reserve any more space.
if(!removed)
return shared_ptr<u8>();
}
}
}

View File

@ -158,20 +158,22 @@ public:
// instead, callers should log the error, including pathname.
RETURN_STATUS_IF_ERR(vfs_Lookup(pathname, &m_rootDirectory, directory, &file));
fileContents = DummySharedPtr((u8*)0);
size = file->Size();
// safely handle zero-length files
if(!size)
fileContents = DummySharedPtr((u8*)0);
else if(size > m_cacheSize)
if(size != 0) // (the file cache can't handle zero-length allocations)
{
RETURN_STATUS_IF_ERR(AllocateAligned(fileContents, size, maxSectorSize));
RETURN_STATUS_IF_ERR(file->Loader()->Load(file->Name(), fileContents, file->Size()));
}
else
{
fileContents = m_fileCache.Reserve(size);
RETURN_STATUS_IF_ERR(file->Loader()->Load(file->Name(), fileContents, file->Size()));
m_fileCache.Add(pathname, fileContents, size);
if(size < m_cacheSize/2) // (avoid evicting lots of previous data)
fileContents = m_fileCache.Reserve(size);
if(fileContents)
{
RETURN_STATUS_IF_ERR(file->Loader()->Load(file->Name(), fileContents, file->Size()));
m_fileCache.Add(pathname, fileContents, size);
}
else
{
RETURN_STATUS_IF_ERR(AllocateAligned(fileContents, size, maxSectorSize));
RETURN_STATUS_IF_ERR(file->Loader()->Load(file->Name(), fileContents, file->Size()));
}
}
}