Android: Use synchronized methods for GameFileCache

Compared to the previous solution of using big `synchronized` blocks,
this makes GameFileCacheManager's executor thread release and re-lock
the lock when possible, giving the GUI thread a chance to do a
(comparatively) quick getOrAdd call if it needs to.
This commit is contained in:
JosJuice 2022-09-27 19:05:02 +02:00
parent 51debaeb47
commit 45901f64b5
2 changed files with 25 additions and 34 deletions

View File

@ -109,11 +109,11 @@ public class GameFileCache
public static native String[] getAllGamePaths(String[] folderPaths, boolean recursiveScan); public static native String[] getAllGamePaths(String[] folderPaths, boolean recursiveScan);
public native int getSize(); public synchronized native int getSize();
public native GameFile[] getAllGames(); public synchronized native GameFile[] getAllGames();
public native GameFile addOrGet(String gamePath); public synchronized native GameFile addOrGet(String gamePath);
/** /**
* Sets the list of games to cache. * Sets the list of games to cache.
@ -123,7 +123,7 @@ public class GameFileCache
* *
* @return true if the cache was modified * @return true if the cache was modified
*/ */
public native boolean update(String[] gamePaths); public synchronized native boolean update(String[] gamePaths);
/** /**
* For each game that already is in the cache, scans the folder that contains the game * For each game that already is in the cache, scans the folder that contains the game
@ -131,9 +131,9 @@ public class GameFileCache
* *
* @return true if the cache was modified * @return true if the cache was modified
*/ */
public native boolean updateAdditionalMetadata(); public synchronized native boolean updateAdditionalMetadata();
public native boolean load(); public synchronized native boolean load();
public native boolean save(); public synchronized native boolean save();
} }

View File

@ -158,7 +158,7 @@ public final class GameFileCacheManager
{ {
// Common case: The game is in the cache, so just grab it from there. // Common case: The game is in the cache, so just grab it from there.
// (Actually, addOrGet already checks for this case, but we want to avoid calling it if possible // (Actually, addOrGet already checks for this case, but we want to avoid calling it if possible
// because onHandleIntent may hold a lock on sGameFileCache for extended periods of time.) // because the executor thread may hold a lock on sGameFileCache for extended periods of time.)
GameFile[] allGames = sGameFiles.getValue(); GameFile[] allGames = sGameFiles.getValue();
for (GameFile game : allGames) for (GameFile game : allGames)
{ {
@ -171,10 +171,7 @@ public final class GameFileCacheManager
// Unusual case: The game wasn't found in the cache. // Unusual case: The game wasn't found in the cache.
// Scan the game and add it to the cache so that we can return it. // Scan the game and add it to the cache so that we can return it.
createGameFileCacheIfNeeded(); createGameFileCacheIfNeeded();
synchronized (sGameFileCache) return sGameFileCache.addOrGet(gamePath);
{
return sGameFileCache.addOrGet(gamePath);
}
} }
/** /**
@ -186,14 +183,11 @@ public final class GameFileCacheManager
{ {
if (!sFirstLoadDone) if (!sFirstLoadDone)
{ {
synchronized (sGameFileCache) sFirstLoadDone = true;
sGameFileCache.load();
if (sGameFileCache.getSize() != 0)
{ {
sFirstLoadDone = true; updateGameFileArray();
sGameFileCache.load();
if (sGameFileCache.getSize() != 0)
{
updateGameFileArray();
}
} }
} }
@ -227,24 +221,21 @@ public final class GameFileCacheManager
{ {
String[] gamePaths = GameFileCache.getAllGamePaths(); String[] gamePaths = GameFileCache.getAllGamePaths();
synchronized (sGameFileCache) boolean changed = sGameFileCache.update(gamePaths);
if (changed)
{ {
boolean changed = sGameFileCache.update(gamePaths); updateGameFileArray();
if (changed) }
{
updateGameFileArray();
}
boolean additionalMetadataChanged = sGameFileCache.updateAdditionalMetadata(); boolean additionalMetadataChanged = sGameFileCache.updateAdditionalMetadata();
if (additionalMetadataChanged) if (additionalMetadataChanged)
{ {
updateGameFileArray(); updateGameFileArray();
} }
if (changed || additionalMetadataChanged) if (changed || additionalMetadataChanged)
{ {
sGameFileCache.save(); sGameFileCache.save();
}
} }
} }