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**
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user