Author: markt Date: Sun Feb 16 18:27:16 2014 New Revision: 1568803 URL: http://svn.apache.org/r1568803 Log: Avoid possible deadlock when one thread tries to close a connection while another thread tries to write to it.
Modified: tomcat/trunk/java/org/apache/tomcat/websocket/WsRemoteEndpointImplBase.java tomcat/trunk/webapps/docs/changelog.xml Modified: tomcat/trunk/java/org/apache/tomcat/websocket/WsRemoteEndpointImplBase.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/websocket/WsRemoteEndpointImplBase.java?rev=1568803&r1=1568802&r2=1568803&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/tomcat/websocket/WsRemoteEndpointImplBase.java (original) +++ tomcat/trunk/java/org/apache/tomcat/websocket/WsRemoteEndpointImplBase.java Sun Feb 16 18:27:16 2014 @@ -249,6 +249,7 @@ public abstract class WsRemoteEndpointIm 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 @@ public abstract class WsRemoteEndpointIm } 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 @@ public abstract class WsRemoteEndpointIm // 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(); Modified: tomcat/trunk/webapps/docs/changelog.xml URL: http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/changelog.xml?rev=1568803&r1=1568802&r2=1568803&view=diff ============================================================================== --- tomcat/trunk/webapps/docs/changelog.xml (original) +++ tomcat/trunk/webapps/docs/changelog.xml Sun Feb 16 18:27:16 2014 @@ -70,6 +70,14 @@ </fix> </changelog> </subsection> + <subsection name="WebSocket"> + <changelog> + <fix> + Avoid a possible deadlock when one thread is shutting down a connection + while another thread is trying to write to it. (markt) + </fix> + </changelog> + </subsection> <subsection name="Other"> <changelog> <fix> --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org