]> nmode's Git Repositories - signal-cli/blobdiff - lib/src/main/java/org/asamk/signal/manager/MultiAccountManagerImpl.java
Copy managers list to prevent ConcurrentModificationException
[signal-cli] / lib / src / main / java / org / asamk / signal / manager / MultiAccountManagerImpl.java
index 26f8b961b089b80c34e71179a1f9d8be37ccdd17..74c4c20ac5f57646157f73230a4c64c2399c1ea4 100644 (file)
@@ -7,6 +7,7 @@ import org.slf4j.LoggerFactory;
 import java.io.File;
 import java.io.IOException;
 import java.net.URI;
+import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -36,6 +37,7 @@ public class MultiAccountManagerImpl implements MultiAccountManager {
             final String userAgent
     ) {
         this.managers.addAll(managers);
+        managers.forEach(m -> m.addClosedListener(() -> this.removeManager(m)));
         this.dataPath = dataPath;
         this.serviceEnvironment = serviceEnvironment;
         this.userAgent = userAgent;
@@ -54,6 +56,7 @@ public class MultiAccountManagerImpl implements MultiAccountManager {
                 return;
             }
             managers.add(m);
+            m.addClosedListener(() -> this.removeManager(m));
         }
         synchronized (onManagerAddedHandlers) {
             for (final var handler : onManagerAddedHandlers) {
@@ -69,6 +72,19 @@ public class MultiAccountManagerImpl implements MultiAccountManager {
         }
     }
 
+    void removeManager(final Manager m) {
+        synchronized (managers) {
+            if (!managers.remove(m)) {
+                return;
+            }
+        }
+        synchronized (onManagerRemovedHandlers) {
+            for (final var handler : onManagerRemovedHandlers) {
+                handler.accept(m);
+            }
+        }
+    }
+
     @Override
     public void addOnManagerRemovedHandler(final Consumer<Manager> handler) {
         synchronized (onManagerRemovedHandlers) {
@@ -109,7 +125,7 @@ public class MultiAccountManagerImpl implements MultiAccountManager {
     @Override
     public void close() {
         synchronized (managers) {
-            for (var m : managers) {
+            for (var m : new ArrayList<>(managers)) {
                 try {
                     m.close();
                 } catch (IOException e) {