From 4b0767ba9ad3aa607f348d4747888616cd2e8d5b Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Mon, 22 Jun 2015 22:49:36 +0200 Subject: [PATCH] Fix concurrency exception in ServerPingWithAlarmManager Fixes SMACK-676. --- .../android/ServerPingWithAlarmManager.java | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/smack-android-extensions/src/main/java/org/jivesoftware/smackx/ping/android/ServerPingWithAlarmManager.java b/smack-android-extensions/src/main/java/org/jivesoftware/smackx/ping/android/ServerPingWithAlarmManager.java index d203aa097..623c4c66e 100644 --- a/smack-android-extensions/src/main/java/org/jivesoftware/smackx/ping/android/ServerPingWithAlarmManager.java +++ b/smack-android-extensions/src/main/java/org/jivesoftware/smackx/ping/android/ServerPingWithAlarmManager.java @@ -17,8 +17,10 @@ package org.jivesoftware.smackx.ping.android; -import java.util.Iterator; +import java.util.HashSet; import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; import java.util.WeakHashMap; import java.util.logging.Logger; @@ -111,10 +113,16 @@ public class ServerPingWithAlarmManager extends Manager { @Override public void onReceive(Context context, Intent intent) { LOGGER.fine("Ping Alarm broadcast received"); - Iterator it = INSTANCES.keySet().iterator(); - while (it.hasNext()) { - XMPPConnection connection = it.next(); - if (ServerPingWithAlarmManager.getInstanceFor(connection).isEnabled()) { + Set> managers; + synchronized (ServerPingWithAlarmManager.class) { + // Make a copy to avoid ConcurrentModificationException when + // iterating directly over INSTANCES and the Set is modified + // concurrently by creating a new ServerPingWithAlarmManager. + managers = new HashSet<>(INSTANCES.entrySet()); + } + for (Entry entry : managers) { + XMPPConnection connection = entry.getKey(); + if (entry.getValue().isEnabled()) { LOGGER.fine("Calling pingServerIfNecessary for connection " + connection.getConnectionCounter()); final PingManager pingManager = PingManager.getInstanceFor(connection);