Author: markt Date: Fri Jan 31 18:34:18 2014 New Revision: 1563206 URL: http://svn.apache.org/r1563206 Log: Enable non-blocking reads to take place on non-container threads.
Added: tomcat/trunk/java/org/apache/coyote/ContainerThreadMarker.java (with props) Modified: tomcat/trunk/java/org/apache/catalina/connector/CoyoteAdapter.java tomcat/trunk/java/org/apache/catalina/connector/InputBuffer.java tomcat/trunk/java/org/apache/coyote/AbstractProtocol.java tomcat/trunk/java/org/apache/coyote/ajp/AjpNioProcessor.java tomcat/trunk/java/org/apache/coyote/http11/Http11NioProcessor.java tomcat/trunk/webapps/docs/changelog.xml Modified: tomcat/trunk/java/org/apache/catalina/connector/CoyoteAdapter.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/connector/CoyoteAdapter.java?rev=1563206&r1=1563205&r2=1563206&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/connector/CoyoteAdapter.java (original) +++ tomcat/trunk/java/org/apache/catalina/connector/CoyoteAdapter.java Fri Jan 31 18:34:18 2014 @@ -373,7 +373,14 @@ public class CoyoteAdapter implements Ad ClassLoader oldCL = null; try { oldCL = request.getContext().bind(false, null); - readListener.onDataAvailable(); + // If data is being read on a non-container thread a + // dispatch with status OPEN_READ will be used to get + // execution back on a container thread for the + // onAllDataRead() event. Therefore, make sure + // onDataAvailable() is not called in this case. + if (!request.isFinished()) { + readListener.onDataAvailable(); + } if (request.isFinished() && req.sendAllDataReadEvent()) { readListener.onAllDataRead(); } Modified: tomcat/trunk/java/org/apache/catalina/connector/InputBuffer.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/connector/InputBuffer.java?rev=1563206&r1=1563205&r2=1563206&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/connector/InputBuffer.java (original) +++ tomcat/trunk/java/org/apache/catalina/connector/InputBuffer.java Fri Jan 31 18:34:18 2014 @@ -27,6 +27,7 @@ import javax.servlet.ReadListener; import org.apache.catalina.security.SecurityUtil; import org.apache.coyote.ActionCode; +import org.apache.coyote.ContainerThreadMarker; import org.apache.coyote.Request; import org.apache.tomcat.util.buf.B2CConverter; import org.apache.tomcat.util.buf.ByteChunk; @@ -273,8 +274,19 @@ public class InputBuffer extends Reader if (coyoteRequest.getReadListener() == null) { throw new IllegalStateException("not in non blocking mode."); } - int available = available(); - boolean result = available > 0; + // Need to check is finished before we check available() as BIO always + // returns 1 for isAvailable() + if (isFinished()) { + // If this is a non-container thread, need to trigger a read + // which will eventually lead to a call to onAllDataRead() via a + // container thread. + if (!ContainerThreadMarker.isContainerThread()) { + coyoteRequest.action(ActionCode.DISPATCH_READ, null); + coyoteRequest.action(ActionCode.DISPATCH_EXECUTE, null); + } + return false; + } + boolean result = available() > 0; if (!result) { coyoteRequest.action(ActionCode.NB_READ_INTEREST, null); } Modified: tomcat/trunk/java/org/apache/coyote/AbstractProtocol.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/AbstractProtocol.java?rev=1563206&r1=1563205&r2=1563206&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/coyote/AbstractProtocol.java (original) +++ tomcat/trunk/java/org/apache/coyote/AbstractProtocol.java Fri Jan 31 18:34:18 2014 @@ -609,6 +609,7 @@ public abstract class AbstractProtocol<S } wrapper.setAsync(false); + ContainerThreadMarker.markAsContainerThread(); try { if (processor == null) { Added: tomcat/trunk/java/org/apache/coyote/ContainerThreadMarker.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/ContainerThreadMarker.java?rev=1563206&view=auto ============================================================================== --- tomcat/trunk/java/org/apache/coyote/ContainerThreadMarker.java (added) +++ tomcat/trunk/java/org/apache/coyote/ContainerThreadMarker.java Fri Jan 31 18:34:18 2014 @@ -0,0 +1,35 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.coyote; + +public class ContainerThreadMarker { + + private static final ThreadLocal<Boolean> marker = new ThreadLocal<>(); + + public static boolean isContainerThread() { + Boolean flag = marker.get(); + if (flag == null) { + return false; + } else { + return flag.booleanValue(); + } + } + + public static void markAsContainerThread() { + marker.set(Boolean.TRUE); + } +} Propchange: tomcat/trunk/java/org/apache/coyote/ContainerThreadMarker.java ------------------------------------------------------------------------------ svn:eol-style = native Modified: tomcat/trunk/java/org/apache/coyote/ajp/AjpNioProcessor.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/ajp/AjpNioProcessor.java?rev=1563206&r1=1563205&r2=1563206&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/coyote/ajp/AjpNioProcessor.java (original) +++ tomcat/trunk/java/org/apache/coyote/ajp/AjpNioProcessor.java Fri Jan 31 18:34:18 2014 @@ -59,17 +59,20 @@ public class AjpNioProcessor extends Abs @Override protected void registerForEvent(boolean read, boolean write) { + final NioChannel socket = socketWrapper.getSocket(); final NioEndpoint.KeyAttachment attach = - (NioEndpoint.KeyAttachment)socketWrapper.getSocket().getAttachment( - false); + (NioEndpoint.KeyAttachment) socket.getAttachment(false); if (attach == null) { return; } + SelectionKey key = socket.getIOChannel().keyFor(socket.getPoller().getSelector()); if (read) { attach.interestOps(attach.interestOps() | SelectionKey.OP_READ); + key.interestOps(key.interestOps() | SelectionKey.OP_READ); } if (write) { attach.interestOps(attach.interestOps() | SelectionKey.OP_WRITE); + key.interestOps(key.interestOps() | SelectionKey.OP_READ); } } Modified: tomcat/trunk/java/org/apache/coyote/http11/Http11NioProcessor.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/Http11NioProcessor.java?rev=1563206&r1=1563205&r2=1563206&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/coyote/http11/Http11NioProcessor.java (original) +++ tomcat/trunk/java/org/apache/coyote/http11/Http11NioProcessor.java Fri Jan 31 18:34:18 2014 @@ -154,17 +154,20 @@ public class Http11NioProcessor extends @Override protected void registerForEvent(boolean read, boolean write) { + final NioChannel socket = socketWrapper.getSocket(); final NioEndpoint.KeyAttachment attach = - (NioEndpoint.KeyAttachment)socketWrapper.getSocket().getAttachment( - false); + (NioEndpoint.KeyAttachment) socket.getAttachment(false); if (attach == null) { return; } + SelectionKey key = socket.getIOChannel().keyFor(socket.getPoller().getSelector()); if (read) { attach.interestOps(attach.interestOps() | SelectionKey.OP_READ); + key.interestOps(key.interestOps() | SelectionKey.OP_READ); } if (write) { attach.interestOps(attach.interestOps() | SelectionKey.OP_WRITE); + key.interestOps(key.interestOps() | SelectionKey.OP_WRITE); } } Modified: tomcat/trunk/webapps/docs/changelog.xml URL: http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/changelog.xml?rev=1563206&r1=1563205&r2=1563206&view=diff ============================================================================== --- tomcat/trunk/webapps/docs/changelog.xml (original) +++ tomcat/trunk/webapps/docs/changelog.xml Fri Jan 31 18:34:18 2014 @@ -58,6 +58,14 @@ </fix> </changelog> </subsection> + <subsection name="Coyote"> + <changelog> + <fix> + Enable non-blocking reads to take place on non-container threads. + (markt) + </fix> + </changelog> + </subsection> <subsection name="Cluster"> <changelog> <scode> --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org