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: [email protected]
For additional commands, e-mail: [email protected]