From df109410c3debafb1401046d11fa375dd3033651 Mon Sep 17 00:00:00 2001 From: Artem Bilan Date: Mon, 23 Oct 2017 13:45:05 -0400 Subject: [PATCH] Fix AbstractStompSessionManager race condition https://build.spring.io/browse/INT-MJATS41-1150 When we add `addHandler()` to the `CompositeStompSessionHandler`, there is no guarantee that we will have `session` atomically during this method invocation or after it relying on the later call to the `this.delegates`. In other words the session may be populated in between and, therefore, our `delegate` loses `afterConnected()` event. We need to synchronize on the barrier and block the concurrent `afterConnected()` or wait for it. This way we atomically ensure that our `delegate` is added to the existing `session` or will be performed afterwards in the `afterConnected()` **Cherry-pick to 4.3.x** --- .../integration/stomp/AbstractStompSessionManager.java | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/spring-integration-stomp/src/main/java/org/springframework/integration/stomp/AbstractStompSessionManager.java b/spring-integration-stomp/src/main/java/org/springframework/integration/stomp/AbstractStompSessionManager.java index 92e410b421..33c7a278f4 100644 --- a/spring-integration-stomp/src/main/java/org/springframework/integration/stomp/AbstractStompSessionManager.java +++ b/spring-integration-stomp/src/main/java/org/springframework/integration/stomp/AbstractStompSessionManager.java @@ -370,10 +370,12 @@ public abstract class AbstractStompSessionManager implements StompSessionManager } void addHandler(StompSessionHandler delegate) { - if (this.session != null) { - delegate.afterConnected(this.session, getConnectHeaders()); + synchronized (this.delegates) { + if (this.session != null) { + delegate.afterConnected(this.session, getConnectHeaders()); + } + this.delegates.add(delegate); } - this.delegates.add(delegate); } void removeHandler(StompSessionHandler delegate) { @@ -382,8 +384,8 @@ public abstract class AbstractStompSessionManager implements StompSessionManager @Override public void afterConnected(StompSession session, StompHeaders connectedHeaders) { - this.session = session; synchronized (this.delegates) { + this.session = session; for (StompSessionHandler delegate : this.delegates) { delegate.afterConnected(session, connectedHeaders); }