Fix concurrency exception in ServerPingWithAlarmManager

Fixes SMACK-676.
This commit is contained in:
Florian Schmaus 2015-06-22 22:49:36 +02:00
parent c1192f18b4
commit 4b0767ba9a
1 changed files with 13 additions and 5 deletions

View File

@ -17,8 +17,10 @@
package org.jivesoftware.smackx.ping.android; package org.jivesoftware.smackx.ping.android;
import java.util.Iterator; import java.util.HashSet;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.WeakHashMap; import java.util.WeakHashMap;
import java.util.logging.Logger; import java.util.logging.Logger;
@ -111,10 +113,16 @@ public class ServerPingWithAlarmManager extends Manager {
@Override @Override
public void onReceive(Context context, Intent intent) { public void onReceive(Context context, Intent intent) {
LOGGER.fine("Ping Alarm broadcast received"); LOGGER.fine("Ping Alarm broadcast received");
Iterator<XMPPConnection> it = INSTANCES.keySet().iterator(); Set<Entry<XMPPConnection, ServerPingWithAlarmManager>> managers;
while (it.hasNext()) { synchronized (ServerPingWithAlarmManager.class) {
XMPPConnection connection = it.next(); // Make a copy to avoid ConcurrentModificationException when
if (ServerPingWithAlarmManager.getInstanceFor(connection).isEnabled()) { // iterating directly over INSTANCES and the Set is modified
// concurrently by creating a new ServerPingWithAlarmManager.
managers = new HashSet<>(INSTANCES.entrySet());
}
for (Entry<XMPPConnection, ServerPingWithAlarmManager> entry : managers) {
XMPPConnection connection = entry.getKey();
if (entry.getValue().isEnabled()) {
LOGGER.fine("Calling pingServerIfNecessary for connection " LOGGER.fine("Calling pingServerIfNecessary for connection "
+ connection.getConnectionCounter()); + connection.getConnectionCounter());
final PingManager pingManager = PingManager.getInstanceFor(connection); final PingManager pingManager = PingManager.getInstanceFor(connection);