1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 *
9 * 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, (TcpConnection) perThrData[0], (Object[]) perThrData[1]);
82 }
83
84 }
85 }
86
87 }