INT-3897: Fix deadlock in the StompMessageHandler

JIRA: https://jira.spring.io/browse/INT-3897

The `StompMessageHandler` synchronized on the `sessionHandler` during `connectIfNecessary()`
performing mutually exclusive connect operation in the `StompSessionManager`.
Since the last one synchronizes on all `sessionHandler`s during its own operations, we end up with the deadlock
waiting for the `connectSemaphore`.

Change synchronization monitor object to the `connectSemaphore` accomplishing the same desired mutually exclusive connect logic
in the `StompMessageHandler`.

**Cherry-pick to 4.2.x**
This commit is contained in:
Artem Bilan
2015-12-08 17:38:49 -05:00
committed by Gary Russell
parent 5bc3208096
commit c810aaae12
2 changed files with 7 additions and 8 deletions

View File

@@ -60,7 +60,10 @@ import org.springframework.util.concurrent.ListenableFutureCallback;
* to the provided {@link StompSessionHandler}s.
* This {@link AbstractStompSessionManager.CompositeStompSessionHandler} is used for the
* {@link StompSession} connection.
*
* @author Artem Bilan
* @author Gary Russell
*
* @since 4.2
*/
public abstract class AbstractStompSessionManager implements StompSessionManager, ApplicationEventPublisherAware,
@@ -363,15 +366,11 @@ public abstract class AbstractStompSessionManager implements StompSessionManager
if (this.session != null) {
delegate.afterConnected(this.session, getConnectHeaders());
}
synchronized (this.delegates) {
this.delegates.add(delegate);
}
this.delegates.add(delegate);
}
void removeHandler(StompSessionHandler delegate) {
synchronized (this.delegates) {
this.delegates.remove(delegate);
}
this.delegates.remove(delegate);
}
@Override

View File

@@ -181,7 +181,7 @@ public class StompMessageHandler extends AbstractMessageHandler implements Appli
}
private StompSession connectIfNecessary() throws Exception {
synchronized (this.sessionHandler) {
synchronized (this.connectSemaphore) {
if (this.stompSession == null || !this.stompSessionManager.isConnected()) {
this.stompSessionManager.disconnect(this.sessionHandler);
this.stompSessionManager.connect(this.sessionHandler);
@@ -259,7 +259,7 @@ public class StompMessageHandler extends AbstractMessageHandler implements Appli
}
@Override
public synchronized void handleTransportError(StompSession session, Throwable exception) {
public void handleTransportError(StompSession session, Throwable exception) {
StompMessageHandler.this.transportError = exception;
StompMessageHandler.this.stompSession = null;
}