1 7 package winstone; 8 9 import java.io.IOException ; 10 import java.net.Socket ; 11 import java.util.ArrayList ; 12 import java.util.Collection ; 13 import java.util.Iterator ; 14 import java.util.List ; 15 import java.util.Map ; 16 17 24 public class ObjectPool implements Runnable { 25 private static final long FLUSH_PERIOD = 60000L; 26 27 private int STARTUP_REQUEST_HANDLERS_IN_POOL = 5; 28 private int MAX_IDLE_REQUEST_HANDLERS_IN_POOL = 50; 29 private int MAX_REQUEST_HANDLERS_IN_POOL = 1000; 30 private long RETRY_PERIOD = 1000; 31 private int START_REQUESTS_IN_POOL = 10; 32 private int MAX_REQUESTS_IN_POOL = 1000; 33 private int START_RESPONSES_IN_POOL = 10; 34 private int MAX_RESPONSES_IN_POOL = 1000; 35 private List unusedRequestHandlerThreads; 36 private List usedRequestHandlerThreads; 37 private List usedRequestPool; 38 private List unusedRequestPool; 39 private List usedResponsePool; 40 private List unusedResponsePool; 41 private Object requestHandlerSemaphore = new Boolean (true); 42 private Object requestPoolSemaphore = new Boolean (true); 43 private Object responsePoolSemaphore = new Boolean (true); 44 private int threadIndex = 0; 45 private boolean simulateModUniqueId; 46 private boolean saveSessions; 47 48 private Thread thread; 49 50 54 public ObjectPool(Map args) throws IOException { 55 this.simulateModUniqueId = WebAppConfiguration.booleanArg(args, "simulateModUniqueId", false); 56 this.saveSessions = WebAppConfiguration.useSavedSessions(args); 57 58 this.unusedRequestHandlerThreads = new ArrayList (); 60 this.usedRequestHandlerThreads = new ArrayList (); 61 62 this.usedRequestPool = new ArrayList (); 64 this.usedResponsePool = new ArrayList (); 65 this.unusedRequestPool = new ArrayList (); 66 this.unusedResponsePool = new ArrayList (); 67 68 if (args.get("handlerCountStartup") != null) { 70 STARTUP_REQUEST_HANDLERS_IN_POOL = Integer.parseInt((String ) args 71 .get("handlerCountStartup")); 72 } 73 if (args.get("handlerCountMax") != null) { 74 MAX_IDLE_REQUEST_HANDLERS_IN_POOL = Integer.parseInt((String ) args 75 .get("handlerCountMax")); 76 } 77 if (args.get("handlerCountMaxIdle") != null) { 78 MAX_IDLE_REQUEST_HANDLERS_IN_POOL = Integer.parseInt((String ) args 79 .get("handlerCountMaxIdle")); 80 } 81 82 for (int n = 0; n < STARTUP_REQUEST_HANDLERS_IN_POOL; n++) { 84 this.unusedRequestHandlerThreads 85 .add(new RequestHandlerThread(this, 86 this.threadIndex++, this.simulateModUniqueId, 87 this.saveSessions)); 88 } 89 90 for (int n = 0; n < START_REQUESTS_IN_POOL; n++) { 92 this.unusedRequestPool.add(new WinstoneRequest()); 93 } 94 for (int n = 0; n < START_RESPONSES_IN_POOL; n++) { 95 this.unusedResponsePool.add(new WinstoneResponse()); 96 } 97 98 this.thread = new Thread (this, "WinstoneObjectPoolMgmt"); 99 this.thread.setDaemon(true); 100 this.thread.start(); 101 } 102 103 public void run() { 104 boolean interrupted = false; 105 while (!interrupted) { 106 try { 107 Thread.sleep(FLUSH_PERIOD); 108 removeUnusedRequestHandlers(); 109 } catch (InterruptedException err) { 110 interrupted = true; 111 } 112 } 113 this.thread = null; 114 } 115 116 private void removeUnusedRequestHandlers() { 117 synchronized (this.requestHandlerSemaphore) { 119 while (this.unusedRequestHandlerThreads.size() > MAX_IDLE_REQUEST_HANDLERS_IN_POOL) { 121 RequestHandlerThread rh = (RequestHandlerThread) this.unusedRequestHandlerThreads.get(0); 122 rh.destroy(); 123 this.unusedRequestHandlerThreads.remove(rh); 124 } 125 } 126 } 127 128 public void destroy() { 129 synchronized (this.requestHandlerSemaphore) { 130 Collection usedHandlers = new ArrayList (this.usedRequestHandlerThreads); 131 for (Iterator i = usedHandlers.iterator(); i.hasNext();) 132 releaseRequestHandler((RequestHandlerThread) i.next()); 133 Collection unusedHandlers = new ArrayList (this.unusedRequestHandlerThreads); 134 for (Iterator i = unusedHandlers.iterator(); i.hasNext();) 135 ((RequestHandlerThread) i.next()).destroy(); 136 this.unusedRequestHandlerThreads.clear(); 137 } 138 if (this.thread != null) { 139 this.thread.interrupt(); 140 } 141 } 142 143 148 public void handleRequest(Socket socket, Listener listener) 149 throws IOException , InterruptedException { 150 RequestHandlerThread rh = null; 151 synchronized (this.requestHandlerSemaphore) { 152 if (this.unusedRequestHandlerThreads.size() > 0) { 154 rh = (RequestHandlerThread) this.unusedRequestHandlerThreads.get(0); 155 this.unusedRequestHandlerThreads.remove(rh); 156 this.usedRequestHandlerThreads.add(rh); 157 Logger.log(Logger.FULL_DEBUG, Launcher.RESOURCES, 158 "ObjectPool.UsingRHPoolThread", new String [] { 159 "" + this.usedRequestHandlerThreads.size(), 160 "" + this.unusedRequestHandlerThreads.size() }); 161 } 162 163 else if (this.usedRequestHandlerThreads.size() < MAX_REQUEST_HANDLERS_IN_POOL) { 165 rh = new RequestHandlerThread(this, 166 this.threadIndex++, this.simulateModUniqueId, 167 this.saveSessions); 168 this.usedRequestHandlerThreads.add(rh); 169 Logger.log(Logger.FULL_DEBUG, Launcher.RESOURCES, 170 "ObjectPool.NewRHPoolThread", new String [] { 171 "" + this.usedRequestHandlerThreads.size(), 172 "" + this.unusedRequestHandlerThreads.size() }); 173 } 174 175 else { 177 Logger.log(Logger.WARNING, Launcher.RESOURCES, 180 "ObjectPool.NoRHPoolThreadsRetry"); 181 } 184 } 185 186 if (rh != null) 187 rh.commenceRequestHandling(socket, listener); 188 else { 189 Thread.sleep(RETRY_PERIOD); 191 192 synchronized (this.requestHandlerSemaphore) { 193 if (this.usedRequestHandlerThreads.size() < MAX_REQUEST_HANDLERS_IN_POOL) { 194 rh = new RequestHandlerThread(this, 195 this.threadIndex++, this.simulateModUniqueId, 196 this.saveSessions); 197 this.usedRequestHandlerThreads.add(rh); 198 Logger.log(Logger.FULL_DEBUG, Launcher.RESOURCES, 199 "ObjectPool.NewRHPoolThread", new String [] { 200 "" + this.usedRequestHandlerThreads.size(), 201 "" + this.unusedRequestHandlerThreads.size() }); 202 } 203 } 204 if (rh != null) 205 rh.commenceRequestHandling(socket, listener); 206 else { 207 Logger.log(Logger.WARNING, Launcher.RESOURCES, 208 "ObjectPool.NoRHPoolThreads"); 209 socket.close(); 210 } 211 } 212 } 213 214 217 public void releaseRequestHandler(RequestHandlerThread rh) { 218 synchronized (this.requestHandlerSemaphore) { 219 this.usedRequestHandlerThreads.remove(rh); 220 this.unusedRequestHandlerThreads.add(rh); 221 Logger.log(Logger.FULL_DEBUG, Launcher.RESOURCES, 222 "ObjectPool.ReleasingRHPoolThread", new String [] { 223 "" + this.usedRequestHandlerThreads.size(), 224 "" + this.unusedRequestHandlerThreads.size() }); 225 } 226 } 227 228 231 public WinstoneRequest getRequestFromPool() throws IOException { 232 WinstoneRequest req = null; 233 synchronized (this.requestPoolSemaphore) { 234 if (this.unusedRequestPool.size() > 0) { 236 req = (WinstoneRequest) this.unusedRequestPool.get(0); 237 this.unusedRequestPool.remove(req); 238 this.usedRequestPool.add(req); 239 Logger.log(Logger.FULL_DEBUG, Launcher.RESOURCES, 240 "ObjectPool.UsingRequestFromPool", "" 241 + this.unusedRequestPool.size()); 242 } 243 else if (this.usedRequestPool.size() < MAX_REQUESTS_IN_POOL) { 245 req = new WinstoneRequest(); 246 this.usedRequestPool.add(req); 247 Logger.log(Logger.FULL_DEBUG, Launcher.RESOURCES, 248 "ObjectPool.NewRequestForPool", "" 249 + this.usedRequestPool.size()); 250 } else 251 throw new WinstoneException(Launcher.RESOURCES 252 .getString("ObjectPool.PoolRequestLimitExceeded")); 253 } 254 return req; 255 } 256 257 public void releaseRequestToPool(WinstoneRequest req) { 258 req.cleanUp(); 259 synchronized (this.requestPoolSemaphore) { 260 this.usedRequestPool.remove(req); 261 this.unusedRequestPool.add(req); 262 Logger.log(Logger.FULL_DEBUG, Launcher.RESOURCES, 263 "ObjectPool.RequestReleased", "" 264 + this.unusedRequestPool.size()); 265 } 266 } 267 268 271 public WinstoneResponse getResponseFromPool() throws IOException { 272 WinstoneResponse rsp = null; 273 synchronized (this.responsePoolSemaphore) { 274 if (this.unusedResponsePool.size() > 0) { 276 rsp = (WinstoneResponse) this.unusedResponsePool.get(0); 277 this.unusedResponsePool.remove(rsp); 278 this.usedResponsePool.add(rsp); 279 Logger.log(Logger.FULL_DEBUG, Launcher.RESOURCES, 280 "ObjectPool.UsingResponseFromPool", "" 281 + this.unusedResponsePool.size()); 282 } 283 else if (this.usedResponsePool.size() < MAX_RESPONSES_IN_POOL) { 285 rsp = new WinstoneResponse(); 286 this.usedResponsePool.add(rsp); 287 Logger.log(Logger.FULL_DEBUG, Launcher.RESOURCES, 288 "ObjectPool.NewResponseForPool", "" 289 + this.usedResponsePool.size()); 290 } else 291 throw new WinstoneException(Launcher.RESOURCES 292 .getString("ObjectPool.PoolResponseLimitExceeded")); 293 } 294 return rsp; 295 } 296 297 public void releaseResponseToPool(WinstoneResponse rsp) { 298 rsp.cleanUp(); 299 synchronized (this.responsePoolSemaphore) { 300 this.usedResponsePool.remove(rsp); 301 this.unusedResponsePool.add(rsp); 302 Logger.log(Logger.FULL_DEBUG, Launcher.RESOURCES, 303 "ObjectPool.ResponseReleased", "" 304 + this.unusedResponsePool.size()); 305 } 306 } 307 308 } 309 | Popular Tags |