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**
(cherry picked from commit df10941)
This commit is contained in:
@@ -377,10 +377,12 @@ public abstract class AbstractStompSessionManager implements StompSessionManager
|
||||
private volatile StompSession session;
|
||||
|
||||
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) {
|
||||
@@ -389,8 +391,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