From 3ff553549a4c10ce7154db6b516e362631045586 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Wed, 2 Feb 2022 12:44:04 +0100 Subject: [PATCH] [SmackFuture] Invoke the callbacks at most once Previously, if a SmackFuture both was successful and unsuccessful, it was possible that the onSuccess() callback was invoked twice. Reported-by: Boris Grozev --- .../src/main/java/org/jivesoftware/smack/SmackFuture.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/smack-core/src/main/java/org/jivesoftware/smack/SmackFuture.java b/smack-core/src/main/java/org/jivesoftware/smack/SmackFuture.java index 08646728a..ec99e6c4a 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/SmackFuture.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/SmackFuture.java @@ -162,16 +162,20 @@ public abstract class SmackFuture implements Future, return result; } + private boolean callbacksInvoked; + protected final synchronized void maybeInvokeCallbacks() { - if (cancelled) { + if (cancelled || callbacksInvoked) { return; } if ((result != null || exception != null) && completionCallback != null) { + callbacksInvoked = true; completionCallback.accept(this); } if (result != null && successCallback != null) { + callbacksInvoked = true; AbstractXMPPConnection.asyncGo(new Runnable() { @Override public void run() { @@ -180,6 +184,7 @@ public abstract class SmackFuture implements Future, }); } else if (exception != null && exceptionCallback != null) { + callbacksInvoked = true; AbstractXMPPConnection.asyncGo(new Runnable() { @Override public void run() {