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]