1 package com.quadcap.net.server; 2 3 40 41 import java.io.IOException ; 42 43 import java.util.Hashtable ; 44 import java.util.Iterator ; 45 import java.util.Properties ; 46 47 import java.net.ServerSocket ; 48 49 import com.quadcap.util.collections.ArrayQueue; 50 import com.quadcap.util.collections.IntMap; 51 52 58 public class Server { 59 Class workerClass; 60 Object workerLock = new Object (); 61 Object context; 62 ThreadGroup threads; 63 IntMap allWorkers; 64 ArrayQueue workers; 65 int numWorkers = 0; 66 int maxWorkers = 128; 67 long shutdownInterval = 2000L; 68 String name; 69 70 109 public Server(Properties props, Object context) 110 throws ClassNotFoundException 111 { 112 this.context = context; 113 this.workerClass = Class.forName(props.getProperty("workerClass")); 114 115 int max = Integer.parseInt(props.getProperty("maxWorkers", "64")); 116 this.workers = new ArrayQueue(max); 117 this.allWorkers = new IntMap(max / 3); 118 this.name = props.getProperty("name", "server"); 119 this.threads = new ThreadGroup (name); 120 this.shutdownInterval = 121 Long.parseLong(props.getProperty("shutdownInterval", "2000")); 122 123 } 124 125 public ThreadGroup getThreadGroup() { 126 return threads; 127 } 128 129 public void startAcceptor(Properties props) throws IOException { 130 int port = Integer.parseInt(props.getProperty("port")); 131 int queueDepth = 132 Integer.parseInt(props.getProperty("queueDepth", "16")); 133 Acceptor acceptor = new Acceptor(this, port, queueDepth); 134 Thread t = new Thread (threads, acceptor); 135 t.start(); 136 } 137 138 public Worker getIdleWorker() throws Exception { 140 synchronized (workerLock) { 141 while (true) { 142 Worker w = (Worker)workers.popFront(); 143 if (w != null) return w; 144 145 if (numWorkers < maxWorkers) { 146 return newWorker(); 147 } else { 148 try { 149 workerLock.wait(); 150 } catch (InterruptedException ee) { 151 } 152 } 153 } 154 } 155 } 156 157 public int getIdleWorkers(Worker[] workerv) throws Exception { 158 int cnt = 0; 159 synchronized (workerLock) { 160 for (; cnt < workerv.length; cnt++) { 161 Worker w = (Worker)workers.popFront(); 162 if (w != null) { 163 workerv[cnt] = w; 164 } else { 165 if (numWorkers < maxWorkers) { 166 workerv[cnt] = newWorker(); 167 } else if (cnt > 0) { 168 break; 169 } else { 170 try { 171 workerLock.wait(); 172 } catch (InterruptedException ee) { 173 } 174 } 175 } 176 } 177 } 178 return cnt; 179 } 180 181 public void returnIdleWorker(Worker w) { 182 synchronized (workerLock) { 183 workers.pushFront(w); 184 workerLock.notifyAll(); 185 } 186 } 187 188 public void workerDone(Worker w) { 189 allWorkers.remove(w.getId()); 190 workerLock.notifyAll(); 191 } 192 193 public Worker newWorker() throws Exception { 194 Worker w = (Worker)workerClass.newInstance(); 195 w.init(this, context, name); 196 allWorkers.put(w.getId(), w); 197 new Thread (threads, w).start(); 198 return w; 199 } 200 201 public void stop() { 202 Iterator iter = allWorkers.keys(); 203 while (iter.hasNext()) { 204 int id = ((Integer )iter.next()).intValue(); 205 Worker w = (Worker)allWorkers.get(id); 206 w.stop(); 207 } 208 try { Thread.sleep(shutdownInterval); } catch (Throwable t) {} 209 210 if (threads.activeCount() > 0) { 211 Thread [] ts = new Thread [threads.activeCount()]; 212 int cnt = threads.enumerate(ts); 213 for (int i = 0; i < cnt; i++) { 214 Thread t = ts[i]; 215 if (!t.isInterrupted()) { 216 t.interrupt(); 217 } 218 } 219 try { Thread.sleep(shutdownInterval); } catch (Throwable t) {} 220 cnt = threads.enumerate(ts); 221 for (int i = 0; i < cnt; i++) { 222 Thread t = ts[i]; 223 try { 224 t.join(shutdownInterval/10); 225 } catch (Throwable th) { 226 } finally { 227 try { 228 t.stop(); 229 } catch (Throwable th2) { 230 } 231 } 232 } 233 } 234 } 235 } 236 | Popular Tags |