Author: remm
Date: Sat Apr 22 17:18:56 2006
New Revision: 396185
URL: http://svn.apache.org/viewcvs?rev=396185&view=rev
Log:
- Add support for using an Executor (the idea in that case is to define one
executor for the whole
server, with an appropriate queue, etc). By default, I think it is good to
continue using the
dumb stack, though.
Modified:
tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/net/AprEndpoint.java
tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/net/JIoEndpoint.java
tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/net/res/LocalStrings.properties
Modified: tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/net/AprEndpoint.java
URL:
http://svn.apache.org/viewcvs/tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/net/AprEndpoint.java?rev=396185&r1=396184&r2=396185&view=diff
==============================================================================
--- tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/net/AprEndpoint.java
(original)
+++ tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/net/AprEndpoint.java Sat
Apr 22 17:18:56 2006
@@ -1,5 +1,5 @@
/*
- * Copyright 2005 The Apache Software Foundation
+ * Copyright 2005-2006 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,21 +19,22 @@
import java.net.InetAddress;
import java.util.ArrayList;
import java.util.HashMap;
+import java.util.concurrent.Executor;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
-import org.apache.tomcat.jni.OS;
import org.apache.tomcat.jni.Address;
import org.apache.tomcat.jni.Error;
import org.apache.tomcat.jni.File;
import org.apache.tomcat.jni.Library;
+import org.apache.tomcat.jni.OS;
import org.apache.tomcat.jni.Poll;
import org.apache.tomcat.jni.Pool;
-import org.apache.tomcat.jni.Socket;
-import org.apache.tomcat.jni.Status;
import org.apache.tomcat.jni.SSL;
import org.apache.tomcat.jni.SSLContext;
import org.apache.tomcat.jni.SSLSocket;
+import org.apache.tomcat.jni.Socket;
+import org.apache.tomcat.jni.Status;
import org.apache.tomcat.util.res.StringManager;
import org.apache.tomcat.util.threads.ThreadWithAttributes;
@@ -159,6 +160,14 @@
/**
+ * External Executor based thread pool.
+ */
+ protected Executor executor = null;
+ public void setExecutor(Executor executor) { this.executor = executor; }
+ public Executor getExecutor() { return executor; }
+
+
+ /**
* Maximum amount of worker threads.
*/
protected int maxThreads = 40;
@@ -685,7 +694,9 @@
paused = false;
// Create worker collection
- workers = new WorkerStack(maxThreads);
+ if (executor == null) {
+ workers = new WorkerStack(maxThreads);
+ }
// Start acceptor thread
for (int i = 0; i < acceptorThreadCount; i++) {
@@ -962,7 +973,26 @@
}
}
}
+
+ /**
+ * Process given socket.
+ */
+ protected boolean processSocket(long socket) {
+ try {
+ if (executor == null) {
+ getWorkerThread().assign(socket);
+ } else {
+ executor.execute(new SocketProcessor(socket));
+ }
+ } catch (Throwable t) {
+ // This means we got an OOM or similar creating a thread, or that
+ // the pool and its queue are full
+ log.error(sm.getString("endpoint.process.fail"), t);
+ return false;
+ }
+ return true;
+ }
// --------------------------------------------------- Acceptor Inner Class
@@ -993,14 +1023,10 @@
}
try {
- // Allocate a new worker thread
- Worker workerThread = getWorkerThread();
// Accept the next incoming connection from the server
socket
long socket = Socket.accept(serverSock);
// Hand this socket off to an appropriate processor
- if (setSocketOptions(socket)) {
- workerThread.assign(socket);
- } else {
+ if (!setSocketOptions(socket) || !processSocket(socket)) {
// Close socket and pool right away
Socket.destroy(socket);
}
@@ -1154,15 +1180,14 @@
if (rv > 0) {
keepAliveCount -= rv;
for (int n = 0; n < rv; n++) {
- // Check for failed sockets
+ // Check for failed sockets and hand this socket
off to a worker
if (((desc[n*2] & Poll.APR_POLLHUP) ==
Poll.APR_POLLHUP)
- || ((desc[n*2] & Poll.APR_POLLERR) ==
Poll.APR_POLLERR)) {
+ || ((desc[n*2] & Poll.APR_POLLERR) ==
Poll.APR_POLLERR)
+ || (!processSocket(desc[n*2+1]))) {
// Close socket and clear pool
Socket.destroy(desc[n*2+1]);
continue;
}
- // Hand this socket off to a worker
- getWorkerThread().assign(desc[n*2+1]);
}
} else if (rv < 0) {
int errn = -rv;
@@ -1548,7 +1573,9 @@
Socket.timeoutSet(state.socket, soTimeout
* 1000);
// If all done hand this socket off to a
worker for
// processing of further requests
- getWorkerThread().assign(state.socket);
+ if (!processSocket(state.socket)) {
+ Socket.destroy(state.socket);
+ }
} else {
// Close the socket since this is
// the end of not keep-alive request.
@@ -1651,4 +1678,34 @@
}
}
+
+ // ---------------------------------------------- SocketProcessor Inner
Class
+
+
+ /**
+ * This class is the equivalent of the Worker, but will simply use in an
+ * external Executor thread pool.
+ */
+ protected class SocketProcessor implements Runnable {
+
+ protected long socket = 0;
+
+ public SocketProcessor(long socket) {
+ this.socket = socket;
+ }
+
+ public void run() {
+
+ // Process the request from this socket
+ if (!handler.process(socket)) {
+ // Close socket and pool
+ Socket.destroy(socket);
+ socket = 0;
+ }
+
+ }
+
+ }
+
+
}
Modified: tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/net/JIoEndpoint.java
URL:
http://svn.apache.org/viewcvs/tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/net/JIoEndpoint.java?rev=396185&r1=396184&r2=396185&view=diff
==============================================================================
--- tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/net/JIoEndpoint.java
(original)
+++ tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/net/JIoEndpoint.java Sat
Apr 22 17:18:56 2006
@@ -1,5 +1,5 @@
/*
- * Copyright 1999-2004 The Apache Software Foundation
+ * Copyright 1999-2006 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
+import java.util.concurrent.Executor;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -49,7 +50,7 @@
// -------------------------------------------------------------- Constants
- protected static Log log=LogFactory.getLog(JIoEndpoint.class );
+ protected static Log log = LogFactory.getLog(JIoEndpoint.class);
protected StringManager sm =
StringManager.getManager("org.apache.tomcat.util.net.res");
@@ -116,6 +117,14 @@
/**
+ * External Executor based thread pool.
+ */
+ protected Executor executor = null;
+ public void setExecutor(Executor executor) { this.executor = executor; }
+ public Executor getExecutor() { return executor; }
+
+
+ /**
* Maximum amount of worker threads.
*/
protected int maxThreads = 40;
@@ -272,17 +281,12 @@
}
}
- // Allocate a new worker thread
- Worker workerThread = getWorkerThread();
-
// Accept the next incoming connection from the server socket
try {
Socket socket =
serverSocketFactory.acceptSocket(serverSocket);
serverSocketFactory.initSocket(socket);
// Hand this socket off to an appropriate processor
- if (setSocketOptions(socket)) {
- workerThread.assign(socket);
- } else {
+ if (!setSocketOptions(socket) || !processSocket(socket)) {
// Close socket right away
try {
socket.close();
@@ -302,6 +306,40 @@
}
+ // ------------------------------------------- SocketProcessor Inner Class
+
+
+ /**
+ * This class is the equivalent of the Worker, but will simply use in an
+ * external Executor thread pool.
+ */
+ protected class SocketProcessor implements Runnable {
+
+ protected Socket socket = null;
+
+ public SocketProcessor(Socket socket) {
+ this.socket = socket;
+ }
+
+ public void run() {
+
+ // Process the request from this socket
+ if (!handler.process(socket)) {
+ // Close socket
+ try {
+ socket.close();
+ } catch (IOException e) {
+ }
+ }
+
+ // Finish up this request
+ socket = null;
+
+ }
+
+ }
+
+
// ----------------------------------------------------- Worker Inner Class
@@ -442,6 +480,11 @@
running = true;
paused = false;
+ // Create worker collection
+ if (executor == null) {
+ workers = new WorkerStack(maxThreads);
+ }
+
// Start acceptor thread
acceptorThread = new Thread(new Acceptor(), getName() +
"-Acceptor");
acceptorThread.setPriority(threadPriority);
@@ -480,7 +523,7 @@
}
if (serverSocket != null) {
try {
- if (serverSocket!=null)
+ if (serverSocket != null)
serverSocket.close();
} catch (Exception e) {
log.error(sm.getString("endpoint.err.close"), e);
@@ -635,6 +678,26 @@
}
}
+
+ /**
+ * Process given socket.
+ */
+ protected boolean processSocket(Socket socket) {
+ try {
+ if (executor == null) {
+ getWorkerThread().assign(socket);
+ } else {
+ executor.execute(new SocketProcessor(socket));
+ }
+ } catch (Throwable t) {
+ // This means we got an OOM or similar creating a thread, or that
+ // the pool and its queue are full
+ log.error(sm.getString("endpoint.process.fail"), t);
+ return false;
+ }
+ return true;
+ }
+
// ------------------------------------------------- WorkerStack Inner
Class
Modified:
tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/net/res/LocalStrings.properties
URL:
http://svn.apache.org/viewcvs/tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/net/res/LocalStrings.properties?rev=396185&r1=396184&r2=396185&view=diff
==============================================================================
---
tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/net/res/LocalStrings.properties
(original)
+++
tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/net/res/LocalStrings.properties
Sat Apr 22 17:18:56 2006
@@ -19,6 +19,7 @@
endpoint.poll.initfail=Poller creation failed
endpoint.poll.fail=Critical poller failure (restarting poller): [{0}] {1}
endpoint.poll.error=Unexpected poller error
+endpoint.process.fail=Error allocating socket processor
endpoint.sendfile.error=Unexpected sendfile error
endpoint.sendfile.addfail=Sednfile failure: [{0}] {1}
endpoint.sendfile.nosupport=Disabling sendfile, since either the APR version
or the system doesn't support it
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]