blob: 386e43fcdf0d2d9bb598fd6c83dcd1f63d2950be [file] [log] [blame]
/*
* 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.net.Socket;
import org.apache.tomcat.util.threads.ThreadPoolRunnable;
/*
* I switched the threading model here.
*
* We used to have a "listener" thread and a "connection"
* thread, this results in code simplicity but also a needless
* thread switch.
*
* Instead I am now using a pool of threads, all the threads are
* simmetric in their execution and no thread switch is needed.
*/
class LeaderFollowerWorkerThread implements ThreadPoolRunnable {
/* This is not a normal Runnable - it gets attached to an existing
thread, runs and when run() ends - the thread keeps running.
It's better to keep the name ThreadPoolRunnable - avoid confusion.
We also want to use per/thread data and avoid sync wherever possible.
*/
PoolTcpEndpoint endpoint;
public LeaderFollowerWorkerThread(PoolTcpEndpoint endpoint) {
this.endpoint = endpoint;
}
public Object[] getInitData() {
// no synchronization overhead, but 2 array access
Object obj[]=new Object[2];
obj[1]= endpoint.getConnectionHandler().init();
obj[0]=new TcpConnection();
return obj;
}
public void runIt(Object perThrData[]) {
// Create per-thread cache
if (endpoint.isRunning()) {
// Loop if endpoint is paused
while (endpoint.isPaused()) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// Ignore
}
}
// Accept a new connection
Socket s = null;
try {
s = endpoint.acceptSocket();
} finally {
// Continue accepting on another thread...
if (endpoint.isRunning()) {
endpoint.tp.runIt(this);
}
}
// Process the connection
if (null != s) {
endpoint.processSocket(s, (TcpConnection) perThrData[0], (Object[]) perThrData[1]);
}
}
}
}