JBossWeb SVN: r2289 - branches/7.4.x/src/main/java/org/apache/tomcat/websocket.
by jbossweb-commits@lists.jboss.org
Author: remy.maucherat(a)jboss.com
Date: 2013-10-23 04:36:46 -0400 (Wed, 23 Oct 2013)
New Revision: 2289
Modified:
branches/7.4.x/src/main/java/org/apache/tomcat/websocket/WsWebSocketContainer.java
Log:
Port patch adding connection timeout to websockets.
Modified: branches/7.4.x/src/main/java/org/apache/tomcat/websocket/WsWebSocketContainer.java
===================================================================
--- branches/7.4.x/src/main/java/org/apache/tomcat/websocket/WsWebSocketContainer.java 2013-10-23 08:31:30 UTC (rev 2288)
+++ branches/7.4.x/src/main/java/org/apache/tomcat/websocket/WsWebSocketContainer.java 2013-10-23 08:36:46 UTC (rev 2289)
@@ -49,6 +49,7 @@
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicInteger;
import javax.net.ssl.SSLContext;
@@ -87,6 +88,16 @@
"org.apache.tomcat.websocket.SSL_TRUSTSTORE_PWD";
public static final String SSL_TRUSTSTORE_PWD_DEFAULT = "changeit";
+ /**
+ * Property name to set to configure the timeout (in milliseconds) when
+ * establishing a WebSocket connection to server. The default is
+ * {@link #IO_TIMEOUT_MS_DEFAULT}.
+ */
+ public static final String IO_TIMEOUT_MS_PROPERTY =
+ "org.apache.tomcat.websocket.IO_TIMEOUT_MS";
+
+ public static final long IO_TIMEOUT_MS_DEFAULT = 5000;
+
private static final Random random = new Random();
private static final byte[] crlf = new byte[] {13, 10};
private static final AsynchronousChannelGroup asynchronousChannelGroup;
@@ -273,30 +284,38 @@
channel = new AsyncChannelWrapperNonSecure(socketChannel);
}
+ // Get the connection timeout
+ long timeout = IO_TIMEOUT_MS_DEFAULT;
+ String timeoutValue = (String) clientEndpointConfiguration.getUserProperties().get(
+ IO_TIMEOUT_MS_PROPERTY);
+ if (timeoutValue != null) {
+ timeout = Long.valueOf(timeoutValue).intValue();
+ }
+
ByteBuffer response;
String subProtocol;
try {
- fConnect.get();
+ fConnect.get(timeout, TimeUnit.MILLISECONDS);
Future<Void> fHandshake = channel.handshake();
- fHandshake.get();
+ fHandshake.get(timeout, TimeUnit.MILLISECONDS);
int toWrite = request.limit();
Future<Integer> fWrite = channel.write(request);
- Integer thisWrite = fWrite.get();
+ Integer thisWrite = fWrite.get(timeout, TimeUnit.MILLISECONDS);
toWrite -= thisWrite.intValue();
while (toWrite > 0) {
fWrite = channel.write(request);
- thisWrite = fWrite.get();
+ thisWrite = fWrite.get(timeout, TimeUnit.MILLISECONDS);
toWrite -= thisWrite.intValue();
}
// Same size as the WsFrame input buffer
response = ByteBuffer.allocate(maxBinaryMessageBufferSize);
HandshakeResponse handshakeResponse =
- processResponse(response, channel);
+ processResponse(response, channel, timeout);
clientEndpointConfiguration.getConfigurator().
afterResponse(handshakeResponse);
@@ -319,6 +338,8 @@
throw new DeploymentException(MESSAGES.httpRequestFailed(), e);
} catch (EOFException e) {
throw new DeploymentException(MESSAGES.httpRequestFailed(), e);
+ } catch (TimeoutException e) {
+ throw new DeploymentException(MESSAGES.httpRequestFailed(), e);
}
// Switch to WebSocket
@@ -528,10 +549,12 @@
* @throws ExecutionException
* @throws InterruptedException
* @throws DeploymentException
+ * @throws TimeoutException
*/
private HandshakeResponse processResponse(ByteBuffer response,
- AsyncChannelWrapper channel) throws InterruptedException,
- ExecutionException, DeploymentException, EOFException {
+ AsyncChannelWrapper channel, long timeout) throws InterruptedException,
+ ExecutionException, DeploymentException, EOFException,
+ TimeoutException {
Map<String,List<String>> headers = new HashMap<String, List<String>>();
@@ -541,7 +564,7 @@
while (!readHeaders) {
// Blocking read
Future<Integer> read = channel.read(response);
- Integer bytesRead = read.get();
+ Integer bytesRead = read.get(timeout, TimeUnit.MILLISECONDS);
if (bytesRead.intValue() == -1) {
throw new EOFException();
}
11 years, 2 months
JBossWeb SVN: r2288 - in branches: 7.4.x/src/main/java/org/apache/jasper and 1 other directory.
by jbossweb-commits@lists.jboss.org
Author: remy.maucherat(a)jboss.com
Date: 2013-10-23 04:31:30 -0400 (Wed, 23 Oct 2013)
New Revision: 2288
Modified:
branches/7.3.x/src/main/java/org/apache/jasper/EmbeddedServletOptions.java
branches/7.4.x/src/main/java/org/apache/jasper/EmbeddedServletOptions.java
Log:
JBWEB-281: Use genStringAsCharArray as used in AS.
Modified: branches/7.3.x/src/main/java/org/apache/jasper/EmbeddedServletOptions.java
===================================================================
--- branches/7.3.x/src/main/java/org/apache/jasper/EmbeddedServletOptions.java 2013-10-23 08:12:47 UTC (rev 2287)
+++ branches/7.3.x/src/main/java/org/apache/jasper/EmbeddedServletOptions.java 2013-10-23 08:31:30 UTC (rev 2288)
@@ -531,7 +531,7 @@
}
}
- String genCharArray = config.getInitParameter("genStrAsCharArray");
+ String genCharArray = config.getInitParameter("genStringAsCharArray");
if (genCharArray != null) {
if (genCharArray.equalsIgnoreCase("true")) {
genStringAsCharArray = true;
Modified: branches/7.4.x/src/main/java/org/apache/jasper/EmbeddedServletOptions.java
===================================================================
--- branches/7.4.x/src/main/java/org/apache/jasper/EmbeddedServletOptions.java 2013-10-23 08:12:47 UTC (rev 2287)
+++ branches/7.4.x/src/main/java/org/apache/jasper/EmbeddedServletOptions.java 2013-10-23 08:31:30 UTC (rev 2288)
@@ -531,7 +531,7 @@
}
}
- String genCharArray = config.getInitParameter("genStrAsCharArray");
+ String genCharArray = config.getInitParameter("genStringAsCharArray");
if (genCharArray != null) {
if (genCharArray.equalsIgnoreCase("true")) {
genStringAsCharArray = true;
11 years, 2 months
JBossWeb SVN: r2287 - in branches: 7.4.x/src/main/java/org/apache/catalina/security and 1 other directory.
by jbossweb-commits@lists.jboss.org
Author: remy.maucherat(a)jboss.com
Date: 2013-10-23 04:12:47 -0400 (Wed, 23 Oct 2013)
New Revision: 2287
Modified:
branches/7.3.x/src/main/java/org/apache/catalina/security/SecurityUtil.java
branches/7.4.x/src/main/java/org/apache/catalina/security/SecurityUtil.java
Log:
JBWEB-282: Change cache to concurrent hash map due to concurrent startup.
Modified: branches/7.3.x/src/main/java/org/apache/catalina/security/SecurityUtil.java
===================================================================
--- branches/7.3.x/src/main/java/org/apache/catalina/security/SecurityUtil.java 2013-10-21 10:06:15 UTC (rev 2286)
+++ branches/7.3.x/src/main/java/org/apache/catalina/security/SecurityUtil.java 2013-10-23 08:12:47 UTC (rev 2287)
@@ -23,7 +23,8 @@
import java.security.Principal;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
-import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
import javax.security.auth.Subject;
import javax.servlet.Filter;
@@ -66,8 +67,8 @@
/**
* Cache every object for which we are creating method on it.
*/
- private static HashMap<Object,Method[]> objectCache =
- new HashMap<Object,Method[]>();
+ private static Map<Object,Method[]> objectCache =
+ new ConcurrentHashMap<Object,Method[]>();
private static boolean packageDefinitionEnabled =
(System.getProperty("package.definition") == null &&
Modified: branches/7.4.x/src/main/java/org/apache/catalina/security/SecurityUtil.java
===================================================================
--- branches/7.4.x/src/main/java/org/apache/catalina/security/SecurityUtil.java 2013-10-21 10:06:15 UTC (rev 2286)
+++ branches/7.4.x/src/main/java/org/apache/catalina/security/SecurityUtil.java 2013-10-23 08:12:47 UTC (rev 2287)
@@ -23,7 +23,8 @@
import java.security.Principal;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
-import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
import javax.security.auth.Subject;
import javax.servlet.Filter;
@@ -66,8 +67,8 @@
/**
* Cache every object for which we are creating method on it.
*/
- private static HashMap<Object,Method[]> objectCache =
- new HashMap<Object,Method[]>();
+ private static Map<Object,Method[]> objectCache =
+ new ConcurrentHashMap<Object,Method[]>();
private static boolean packageDefinitionEnabled =
(System.getProperty("package.definition") == null &&
11 years, 2 months
JBossWeb SVN: r2286 - branches/7.4.x/src/main/java/org/apache/tomcat/websocket.
by jbossweb-commits@lists.jboss.org
Author: remy.maucherat(a)jboss.com
Date: 2013-10-21 06:06:15 -0400 (Mon, 21 Oct 2013)
New Revision: 2286
Modified:
branches/7.4.x/src/main/java/org/apache/tomcat/websocket/Util.java
branches/7.4.x/src/main/java/org/apache/tomcat/websocket/WsSession.java
Log:
Port websockets patches (array support + pass session to message handler method calls).
Modified: branches/7.4.x/src/main/java/org/apache/tomcat/websocket/Util.java
===================================================================
--- branches/7.4.x/src/main/java/org/apache/tomcat/websocket/Util.java 2013-10-18 08:30:12 UTC (rev 2285)
+++ branches/7.4.x/src/main/java/org/apache/tomcat/websocket/Util.java 2013-10-21 10:06:15 UTC (rev 2286)
@@ -20,6 +20,7 @@
import java.io.InputStream;
import java.io.Reader;
+import java.lang.reflect.GenericArrayType;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
@@ -46,6 +47,7 @@
import javax.websocket.EndpointConfig;
import javax.websocket.MessageHandler;
import javax.websocket.PongMessage;
+import javax.websocket.Session;
import org.apache.tomcat.websocket.pojo.PojoMessageHandlerWholeBinary;
import org.apache.tomcat.websocket.pojo.PojoMessageHandlerWholeText;
@@ -158,22 +160,22 @@
static Class<?> getMessageType(MessageHandler listener) {
- return (Class<?>) Util.getGenericType(MessageHandler.class,
- listener.getClass());
+ return Util.getGenericType(MessageHandler.class,
+ listener.getClass()).getClazz();
}
public static Class<?> getDecoderType(Class<? extends Decoder> decoder) {
- return (Class<?>) Util.getGenericType(Decoder.class, decoder);
+ return Util.getGenericType(Decoder.class, decoder).getClazz();
}
static Class<?> getEncoderType(Class<? extends Encoder> encoder) {
- return (Class<?>) Util.getGenericType(Encoder.class, encoder);
+ return Util.getGenericType(Encoder.class, encoder).getClazz();
}
- private static <T> Object getGenericType(Class<T> type,
+ private static <T> TypeResult getGenericType(Class<T> type,
Class<? extends T> clazz) {
// Look to see if this class implements the generic MessageHandler<>
@@ -200,24 +202,52 @@
Class<? extends T> superClazz =
(Class<? extends T>) clazz.getSuperclass();
- Object result = getGenericType(type, superClazz);
- if (result instanceof Class<?>) {
+ TypeResult superClassTypeResult = getGenericType(type, superClazz);
+ int dimension = superClassTypeResult.getDimension();
+ if (superClassTypeResult.getIndex() == -1 && dimension == 0) {
// Superclass implements interface and defines explicit type for
// MessageHandler<>
- return result;
- } else if (result instanceof Integer) {
+ return superClassTypeResult;
+ }
+
+ if (superClassTypeResult.getIndex() > -1) {
// Superclass implements interface and defines unknown type for
// MessageHandler<>
// Map that unknown type to the generic types defined in this class
ParameterizedType superClassType =
(ParameterizedType) clazz.getGenericSuperclass();
- return getTypeParameter(clazz,
+ TypeResult result = getTypeParameter(clazz,
superClassType.getActualTypeArguments()[
- ((Integer) result).intValue()]);
- } else {
- // Error will be logged further up the call stack
- return null;
+ superClassTypeResult.getIndex()]);
+ result.incrementDimension(superClassTypeResult.getDimension());
+ if (result.getClazz() != null && result.getDimension() > 0) {
+ superClassTypeResult = result;
+ } else {
+ return result;
+ }
}
+
+ if (superClassTypeResult.getDimension() > 0) {
+ StringBuilder className = new StringBuilder();
+ for (int i = 0; i < dimension; i++) {
+ className.append('[');
+ }
+ className.append('L');
+ className.append(superClassTypeResult.getClazz().getCanonicalName());
+ className.append(';');
+
+ Class<?> arrayClazz;
+ try {
+ arrayClazz = Class.forName(className.toString());
+ } catch (ClassNotFoundException e) {
+ throw new IllegalArgumentException(e);
+ }
+
+ return new TypeResult(arrayClazz, -1, 0);
+ }
+
+ // Error will be logged further up the call stack
+ return null;
}
@@ -225,16 +255,21 @@
* For a generic parameter, return either the Class used or if the type
* is unknown, the index for the type in definition of the class
*/
- private static Object getTypeParameter(Class<?> clazz, Type argType) {
+ private static TypeResult getTypeParameter(Class<?> clazz, Type argType) {
if (argType instanceof Class<?>) {
- return argType;
+ return new TypeResult((Class<?>) argType, -1, 0);
} else if (argType instanceof ParameterizedType) {
- return ((ParameterizedType) argType).getRawType();
+ return new TypeResult((Class<?>)((ParameterizedType) argType).getRawType(), -1, 0);
+ } else if (argType instanceof GenericArrayType) {
+ Type arrayElementType = ((GenericArrayType) argType).getGenericComponentType();
+ TypeResult result = getTypeParameter(clazz, arrayElementType);
+ result.incrementDimension(1);
+ return result;
} else {
TypeVariable<?>[] tvs = clazz.getTypeParameters();
for (int i = 0; i < tvs.length; i++) {
if (tvs[i].equals(argType)) {
- return Integer.valueOf(i);
+ return new TypeResult(null, i, 0);
}
}
return null;
@@ -313,7 +348,8 @@
public static Set<MessageHandlerResult> getMessageHandlers(
- MessageHandler listener, EndpointConfig endpointConfig) {
+ MessageHandler listener, EndpointConfig endpointConfig,
+ Session session) {
Class<?> target = Util.getMessageType(listener);
@@ -342,7 +378,7 @@
} else if (byte[].class.isAssignableFrom(target)) {
MessageHandlerResult result = new MessageHandlerResult(
new PojoMessageHandlerWholeBinary(listener,
- getOnMessageMethod(listener), null,
+ getOnMessageMethod(listener), session,
endpointConfig, null, new Object[1], 0, true, -1,
false, -1),
MessageHandlerResultType.BINARY);
@@ -350,7 +386,7 @@
} else if (InputStream.class.isAssignableFrom(target)) {
MessageHandlerResult result = new MessageHandlerResult(
new PojoMessageHandlerWholeBinary(listener,
- getOnMessageMethod(listener), null,
+ getOnMessageMethod(listener), session,
endpointConfig, null, new Object[1], 0, true, -1,
true, -1),
MessageHandlerResultType.BINARY);
@@ -358,7 +394,7 @@
} else if (Reader.class.isAssignableFrom(target)) {
MessageHandlerResult result = new MessageHandlerResult(
new PojoMessageHandlerWholeText(listener,
- getOnMessageMethod(listener), null,
+ getOnMessageMethod(listener), session,
endpointConfig, null, new Object[1], 0, true, -1,
-1),
MessageHandlerResultType.TEXT);
@@ -379,7 +415,7 @@
Method m = getOnMessageMethod(listener);
if (decoderMatch.getBinaryDecoders().size() > 0) {
MessageHandlerResult result = new MessageHandlerResult(
- new PojoMessageHandlerWholeBinary(listener, m, null,
+ new PojoMessageHandlerWholeBinary(listener, m, session,
endpointConfig,
decoderMatch.getBinaryDecoders(), new Object[1],
0, false, -1, false, -1),
@@ -388,7 +424,7 @@
}
if (decoderMatch.getTextDecoders().size() > 0) {
MessageHandlerResult result = new MessageHandlerResult(
- new PojoMessageHandlerWholeText(listener, m, null,
+ new PojoMessageHandlerWholeText(listener, m, session,
endpointConfig,
decoderMatch.getTextDecoders(), new Object[1],
0, false, -1, -1),
@@ -472,4 +508,33 @@
return (textDecoders.size() > 0) || (binaryDecoders.size() > 0);
}
}
+
+
+ private static class TypeResult {
+ private final Class<?> clazz;
+ private final int index;
+ private int dimension;
+
+ public TypeResult(Class<?> clazz, int index, int dimension) {
+ this.clazz= clazz;
+ this.index = index;
+ this.dimension = dimension;
+ }
+
+ public Class<?> getClazz() {
+ return clazz;
+ }
+
+ public int getIndex() {
+ return index;
+ }
+
+ public int getDimension() {
+ return dimension;
+ }
+
+ public void incrementDimension(int inc) {
+ dimension += inc;
+ }
+ }
}
Modified: branches/7.4.x/src/main/java/org/apache/tomcat/websocket/WsSession.java
===================================================================
--- branches/7.4.x/src/main/java/org/apache/tomcat/websocket/WsSession.java 2013-10-18 08:30:12 UTC (rev 2285)
+++ branches/7.4.x/src/main/java/org/apache/tomcat/websocket/WsSession.java 2013-10-21 10:06:15 UTC (rev 2286)
@@ -174,7 +174,7 @@
// just as easily.
Set<MessageHandlerResult> mhResults =
- Util.getMessageHandlers(listener, endpointConfig);
+ Util.getMessageHandlers(listener, endpointConfig, this);
for (MessageHandlerResult mhResult : mhResults) {
switch (mhResult.getType()) {
11 years, 2 months
JBossWeb SVN: r2285 - branches/7.4.x/src/main/java/org/apache/tomcat/websocket.
by jbossweb-commits@lists.jboss.org
Author: remy.maucherat(a)jboss.com
Date: 2013-10-18 04:30:12 -0400 (Fri, 18 Oct 2013)
New Revision: 2285
Modified:
branches/7.4.x/src/main/java/org/apache/tomcat/websocket/Util.java
Log:
Port patch for generic type handling for WS components.
Modified: branches/7.4.x/src/main/java/org/apache/tomcat/websocket/Util.java
===================================================================
--- branches/7.4.x/src/main/java/org/apache/tomcat/websocket/Util.java 2013-10-17 12:26:41 UTC (rev 2284)
+++ branches/7.4.x/src/main/java/org/apache/tomcat/websocket/Util.java 2013-10-18 08:30:12 UTC (rev 2285)
@@ -163,8 +163,8 @@
}
- public static Class<?> getDecoderType(Class<? extends Decoder> Decoder) {
- return (Class<?>) Util.getGenericType(Decoder.class, Decoder);
+ public static Class<?> getDecoderType(Class<? extends Decoder> decoder) {
+ return (Class<?>) Util.getGenericType(Decoder.class, decoder);
}
@@ -228,6 +228,8 @@
private static Object getTypeParameter(Class<?> clazz, Type argType) {
if (argType instanceof Class<?>) {
return argType;
+ } else if (argType instanceof ParameterizedType) {
+ return ((ParameterizedType) argType).getRawType();
} else {
TypeVariable<?>[] tvs = clazz.getTypeParameters();
for (int i = 0; i < tvs.length; i++) {
11 years, 2 months
JBossWeb SVN: r2284 - branches/7.4.x/src/main/java/org/apache/coyote/http11.
by jbossweb-commits@lists.jboss.org
Author: remy.maucherat(a)jboss.com
Date: 2013-10-17 08:26:41 -0400 (Thu, 17 Oct 2013)
New Revision: 2284
Modified:
branches/7.4.x/src/main/java/org/apache/coyote/http11/InternalNioInputBuffer.java
branches/7.4.x/src/main/java/org/apache/coyote/http11/InternalNioOutputBuffer.java
Log:
- Some more cleanups.
- Refactor again using a reusable semaphore.
Modified: branches/7.4.x/src/main/java/org/apache/coyote/http11/InternalNioInputBuffer.java
===================================================================
--- branches/7.4.x/src/main/java/org/apache/coyote/http11/InternalNioInputBuffer.java 2013-10-16 16:57:58 UTC (rev 2283)
+++ branches/7.4.x/src/main/java/org/apache/coyote/http11/InternalNioInputBuffer.java 2013-10-17 12:26:41 UTC (rev 2284)
@@ -23,10 +23,9 @@
import java.io.EOFException;
import java.io.IOException;
import java.net.SocketTimeoutException;
-import java.nio.ByteBuffer;
import java.nio.channels.ClosedChannelException;
import java.nio.channels.CompletionHandler;
-import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
import org.apache.coyote.InputBuffer;
@@ -81,9 +80,9 @@
private CompletionHandler<Integer, NioChannel> completionHandler;
/**
- * Lock used for auto blocking.
+ * Semaphore used for waiting for completion handler.
*/
- private CountDownLatch latch = new CountDownLatch(0);
+ private Semaphore semaphore = new Semaphore(1);
/**
* Create a new instance of {@code InternalNioInputBuffer}
@@ -121,7 +120,7 @@
bbuf.flip();
bbuf.get(buf, pos, nBytes);
lastValid = pos + nBytes;
- latch.countDown();
+ semaphore.release();
if (!processor.isProcessing() && processor.getReadNotifications()) {
if (!endpoint.processChannel(attachment, SocketStatus.OPEN_READ)) {
endpoint.closeChannel(attachment);
@@ -134,6 +133,7 @@
public void failed(Throwable exc, NioChannel attachment) {
processor.getResponse().setErrorException(exc);
endpoint.removeEventChannel(attachment);
+ semaphore.release();
if (!endpoint.processChannel(attachment, SocketStatus.ERROR)) {
endpoint.closeChannel(attachment);
}
@@ -196,8 +196,11 @@
*/
public boolean nextRequest() {
boolean result = super.nextRequest();
- nonBlocking = false;
available = false;
+ if (nonBlocking) {
+ semaphore.release();
+ }
+ nonBlocking = false;
return result;
}
@@ -418,18 +421,23 @@
int nRead = 0;
// Reading from client
if (nonBlocking) {
- synchronized (completionHandler) {
- if (latch.getCount() == 0) {
- // Prepare the internal input buffer for reading
- this.prepare();
- nonBlockingRead(readTimeout, unit);
- nRead = lastValid - pos;
+ if (semaphore.tryAcquire()) {
+ // Prepare the internal input buffer for reading
+ prepare();
+ try {
+ channel.read(bbuf, readTimeout, TimeUnit.MILLISECONDS, channel, this.completionHandler);
+ } catch (Exception e) {
+ processor.getResponse().setErrorException(e);
+ if (CoyoteLogger.HTTP_LOGGER.isDebugEnabled()) {
+ CoyoteLogger.HTTP_LOGGER.errorWithNonBlockingRead(e);
+ }
}
- }
- // If there's nothing and flow control is not used, autoblock
- if (nRead == 0 && !available) {
+ nRead = lastValid - pos;
+ } else if (nRead == 0 && !available) {
+ // If there's nothing and flow control is not used, autoblock
try {
- latch.await(readTimeout, unit);
+ if (semaphore.tryAcquire(readTimeout, unit))
+ semaphore.release();
} catch (InterruptedException e) {
// Ignore
}
@@ -437,7 +445,7 @@
}
} else {
// Prepare the internal input buffer for reading
- this.prepare();
+ prepare();
nRead = blockingRead(readTimeout, unit);
if (nRead > 0) {
bbuf.flip();
@@ -465,7 +473,6 @@
*/
private void prepare() {
bbuf.clear();
-
if (parsingHeader) {
if (lastValid == buf.length) {
throw MESSAGES.requestHeaderTooLarge();
@@ -484,25 +491,6 @@
}
/**
- * Read a sequence of bytes in non-blocking mode from he current channel
- *
- * @param bb
- * the byte buffer which will contain the bytes read from the
- * current channel
- */
- private void nonBlockingRead(long timeout, TimeUnit unit) {
- try {
- latch = new CountDownLatch(1);
- channel.read(bbuf, channel, this.completionHandler);
- } catch (Exception e) {
- processor.getResponse().setErrorException(e);
- if (CoyoteLogger.HTTP_LOGGER.isDebugEnabled()) {
- CoyoteLogger.HTTP_LOGGER.errorWithNonBlockingRead(e);
- }
- }
- }
-
- /**
* Read a sequence of bytes in blocking mode from he current channel
*
* @param bb
Modified: branches/7.4.x/src/main/java/org/apache/coyote/http11/InternalNioOutputBuffer.java
===================================================================
--- branches/7.4.x/src/main/java/org/apache/coyote/http11/InternalNioOutputBuffer.java 2013-10-16 16:57:58 UTC (rev 2283)
+++ branches/7.4.x/src/main/java/org/apache/coyote/http11/InternalNioOutputBuffer.java 2013-10-17 12:26:41 UTC (rev 2284)
@@ -23,7 +23,7 @@
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.CompletionHandler;
-import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
import org.apache.coyote.ActionCode;
@@ -138,10 +138,10 @@
*/
private CompletionHandler<Integer, NioChannel> completionHandler;
- /**
- * Latch used for auto blocking.
- */
- private CountDownLatch latch = new CountDownLatch(0);
+ /**
+ * Semaphore used for waiting for completion handler.
+ */
+ private Semaphore semaphore = new Semaphore(1);
/**
* Create a new instance of {@code InternalNioOutputBuffer}
@@ -209,7 +209,7 @@
} else {
response.setLastWrite(nBytes);
leftover.recycle();
- latch.countDown();
+ semaphore.release();
if (!processor.isProcessing() && processor.getWriteNotification()) {
if (!endpoint.processChannel(attachment, SocketStatus.OPEN_WRITE)) {
endpoint.closeChannel(attachment);
@@ -226,6 +226,7 @@
public void failed(Throwable exc, NioChannel attachment) {
processor.getResponse().setErrorException(exc);
endpoint.removeEventChannel(attachment);
+ semaphore.release();
if (!endpoint.processChannel(attachment, SocketStatus.ERROR)) {
endpoint.closeChannel(attachment);
}
@@ -288,35 +289,6 @@
return nw;
}
- /**
- * Perform a non-blocking write operation
- *
- * @param buffer
- * the buffer containing the data to write
- * @param timeout
- * a timeout for the operation
- * @param unit
- * The time unit
- */
- private void nonBlockingWrite(final long timeout, final TimeUnit unit) {
- try {
- latch = new CountDownLatch(1);
- // Calculate the number of bytes that fit in the buffer
- int n = Math.min(leftover.getLength(), bbuf.capacity() - bbuf.position());
- // put bytes in the buffer
- bbuf.put(leftover.getBuffer(), leftover.getOffset(), n).flip();
- // Update the offset
- leftover.setOffset(leftover.getOffset() + n);
- // Perform the write operation
- this.channel.write(this.bbuf, timeout, unit, this.channel, this.completionHandler);
- } catch (Throwable t) {
- processor.getResponse().setErrorException(t);
- if (CoyoteLogger.HTTP_LOGGER.isDebugEnabled()) {
- CoyoteLogger.HTTP_LOGGER.errorWithNonBlockingWrite(t);
- }
- }
- }
-
/**
* Perform a write operation. The operation may be blocking or non-blocking
* depending on the value of {@code nonBlocking} flag.
@@ -542,6 +514,9 @@
lastActiveFilter = -1;
committed = false;
finished = false;
+ if (nonBlocking) {
+ semaphore.release();
+ }
nonBlocking = false;
}
@@ -839,7 +814,8 @@
if (leftover.getLength() > Constants.ASYNC_BUFFER_SIZE && response.getFlushLeftovers()
&& Http11AbstractProcessor.containerThread.get() == Boolean.TRUE) {
try {
- latch.await(writeTimeout, TimeUnit.MILLISECONDS);
+ if (semaphore.tryAcquire(writeTimeout, TimeUnit.MILLISECONDS))
+ semaphore.release();
} catch (InterruptedException e) {
// Ignore
}
@@ -849,8 +825,19 @@
if (leftover.getLength() > Constants.ASYNC_BUFFER_SIZE) {
response.setLastWrite(0);
}
- if (latch.getCount() == 0) {
- nonBlockingWrite(writeTimeout, TimeUnit.MILLISECONDS);
+ if (semaphore.tryAcquire()) {
+ // Calculate the number of bytes that fit in the buffer
+ int n = Math.min(leftover.getLength(), bbuf.capacity() - bbuf.position());
+ bbuf.put(leftover.getBuffer(), leftover.getOffset(), n).flip();
+ leftover.setOffset(leftover.getOffset() + n);
+ try {
+ channel.write(bbuf, writeTimeout, TimeUnit.MILLISECONDS, channel, completionHandler);
+ } catch (Exception e) {
+ processor.getResponse().setErrorException(e);
+ if (CoyoteLogger.HTTP_LOGGER.isDebugEnabled()) {
+ CoyoteLogger.HTTP_LOGGER.errorWithNonBlockingWrite(e);
+ }
+ }
}
}
} else {
11 years, 2 months
JBossWeb SVN: r2283 - branches/7.4.x/src/main/java/org/apache/coyote/http11.
by jbossweb-commits@lists.jboss.org
Author: remy.maucherat(a)jboss.com
Date: 2013-10-16 12:57:58 -0400 (Wed, 16 Oct 2013)
New Revision: 2283
Modified:
branches/7.4.x/src/main/java/org/apache/coyote/http11/InternalNioInputBuffer.java
branches/7.4.x/src/main/java/org/apache/coyote/http11/InternalNioOutputBuffer.java
Log:
Some cleanups.
Modified: branches/7.4.x/src/main/java/org/apache/coyote/http11/InternalNioInputBuffer.java
===================================================================
--- branches/7.4.x/src/main/java/org/apache/coyote/http11/InternalNioInputBuffer.java 2013-10-16 12:46:56 UTC (rev 2282)
+++ branches/7.4.x/src/main/java/org/apache/coyote/http11/InternalNioInputBuffer.java 2013-10-16 16:57:58 UTC (rev 2283)
@@ -81,9 +81,9 @@
private CompletionHandler<Integer, NioChannel> completionHandler;
/**
- * Latch used for auto blocking.
+ * Lock used for auto blocking.
*/
- private CountDownLatch latch = null;
+ private CountDownLatch latch = new CountDownLatch(0);
/**
* Create a new instance of {@code InternalNioInputBuffer}
@@ -419,11 +419,14 @@
// Reading from client
if (nonBlocking) {
synchronized (completionHandler) {
- // Prepare the internal input buffer for reading
- this.prepare();
- nonBlockingRead(bbuf, readTimeout, unit);
- nRead = lastValid - pos;
+ if (latch.getCount() == 0) {
+ // Prepare the internal input buffer for reading
+ this.prepare();
+ nonBlockingRead(readTimeout, unit);
+ nRead = lastValid - pos;
+ }
}
+ // If there's nothing and flow control is not used, autoblock
if (nRead == 0 && !available) {
try {
latch.await(readTimeout, unit);
@@ -435,7 +438,7 @@
} else {
// Prepare the internal input buffer for reading
this.prepare();
- nRead = blockingRead(bbuf, readTimeout, unit);
+ nRead = blockingRead(readTimeout, unit);
if (nRead > 0) {
bbuf.flip();
if (nRead > (buf.length - end)) {
@@ -487,11 +490,10 @@
* the byte buffer which will contain the bytes read from the
* current channel
*/
- private void nonBlockingRead(final ByteBuffer bb, long timeout, TimeUnit unit) {
- final NioChannel ch = this.channel;
+ private void nonBlockingRead(long timeout, TimeUnit unit) {
try {
latch = new CountDownLatch(1);
- ch.read(bb, ch, this.completionHandler);
+ channel.read(bbuf, channel, this.completionHandler);
} catch (Exception e) {
processor.getResponse().setErrorException(e);
if (CoyoteLogger.HTTP_LOGGER.isDebugEnabled()) {
@@ -507,11 +509,11 @@
* @return the number of bytes read or -1 if the end of the stream was
* reached
*/
- private int blockingRead(ByteBuffer bb, long timeout, TimeUnit unit) {
+ private int blockingRead(long timeout, TimeUnit unit) {
int nr = 0;
try {
long readTimeout = timeout > 0 ? timeout : Integer.MAX_VALUE;
- nr = this.channel.readBytes(bb, readTimeout, unit);
+ nr = this.channel.readBytes(bbuf, readTimeout, unit);
if (nr < 0) {
close(channel);
}
Modified: branches/7.4.x/src/main/java/org/apache/coyote/http11/InternalNioOutputBuffer.java
===================================================================
--- branches/7.4.x/src/main/java/org/apache/coyote/http11/InternalNioOutputBuffer.java 2013-10-16 12:46:56 UTC (rev 2282)
+++ branches/7.4.x/src/main/java/org/apache/coyote/http11/InternalNioOutputBuffer.java 2013-10-16 16:57:58 UTC (rev 2283)
@@ -300,6 +300,7 @@
*/
private void nonBlockingWrite(final long timeout, final TimeUnit unit) {
try {
+ latch = new CountDownLatch(1);
// Calculate the number of bytes that fit in the buffer
int n = Math.min(leftover.getLength(), bbuf.capacity() - bbuf.position());
// put bytes in the buffer
@@ -307,7 +308,6 @@
// Update the offset
leftover.setOffset(leftover.getOffset() + n);
// Perform the write operation
- latch = new CountDownLatch(1);
this.channel.write(this.bbuf, timeout, unit, this.channel, this.completionHandler);
} catch (Throwable t) {
processor.getResponse().setErrorException(t);
@@ -835,7 +835,7 @@
*/
public int doWrite(ByteChunk chunk, Response res) throws IOException {
if (nonBlocking) {
- // Autoblocking if the buffer is already full
+ // If the buffer is growing and flow control is not used, autoblock if in a container thread
if (leftover.getLength() > Constants.ASYNC_BUFFER_SIZE && response.getFlushLeftovers()
&& Http11AbstractProcessor.containerThread.get() == Boolean.TRUE) {
try {
11 years, 2 months
JBossWeb SVN: r2282 - branches/7.4.x/src/main/java/org/apache/catalina/connector.
by jbossweb-commits@lists.jboss.org
Author: remy.maucherat(a)jboss.com
Date: 2013-10-16 08:46:56 -0400 (Wed, 16 Oct 2013)
New Revision: 2282
Modified:
branches/7.4.x/src/main/java/org/apache/catalina/connector/CoyoteAdapter.java
branches/7.4.x/src/main/java/org/apache/catalina/connector/Request.java
branches/7.4.x/src/main/java/org/apache/catalina/connector/Response.java
Log:
- If upgrading, discard the IS and OS, the examples are not doing cleanup well enough.
Modified: branches/7.4.x/src/main/java/org/apache/catalina/connector/CoyoteAdapter.java
===================================================================
--- branches/7.4.x/src/main/java/org/apache/catalina/connector/CoyoteAdapter.java 2013-10-16 12:44:02 UTC (rev 2281)
+++ branches/7.4.x/src/main/java/org/apache/catalina/connector/CoyoteAdapter.java 2013-10-16 12:46:56 UTC (rev 2282)
@@ -267,6 +267,10 @@
req.getRequestProcessor().setWorkerThreadName(null);
// Recycle the wrapper request and response
if (error || close || response.isClosed()) {
+ if (request.getUpgradeHandler() != null) {
+ request.clearInputStream();
+ response.clearOutputStream();
+ }
request.recycle();
response.recycle();
res.action(ActionCode.ACTION_EVENT_END, null);
Modified: branches/7.4.x/src/main/java/org/apache/catalina/connector/Request.java
===================================================================
--- branches/7.4.x/src/main/java/org/apache/catalina/connector/Request.java 2013-10-16 12:44:02 UTC (rev 2281)
+++ branches/7.4.x/src/main/java/org/apache/catalina/connector/Request.java 2013-10-16 12:46:56 UTC (rev 2282)
@@ -597,6 +597,17 @@
/**
+ * Clear output stream.
+ */
+ public void clearInputStream() {
+ if (inputStream != null) {
+ inputStream.clear();
+ inputStream = null;
+ }
+ }
+
+
+ /**
* Clear cached encoders (to save memory for event or async requests).
*/
public void clearEncoders() {
Modified: branches/7.4.x/src/main/java/org/apache/catalina/connector/Response.java
===================================================================
--- branches/7.4.x/src/main/java/org/apache/catalina/connector/Response.java 2013-10-16 12:44:02 UTC (rev 2281)
+++ branches/7.4.x/src/main/java/org/apache/catalina/connector/Response.java 2013-10-16 12:46:56 UTC (rev 2282)
@@ -290,6 +290,17 @@
}
+ /**
+ * Clear output stream.
+ */
+ public void clearOutputStream() {
+ if (outputStream != null) {
+ outputStream.clear();
+ outputStream = null;
+ }
+ }
+
+
// ------------------------------------------------------- Response Methods
11 years, 2 months
JBossWeb SVN: r2281 - branches/7.4.x/src/main/java/org/apache/tomcat/websocket.
by jbossweb-commits@lists.jboss.org
Author: remy.maucherat(a)jboss.com
Date: 2013-10-16 08:44:02 -0400 (Wed, 16 Oct 2013)
New Revision: 2281
Modified:
branches/7.4.x/src/main/java/org/apache/tomcat/websocket/WsSession.java
Log:
Pour WS patch.
Modified: branches/7.4.x/src/main/java/org/apache/tomcat/websocket/WsSession.java
===================================================================
--- branches/7.4.x/src/main/java/org/apache/tomcat/websocket/WsSession.java 2013-10-16 10:48:32 UTC (rev 2280)
+++ branches/7.4.x/src/main/java/org/apache/tomcat/websocket/WsSession.java 2013-10-16 12:44:02 UTC (rev 2281)
@@ -32,6 +32,7 @@
import java.util.concurrent.atomic.AtomicLong;
import javax.websocket.CloseReason;
+import javax.websocket.CloseReason.CloseCode;
import javax.websocket.CloseReason.CloseCodes;
import javax.websocket.DeploymentException;
import javax.websocket.Endpoint;
@@ -460,7 +461,8 @@
private void sendCloseMessage(CloseReason closeReason) {
// 125 is maximum size for the payload of a control message
ByteBuffer msg = ByteBuffer.allocate(125);
- msg.putShort((short) closeReason.getCloseCode().getCode());
+ CloseCode closeCode = closeReason.getCloseCode();
+ msg.putShort((short) closeCode.getCode());
String reason = closeReason.getReasonPhrase();
if (reason != null && reason.length() > 0) {
@@ -475,7 +477,13 @@
// deal with the Exception
WebsocketsLogger.ROOT_LOGGER.closeMessageFail(ioe);
wsRemoteEndpoint.close();
- localEndpoint.onError(this, ioe);
+ // Failure to send a close message is not unexpected in the case of
+ // an abnormal closure (usually triggered by a failure to read/write
+ // from/to the client. In this case do not trigger the endpoint's
+ // error handling
+ if (closeCode != CloseCodes.CLOSED_ABNORMALLY) {
+ localEndpoint.onError(this, ioe);
+ }
} finally {
webSocketContainer.unregisterSession(localEndpoint, this);
}
11 years, 2 months
JBossWeb SVN: r2280 - in branches/7.4.x/src/main/java/org/apache: coyote and 2 other directories.
by jbossweb-commits@lists.jboss.org
Author: remy.maucherat(a)jboss.com
Date: 2013-10-16 06:48:32 -0400 (Wed, 16 Oct 2013)
New Revision: 2280
Modified:
branches/7.4.x/src/main/java/org/apache/catalina/core/StandardWrapperValve.java
branches/7.4.x/src/main/java/org/apache/coyote/Response.java
branches/7.4.x/src/main/java/org/apache/coyote/http11/Http11NioProcessor.java
branches/7.4.x/src/main/java/org/apache/coyote/http11/Http11NioProtocol.java
branches/7.4.x/src/main/java/org/apache/coyote/http11/InternalNioInputBuffer.java
branches/7.4.x/src/main/java/org/apache/coyote/http11/InternalNioOutputBuffer.java
branches/7.4.x/src/main/java/org/apache/tomcat/util/net/NioEndpoint.java
Log:
- Some exception reporting.
- Be careful about using processChannel.
Modified: branches/7.4.x/src/main/java/org/apache/catalina/core/StandardWrapperValve.java
===================================================================
--- branches/7.4.x/src/main/java/org/apache/catalina/core/StandardWrapperValve.java 2013-10-15 17:30:15 UTC (rev 2279)
+++ branches/7.4.x/src/main/java/org/apache/catalina/core/StandardWrapperValve.java 2013-10-16 10:48:32 UTC (rev 2280)
@@ -546,7 +546,12 @@
if (error) {
Throwable throwable = asyncContext.getError();
if (throwable == null) {
- throwable = new EOFException();
+ throwable = response.getCoyoteResponse().getErrorException();
+ if (throwable != null) {
+ throwable = new IOException(throwable);
+ } else {
+ throwable = new EOFException();
+ }
}
if (request.getReadListener() != null) {
request.getReadListener().onError(throwable);
Modified: branches/7.4.x/src/main/java/org/apache/coyote/Response.java
===================================================================
--- branches/7.4.x/src/main/java/org/apache/coyote/Response.java 2013-10-15 17:30:15 UTC (rev 2279)
+++ branches/7.4.x/src/main/java/org/apache/coyote/Response.java 2013-10-16 10:48:32 UTC (rev 2280)
@@ -110,7 +110,7 @@
/**
* Holds request error exception.
*/
- protected Exception errorException = null;
+ protected Throwable errorException = null;
/**
* Has the charset been explicitly set.
@@ -262,8 +262,8 @@
* Set the error Exception that occurred during
* request processing.
*/
- public void setErrorException(Exception ex) {
- errorException = ex;
+ public void setErrorException(Throwable t) {
+ errorException = t;
}
@@ -271,7 +271,7 @@
* Get the Exception that occurred during request
* processing.
*/
- public Exception getErrorException() {
+ public Throwable getErrorException() {
return errorException;
}
Modified: branches/7.4.x/src/main/java/org/apache/coyote/http11/Http11NioProcessor.java
===================================================================
--- branches/7.4.x/src/main/java/org/apache/coyote/http11/Http11NioProcessor.java 2013-10-15 17:30:15 UTC (rev 2279)
+++ branches/7.4.x/src/main/java/org/apache/coyote/http11/Http11NioProcessor.java 2013-10-16 10:48:32 UTC (rev 2280)
@@ -301,7 +301,9 @@
// Reach the end of the stream
failed(null, attachment);
} else {
- endpoint.processChannel(ch, null);
+ if (!endpoint.processChannel(attachment, null)) {
+ closeChannel(attachment);
+ }
}
}
Modified: branches/7.4.x/src/main/java/org/apache/coyote/http11/Http11NioProtocol.java
===================================================================
--- branches/7.4.x/src/main/java/org/apache/coyote/http11/Http11NioProtocol.java 2013-10-15 17:30:15 UTC (rev 2279)
+++ branches/7.4.x/src/main/java/org/apache/coyote/http11/Http11NioProtocol.java 2013-10-16 10:48:32 UTC (rev 2280)
@@ -806,6 +806,7 @@
* .AsynchronousSocketChannel, org.apache.tomcat.util.net.ChannelStatus)
*/
@Override
+ // FIXME: probably needs sync due to concurrent read/write possibilities
public synchronized SocketState event(NioChannel channel, SocketStatus status) {
Http11NioProcessor processor = connections.get(channel.getId());
@@ -848,7 +849,9 @@
if (nBytes < 0) {
failed(new ClosedChannelException(), endpoint);
} else {
- endpoint.processChannel(ch, null);
+ if (!endpoint.processChannel(ch, null)) {
+ endpoint.closeChannel(ch);
+ }
}
}
@@ -895,7 +898,7 @@
}
processor.startProcessing();
- if (proto.secure && (proto.sslImplementation != null)) {
+ if (proto.secure && (proto.sslImplementation != null)) {
processor.setSSLSupport(((NioJSSEImplementation) proto.sslImplementation).getSSLSupport(channel));
} else {
processor.setSSLSupport(null);
@@ -913,9 +916,9 @@
// Call a read event right away
state = event(channel, SocketStatus.OPEN_READ);
} else {
- proto.endpoint.addEventChannel(channel, processor.getTimeout(),
+ proto.endpoint.addEventChannel(channel, processor.getTimeout(),
processor.getReadNotifications(), false,
- processor.getResumeNotification(), false);
+ processor.getResumeNotification(), false);
}
} else {
recycledProcessors.offer(processor);
Modified: branches/7.4.x/src/main/java/org/apache/coyote/http11/InternalNioInputBuffer.java
===================================================================
--- branches/7.4.x/src/main/java/org/apache/coyote/http11/InternalNioInputBuffer.java 2013-10-15 17:30:15 UTC (rev 2279)
+++ branches/7.4.x/src/main/java/org/apache/coyote/http11/InternalNioInputBuffer.java 2013-10-16 10:48:32 UTC (rev 2280)
@@ -123,17 +123,19 @@
lastValid = pos + nBytes;
latch.countDown();
if (!processor.isProcessing() && processor.getReadNotifications()) {
- endpoint.processChannel(attachment, SocketStatus.OPEN_READ);
+ if (!endpoint.processChannel(attachment, SocketStatus.OPEN_READ)) {
+ endpoint.closeChannel(attachment);
+ }
}
}
}
@Override
public void failed(Throwable exc, NioChannel attachment) {
- exc.printStackTrace();
+ processor.getResponse().setErrorException(exc);
endpoint.removeEventChannel(attachment);
- if (!processor.isProcessing()) {
- endpoint.processChannel(attachment, SocketStatus.ERROR);
+ if (!endpoint.processChannel(attachment, SocketStatus.ERROR)) {
+ endpoint.closeChannel(attachment);
}
}
};
@@ -490,9 +492,10 @@
try {
latch = new CountDownLatch(1);
ch.read(bb, ch, this.completionHandler);
- } catch (Throwable t) {
+ } catch (Exception e) {
+ processor.getResponse().setErrorException(e);
if (CoyoteLogger.HTTP_LOGGER.isDebugEnabled()) {
- CoyoteLogger.HTTP_LOGGER.errorWithNonBlockingRead(t);
+ CoyoteLogger.HTTP_LOGGER.errorWithNonBlockingRead(e);
}
}
}
Modified: branches/7.4.x/src/main/java/org/apache/coyote/http11/InternalNioOutputBuffer.java
===================================================================
--- branches/7.4.x/src/main/java/org/apache/coyote/http11/InternalNioOutputBuffer.java 2013-10-15 17:30:15 UTC (rev 2279)
+++ branches/7.4.x/src/main/java/org/apache/coyote/http11/InternalNioOutputBuffer.java 2013-10-16 10:48:32 UTC (rev 2280)
@@ -211,7 +211,9 @@
leftover.recycle();
latch.countDown();
if (!processor.isProcessing() && processor.getWriteNotification()) {
- endpoint.processChannel(attachment, SocketStatus.OPEN_WRITE);
+ if (!endpoint.processChannel(attachment, SocketStatus.OPEN_WRITE)) {
+ endpoint.closeChannel(attachment);
+ }
}
return;
}
@@ -222,11 +224,11 @@
@Override
public void failed(Throwable exc, NioChannel attachment) {
- exc.printStackTrace();
+ processor.getResponse().setErrorException(exc);
endpoint.removeEventChannel(attachment);
- if (!processor.isProcessing()) {
- endpoint.processChannel(attachment, SocketStatus.ERROR);
- }
+ if (!endpoint.processChannel(attachment, SocketStatus.ERROR)) {
+ endpoint.closeChannel(attachment);
+ }
}
};
}
@@ -308,6 +310,7 @@
latch = new CountDownLatch(1);
this.channel.write(this.bbuf, timeout, unit, this.channel, this.completionHandler);
} catch (Throwable t) {
+ processor.getResponse().setErrorException(t);
if (CoyoteLogger.HTTP_LOGGER.isDebugEnabled()) {
CoyoteLogger.HTTP_LOGGER.errorWithNonBlockingWrite(t);
}
@@ -529,7 +532,12 @@
}
// Reset pointers
- leftover.recycle();
+ byte[] leftoverBuf = leftover.getBuffer();
+ if (leftoverBuf != null && leftoverBuf.length > Constants.ASYNC_BUFFER_SIZE) {
+ leftover = new ByteChunk();
+ } else {
+ leftover.recycle();
+ }
pos = 0;
lastActiveFilter = -1;
committed = false;
@@ -835,7 +843,6 @@
} catch (InterruptedException e) {
// Ignore
}
- // FIXME? throw new IOException(MESSAGES.invalidBacklog());
}
synchronized (completionHandler) {
leftover.append(chunk);
Modified: branches/7.4.x/src/main/java/org/apache/tomcat/util/net/NioEndpoint.java
===================================================================
--- branches/7.4.x/src/main/java/org/apache/tomcat/util/net/NioEndpoint.java 2013-10-15 17:30:15 UTC (rev 2279)
+++ branches/7.4.x/src/main/java/org/apache/tomcat/util/net/NioEndpoint.java 2013-10-16 10:48:32 UTC (rev 2280)
@@ -1271,7 +1271,9 @@
@Override
public void failed(Throwable exc, NioChannel attach) {
remove(attach);
- processChannel(attach, SocketStatus.ERROR);
+ if (!processChannel(attach, SocketStatus.ERROR)) {
+ closeChannel(attach);
+ }
// Recycle the completion handler
recycleHanlder(this);
}
@@ -1315,29 +1317,28 @@
} else {
info.flags = ChannelInfo.merge(info.flags, flag);
}
+
// Setting the channel timeout
info.timeout = date;
-
final NioChannel ch = channel;
-
if (info.resume()) {
remove(info);
if (!processChannel(ch, SocketStatus.OPEN_CALLBACK)) {
closeChannel(ch);
}
- } else if (info.read()) {
- try {
- // Trying awaiting for read event
- ch.awaitRead(ch, getCompletionHandler());
- } catch (Exception e) {
- // Ignore
- CoyoteLogger.UTIL_LOGGER.errorAwaitingRead(e);
- }
} else if (info.write()) {
remove(info);
if (!processChannel(ch, SocketStatus.OPEN_WRITE)) {
closeChannel(ch);
}
+ } else if (info.read()) {
+ try {
+ // Trying awaiting for read event
+ ch.awaitRead(ch, getCompletionHandler());
+ } catch (Exception e) {
+ // Ignore
+ CoyoteLogger.UTIL_LOGGER.errorAwaitingRead(e);
+ }
} else if (info.wakeup()) {
remove(info);
// TODO
11 years, 2 months