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) {
|
void addHandler(StompSessionHandler delegate) {
|
||||||
if (this.session != null) {
|
synchronized (this.delegates) {
|
||||||
delegate.afterConnected(this.session, getConnectHeaders());
|
if (this.session != null) {
|
||||||
|
delegate.afterConnected(this.session, getConnectHeaders());
|
||||||
|
}
|
||||||
|
this.delegates.add(delegate);
|
||||||
}
|
}
|
||||||
this.delegates.add(delegate);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void removeHandler(StompSessionHandler delegate) {
|
void removeHandler(StompSessionHandler delegate) {
|
||||||
@@ -382,8 +384,8 @@ public abstract class AbstractStompSessionManager implements StompSessionManager
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void afterConnected(StompSession session, StompHeaders connectedHeaders) {
|
public void afterConnected(StompSession session, StompHeaders connectedHeaders) {
|
||||||
this.session = session;
|
|
||||||
synchronized (this.delegates) {
|
synchronized (this.delegates) {
|
||||||
|
this.session = session;
|
||||||
for (StompSessionHandler delegate : this.delegates) {
|
for (StompSessionHandler delegate : this.delegates) {
|
||||||
delegate.afterConnected(session, connectedHeaders);
|
delegate.afterConnected(session, connectedHeaders);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user