01: /*
02: * Licensed to the Apache Software Foundation (ASF) under one or more
03: * contributor license agreements. See the NOTICE file distributed with
04: * this work for additional information regarding copyright ownership.
05: * The ASF licenses this file to You under the Apache License, Version 2.0
06: * (the "License"); you may not use this file except in compliance with
07: * the License. You may obtain a copy of the License at
08: *
09: * http://www.apache.org/licenses/LICENSE-2.0
10: *
11: * Unless required by applicable law or agreed to in writing, software
12: * distributed under the License is distributed on an "AS IS" BASIS,
13: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14: * See the License for the specific language governing permissions and
15: * limitations under the License.
16: */
17:
18: package org.apache.tomcat.util.net;
19:
20: import java.net.Socket;
21: import org.apache.tomcat.util.threads.ThreadPoolRunnable;
22:
23: /*
24: * I switched the threading model here.
25: *
26: * We used to have a "listener" thread and a "connection"
27: * thread, this results in code simplicity but also a needless
28: * thread switch.
29: *
30: * Instead I am now using a pool of threads, all the threads are
31: * simmetric in their execution and no thread switch is needed.
32: */
33: class LeaderFollowerWorkerThread implements ThreadPoolRunnable {
34: /* This is not a normal Runnable - it gets attached to an existing
35: thread, runs and when run() ends - the thread keeps running.
36:
37: It's better to keep the name ThreadPoolRunnable - avoid confusion.
38: We also want to use per/thread data and avoid sync wherever possible.
39: */
40: PoolTcpEndpoint endpoint;
41:
42: public LeaderFollowerWorkerThread(PoolTcpEndpoint endpoint) {
43: this .endpoint = endpoint;
44: }
45:
46: public Object[] getInitData() {
47: // no synchronization overhead, but 2 array access
48: Object obj[] = new Object[2];
49: obj[1] = endpoint.getConnectionHandler().init();
50: obj[0] = new TcpConnection();
51: return obj;
52: }
53:
54: public void runIt(Object perThrData[]) {
55:
56: // Create per-thread cache
57: if (endpoint.isRunning()) {
58:
59: // Loop if endpoint is paused
60: while (endpoint.isPaused()) {
61: try {
62: Thread.sleep(1000);
63: } catch (InterruptedException e) {
64: // Ignore
65: }
66: }
67:
68: // Accept a new connection
69: Socket s = null;
70: try {
71: s = endpoint.acceptSocket();
72: } finally {
73: // Continue accepting on another thread...
74: if (endpoint.isRunning()) {
75: endpoint.tp.runIt(this );
76: }
77: }
78:
79: // Process the connection
80: if (null != s) {
81: endpoint.processSocket(s,
82: (TcpConnection) perThrData[0],
83: (Object[]) perThrData[1]);
84: }
85:
86: }
87: }
88:
89: }
|