From 5c090c35d4da3bfacc20342dd1d7351a603cde57 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Fri, 2 Nov 2018 21:51:09 +0100 Subject: [PATCH] Ensure sync listeners not being called after they removed themselves --- .../jivesoftware/smack/AbstractXMPPConnection.java | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/smack-core/src/main/java/org/jivesoftware/smack/AbstractXMPPConnection.java b/smack-core/src/main/java/org/jivesoftware/smack/AbstractXMPPConnection.java index 64cddbe45..c47deffff 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/AbstractXMPPConnection.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/AbstractXMPPConnection.java @@ -22,6 +22,7 @@ import java.io.Writer; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; +import java.util.Iterator; import java.util.LinkedHashMap; import java.util.LinkedList; import java.util.List; @@ -1220,6 +1221,19 @@ public abstract class AbstractXMPPConnection implements XMPPConnection { ASYNC_BUT_ORDERED.performAsyncButOrdered(this, new Runnable() { @Override public void run() { + // As listeners are able to remove themselves and because the timepoint where it is decided to invoke a + // listener is a different timepoint where the listener is actually invoked (here), we have to check + // again if the listener is still active. + Iterator it = listenersToNotify.iterator(); + synchronized (syncRecvListeners) { + while (it.hasNext()) { + StanzaListener stanzaListener = it.next(); + if (!syncRecvListeners.containsKey(stanzaListener)) { + // The listener was removed from syncRecvListener, also remove him from listenersToNotify. + it.remove(); + } + } + } for (StanzaListener listener : listenersToNotify) { try { listener.processStanza(packet);