Fix for a crash (I think the same one Zeth reported) where the game dies somewhere in file reading source - I wasn't paying close enough attention to the fact that there are in fact 3 separate caches, so each had their own mutex, so JFileSystem wasn't actually being protected from reentrancy. So, if the app tried to load an audio sample at the same time as an image, boom...

This commit is contained in:
wrenczes@gmail.com
2011-04-20 09:03:08 +00:00
parent fc0a59a14e
commit ec95bb93e1
2 changed files with 9 additions and 10 deletions

View File

@@ -25,6 +25,11 @@ namespace
const std::string kGenericCard("back.jpg");
const std::string kGenericThumbCard("back_thumb.jpg");
// mutex meant for the cache map
boost::mutex sCacheMutex;
// mutex meant to protect against unthread-safe calls into JFileSystem, etc.
boost::mutex sLoadFunctionMutex;
}
WResourceManager* WResourceManager::sInstance = NULL;
@@ -1161,7 +1166,7 @@ cacheItem* WCache<cacheItem, cacheActual>::Get(int id, const string& filename, i
//Not managed, so look in cache.
if (style != RETRIEVE_MANAGE)
{
boost::mutex::scoped_lock lock(mCacheMutex);
boost::mutex::scoped_lock lock(sCacheMutex);
//DebugTrace("Cache lock acquired, looking up index " << lookup);
it = cache.find(lookup);
//Well, we've found something...
@@ -1216,7 +1221,7 @@ cacheItem* WCache<cacheItem, cacheActual>::LoadIntoCache(int id, const string& f
// the shared cache container, and this separate lock was added to insulate us against thread safety issues in JGE. In particular,
// JFileSystem is particularly unsafe, as it assumes that we have only one zip loaded at a time... rather than add mutexes in JGE,
// I've kept it local to here.
boost::mutex::scoped_lock functionLock(mLoadFunctionMutex);
boost::mutex::scoped_lock functionLock(sLoadFunctionMutex);
cacheItem* item = AttemptNew(filename, submode);
//assert(item);
if (style == RETRIEVE_MANAGE)
@@ -1234,7 +1239,7 @@ cacheItem* WCache<cacheItem, cacheActual>::LoadIntoCache(int id, const string& f
{
if (mError == CACHE_ERROR_404 || item)
{
boost::mutex::scoped_lock lock(mCacheMutex);
boost::mutex::scoped_lock lock(sCacheMutex);
cache[id] = item;
DebugTrace("inserted item ptr " << ToHex(item) << " at index " << id);
}
@@ -1331,7 +1336,7 @@ bool WCache<cacheItem, cacheActual>::Cleanup()
// this looks redundant, but the idea is, don't grab the mutex if there's no work to do
if (RequiresOldItemCleanup())
{
boost::mutex::scoped_lock lock(mCacheMutex);
boost::mutex::scoped_lock lock(sCacheMutex);
while (RequiresOldItemCleanup())
{
if (!RemoveOldest())