Destination: Fix ConcurrentModificationException Use a ConcurrentMap to cover unsynchronized reads happening during synchronized writes. Change-Id: I09fb626104361f20b62216d939c85219657678ab
diff --git a/src/main/java/com/googlesource/gerrit/plugins/replication/Destination.java b/src/main/java/com/googlesource/gerrit/plugins/replication/Destination.java index 7e4298b..444bb46 100644 --- a/src/main/java/com/googlesource/gerrit/plugins/replication/Destination.java +++ b/src/main/java/com/googlesource/gerrit/plugins/replication/Destination.java
@@ -71,6 +71,8 @@ import java.util.Map; import java.util.Set; import java.util.concurrent.Callable; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; @@ -95,7 +97,9 @@ private final ReplicationStateListener stateLog; private final Object stateLock = new Object(); - private final Map<URIish, PushOne> pending = new HashMap<>(); + private final ConcurrentMap<URIish, PushOne> pending = + new ConcurrentHashMap<>(); // writes are covered by the stateLock, but some reads are still + // allowed without the lock private final Map<URIish, PushOne> inFlight = new HashMap<>(); private final PushOne.Factory opFactory; private final DeleteProjectTask.Factory deleteProjectFactory;