From 246bf5c1dca6b72611f9fb8b3285fa93c374ac56 Mon Sep 17 00:00:00 2001 From: artdeell Date: Mon, 30 Jan 2023 22:58:19 +0300 Subject: [PATCH] Fix: synchronize method bodies instead of completely relying on synchronized colelctions Should prevent ConcurrentModificationExceptions and runtime corruption --- .../progresskeeper/ProgressKeeper.java | 38 +++++++++---------- 1 file changed, 17 insertions(+), 21 deletions(-) diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/progresskeeper/ProgressKeeper.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/progresskeeper/ProgressKeeper.java index 9b5b76b80..1c5e837b7 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/progresskeeper/ProgressKeeper.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/progresskeeper/ProgressKeeper.java @@ -1,19 +1,15 @@ package net.kdt.pojavlaunch.progresskeeper; -import android.util.Log; - import java.util.ArrayList; -import java.util.Collections; +import java.util.HashMap; import java.util.List; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentLinkedQueue; public class ProgressKeeper { - private static final ConcurrentHashMap> sProgressListeners = new ConcurrentHashMap<>(); - private static final ConcurrentHashMap sProgressStates = new ConcurrentHashMap<>(); - private static final List sTaskCountListeners = Collections.synchronizedList(new ArrayList<>()); + private static final HashMap> sProgressListeners = new HashMap<>(); + private static final HashMap sProgressStates = new HashMap<>(); + private static final List sTaskCountListeners = new ArrayList<>(); - public static void submitProgress(String progressRecord, int progress, int resid, Object... va) { + public static synchronized void submitProgress(String progressRecord, int progress, int resid, Object... va) { ProgressState progressState = sProgressStates.get(progressRecord); boolean shouldCallStarted = progressState == null; boolean shouldCallEnded = resid == -1 && progress == -1; @@ -31,7 +27,7 @@ public class ProgressKeeper { progressState.varArg = va; } - ConcurrentLinkedQueue progressListeners = sProgressListeners.get(progressRecord); + List progressListeners = sProgressListeners.get(progressRecord); if(progressListeners != null) for(ProgressListener listener : progressListeners) { if(shouldCallStarted) listener.onProgressStarted(); @@ -40,14 +36,14 @@ public class ProgressKeeper { } } - private static void updateTaskCount() { + private static synchronized void updateTaskCount() { int count = sProgressStates.size(); for(TaskCountListener listener : sTaskCountListeners) { listener.onUpdateTaskCount(count); } } - public static void addListener(String progressRecord, ProgressListener listener) { + public static synchronized void addListener(String progressRecord, ProgressListener listener) { ProgressState state = sProgressStates.get(progressRecord); if(state != null && (state.resid != -1 || state.progress != -1)) { listener.onProgressStarted(); @@ -55,32 +51,32 @@ public class ProgressKeeper { }else{ listener.onProgressEnded(); } - ConcurrentLinkedQueue listenerWeakReferenceList = sProgressListeners.get(progressRecord); - if(listenerWeakReferenceList == null) sProgressListeners.put(progressRecord, (listenerWeakReferenceList = new ConcurrentLinkedQueue<>())); + List listenerWeakReferenceList = sProgressListeners.get(progressRecord); + if(listenerWeakReferenceList == null) sProgressListeners.put(progressRecord, (listenerWeakReferenceList = new ArrayList<>())); listenerWeakReferenceList.add(listener); } - public static void removeListener(String progressRecord, ProgressListener listener) { - ConcurrentLinkedQueue listenerWeakReferenceList = sProgressListeners.get(progressRecord); + public static synchronized void removeListener(String progressRecord, ProgressListener listener) { + List listenerWeakReferenceList = sProgressListeners.get(progressRecord); if(listenerWeakReferenceList != null) listenerWeakReferenceList.remove(listener); } - public static void addTaskCountListener(TaskCountListener listener) { + public static synchronized void addTaskCountListener(TaskCountListener listener) { listener.onUpdateTaskCount(sProgressStates.size()); if(!sTaskCountListeners.contains(listener)) sTaskCountListeners.add(listener); } - public static void addTaskCountListener(TaskCountListener listener, boolean runUpdate) { + public static synchronized void addTaskCountListener(TaskCountListener listener, boolean runUpdate) { if(runUpdate) listener.onUpdateTaskCount(sProgressStates.size()); if(!sTaskCountListeners.contains(listener)) sTaskCountListeners.add(listener); } - public static void removeTaskCountListener(TaskCountListener listener) { + public static synchronized void removeTaskCountListener(TaskCountListener listener) { sTaskCountListeners.remove(listener); } /** * Waits until all tasks are done and runs the runnable, or if there were no pending process remaining * The runnable runs from the thread that updated the task count last, and it might be the UI thread, - * so dont put long running processes in it + * so don't put long running processes in it * @param runnable the runnable to run when no tasks are remaining */ public static void waitUntilDone(final Runnable runnable) { @@ -101,7 +97,7 @@ public class ProgressKeeper { addTaskCountListener(listener); } - public static int getTaskCount() { + public static synchronized int getTaskCount() { return sProgressStates.size(); } }