Author: remy.maucherat(a)jboss.com
Date: 2014-02-17 05:33:49 -0500 (Mon, 17 Feb 2014)
New Revision: 2366
Modified:
branches/7.4.x/src/main/java/org/apache/tomcat/websocket/WsRemoteEndpointImplBase.java
Log:
Port patch to avoid deadlock closing during a write.
Modified:
branches/7.4.x/src/main/java/org/apache/tomcat/websocket/WsRemoteEndpointImplBase.java
===================================================================
---
branches/7.4.x/src/main/java/org/apache/tomcat/websocket/WsRemoteEndpointImplBase.java 2014-02-14
13:12:02 UTC (rev 2365)
+++
branches/7.4.x/src/main/java/org/apache/tomcat/websocket/WsRemoteEndpointImplBase.java 2014-02-17
10:33:49 UTC (rev 2366)
@@ -250,6 +250,7 @@
MessagePart mp = new MessagePart(opCode, payload, last, handler, this);
+ boolean doWrite = false;
synchronized (messagePartLock) {
if (Constants.OPCODE_CLOSE == mp.getOpCode()) {
try {
@@ -260,30 +261,38 @@
}
if (messagePartInProgress) {
// When a control message is sent while another message is being
- // the control message is queued. Chances are the subsequent
- // data message part will end up queued while the control
- // message is sent. The logic in this class (state machine,
- // EndMessageHanlder, TextMessageSendHandler) ensures that there
- // will only ever be one data message part in the queue. There
- // could be multiple control messages in the queue.
+ // sent, the control message is queued. Chances are the
+ // subsequent data message part will end up queued while the
+ // control message is sent. The logic in this class (state
+ // machine, EndMessageHandler, TextMessageSendHandler) ensures
+ // that there will only ever be one data message part in the
+ // queue. There could be multiple control messages in the queue.
// Add it to the queue
messagePartQueue.add(mp);
} else {
messagePartInProgress = true;
- writeMessagePart(mp);
+ doWrite = true;
}
}
+ if (doWrite) {
+ // Actual write has to be outside sync block to avoid possible
+ // deadlock between messagePartLock and writeLock in
+ // o.a.coyote.http11.upgrade.AbstractServletOutputStream
+ writeMessagePart(mp);
+ }
}
void endMessage(SendHandler handler, SendResult result) {
+ boolean doWrite = false;
+ MessagePart mpNext = null;
synchronized (messagePartLock) {
fragmented = nextFragmented;
text = nextText;
- MessagePart mpNext = messagePartQueue.poll();
+ mpNext = messagePartQueue.poll();
if (mpNext == null) {
messagePartInProgress = false;
} else if (!closed){
@@ -291,9 +300,15 @@
// sending a fragmented message closing the endpoint. If this
// happens, clearly there is no point trying to send the rest of
// the message.
- writeMessagePart(mpNext);
+ doWrite = true;
}
}
+ if (doWrite) {
+ // Actual write has to be outside sync block to avoid possible
+ // deadlock between messagePartLock and writeLock in
+ // o.a.coyote.http11.upgrade.AbstractServletOutputStream
+ writeMessagePart(mpNext);
+ }
wsSession.updateLastActive();
Show replies by date