Author: costin
Date: Wed Nov 23 21:27:02 2005
New Revision: 348659
URL: http://svn.apache.org/viewcvs?rev=348659&view=rev
Log:
New endpoint - it's a long time since I had this planned, now I got the chance.
I think this is the _RIGHT_ way to do the pool and threading - not run any
benchmark, but I have
a feeling it will be good ( in particular on MP machines !).
Each thread is accepting - the kernel decides who gets to process the request (
may accept at
the same time on multiple CPUs AFAIK ) - no thread switching or lock or
anything.
I'll use this as a base for the NIO stuff
Added:
tomcat/sandbox/java/org/apache/tomcat/util/net/AcceptorEndpoint.java
Added: tomcat/sandbox/java/org/apache/tomcat/util/net/AcceptorEndpoint.java
URL:
http://svn.apache.org/viewcvs/tomcat/sandbox/java/org/apache/tomcat/util/net/AcceptorEndpoint.java?rev=348659&view=auto
==============================================================================
--- tomcat/sandbox/java/org/apache/tomcat/util/net/AcceptorEndpoint.java (added)
+++ tomcat/sandbox/java/org/apache/tomcat/util/net/AcceptorEndpoint.java Wed
Nov 23 21:27:02 2005
@@ -0,0 +1,164 @@
+/*
+ * Copyright 1999-2004 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.
+ * 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.tomcat.util.net;
+
+import java.io.IOException;
+import java.net.Socket;
+
+import org.apache.tomcat.util.threads.ThreadWithAttributes;
+
+
+/** All threads blocked in accept(). New thread created on demand.
+ * No use of ThreadPool or ServerSocketFactory.
+ *
+ *
+ */
+public class AcceptorEndpoint extends SimpleEndpoint {
+
+ private final Object threadSync = new Object();
+
+ // ------ Leader follower fields
+
+ // ------ Master slave fields
+
+ /* The background thread. */
+ private Thread thread = null;
+
+ // active acceptors
+ private int acceptors=0;
+
+ public AcceptorEndpoint() {
+ }
+
+ // -------------------- Configuration --------------------
+
+ public String getStrategy() {
+ return "ms";
+ }
+
+ public void setStrategy(String strategy) {
+ }
+
+ public int getCurrentThreadsBusy() {
+ return curThreads;
+ }
+
+ // -------------------- Public methods --------------------
+
+ public void startEndpoint() throws IOException, InstantiationException {
+ if (!initialized) {
+ initEndpoint();
+ }
+ if( maxSpareThreads == minSpareThreads ) {
+ maxSpareThreads = minSpareThreads + 4;
+ }
+ running = true;
+ paused = false;
+ checkSpares();
+ }
+
+
+ // -------------------------------------------------- Master Slave Methods
+
+
+
+ /** Block in accept. If spares is low, create more spares.
+ * If spares is high - terminate this thread. Checks before
+ * and after running the connection handler.
+ */
+ class AcceptorThread implements Runnable {
+ private TcpConnection con = new TcpConnection();
+
+ public void run() {
+ Object[] threadData = getConnectionHandler().init();
+ while( running ) {
+ // Loop if endpoint is paused
+ if( checkSpares() ) {
+ return;
+ }
+
+ while (paused) {
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException e) {
+ // Ignore
+ }
+ }
+
+ Socket socket = acceptSocket();
+
+ workerStart(this);
+
+ // Process the request from this socket
+ processSocket(socket, con, threadData);
+
+ // Finish up this request
+ workerDone(this);
+
+ if( checkSpares() ) {
+ return;
+ }
+ }
+
+ acceptors--; // we're done
+ synchronized (threadSync) {
+ threadSync.notifyAll();
+ }
+ }
+ }
+
+ public void workerDone(Runnable workerThread) {
+ curThreads--;
+ }
+
+ void workerStart( Runnable r ) {
+ curThreads++;
+ }
+
+ void newAcceptor() {
+ acceptors++;
+ Thread t=new ThreadWithAttributes( this, new AcceptorThread());
+ t.setPriority(threadPriority);
+ t.setDaemon(daemon);
+ threadStart( t );
+ t.start();
+ }
+
+ /** Check the spare situation. If not enough - create more.
+ * If too many - return true to end this.
+ *
+ * @return
+ */
+ boolean checkSpares() {
+ // make sure we have min spare threads
+ while( (acceptors - curThreads ) < minSpareThreads ) {
+ if( acceptors >= maxThreads ) {
+ // limit reached, we won't accept any more requests.
+ } else {
+ newAcceptor();
+ }
+ }
+
+ if( acceptors - curThreads > maxSpareThreads ) {
+ threadEnd( Thread.currentThread() );
+ return true; // this one should go
+ }
+
+ return false;
+ }
+
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]