diff options
| author | Mai M <mathew1800@gmail.com> | 2021-08-27 10:15:25 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-08-27 10:15:25 -0400 |
| commit | 48161953662b9d77c4ece357f6f16814dd0c5f58 (patch) | |
| tree | 5f10b66d89f69cda73eb5e8f1b254d7165ed6774 /Source/Android/app/src/main/java | |
| parent | 7d88354659148479818423d0990b055c4e845cc3 (diff) | |
| parent | 719930bb390ed0020b99a7942289d83218e99d69 (diff) | |
Merge pull request #10054 from JosJuice/android-game-cache-lock
Android: Reduce gameFileCache lock contention
Diffstat (limited to 'Source/Android/app/src/main/java')
2 files changed, 54 insertions, 29 deletions
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/model/GameFileCache.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/model/GameFileCache.java index a6f5261048..ed0f65741a 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/model/GameFileCache.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/model/GameFileCache.java @@ -96,12 +96,7 @@ public class GameFileCache return pathSet; } - /** - * Scans through the file system and updates the cache to match. - * - * @return true if the cache was modified - */ - public boolean update() + public static String[] getAllGamePaths() { boolean recursiveScan = BooleanSetting.MAIN_RECURSIVE_ISO_PATHS.getBooleanGlobal(); @@ -109,17 +104,33 @@ public class GameFileCache String[] folderPaths = folderPathsSet.toArray(new String[0]); - return update(folderPaths, recursiveScan); + return getAllGamePaths(folderPaths, recursiveScan); } + public static native String[] getAllGamePaths(String[] folderPaths, boolean recursiveScan); + public native int getSize(); public native GameFile[] getAllGames(); public native GameFile addOrGet(String gamePath); - public native boolean update(String[] folderPaths, boolean recursiveScan); + /** + * Sets the list of games to cache. + * + * Games which are in the passed-in list but not in the cache are scanned and added to the cache, + * and games which are in the cache but not in the passed-in list are removed from the cache. + * + * @return true if the cache was modified + */ + public native boolean update(String[] gamePaths); + /** + * For each game that already is in the cache, scans the folder that contains the game + * for additional metadata files (PNG/XML). + * + * @return true if the cache was modified + */ public native boolean updateAdditionalMetadata(); public native boolean load(); diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/services/GameFileCacheService.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/services/GameFileCacheService.java index 7cff59a3e9..3be5fb039f 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/services/GameFileCacheService.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/services/GameFileCacheService.java @@ -159,9 +159,20 @@ public final class GameFileCacheService extends IntentService public static GameFile addOrGet(String gamePath) { - // The existence of this one function, which is called from one - // single place, forces us to use synchronization in onHandleIntent... - // A bit annoying, but should be good enough for now + // 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 + // because onHandleIntent may hold a lock on gameFileCache for extended periods of time.) + GameFile[] allGames = gameFiles.get(); + for (GameFile game : allGames) + { + if (game.getPath().equals(gamePath)) + { + return game; + } + } + + // 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. synchronized (gameFileCache) { return gameFileCache.addOrGet(gamePath); @@ -192,26 +203,29 @@ public final class GameFileCacheService extends IntentService { if (gameFileCache != null) { + String[] gamePaths = GameFileCache.getAllGamePaths(); + + boolean changed; synchronized (gameFileCache) { - boolean changed = gameFileCache.update(); - if (changed) - { - updateGameFileArray(); - sendBroadcast(CACHE_UPDATED); - } - - boolean additionalMetadataChanged = gameFileCache.updateAdditionalMetadata(); - if (additionalMetadataChanged) - { - updateGameFileArray(); - sendBroadcast(CACHE_UPDATED); - } - - if (changed || additionalMetadataChanged) - { - gameFileCache.save(); - } + changed = gameFileCache.update(gamePaths); + } + if (changed) + { + updateGameFileArray(); + sendBroadcast(CACHE_UPDATED); + } + + boolean additionalMetadataChanged = gameFileCache.updateAdditionalMetadata(); + if (additionalMetadataChanged) + { + updateGameFileArray(); + sendBroadcast(CACHE_UPDATED); + } + + if (changed || additionalMetadataChanged) + { + gameFileCache.save(); } } |
