1 19 package org.apache.avalon.excalibur.pool; 20 21 import java.util.HashMap ; 22 import java.util.Iterator ; 23 import java.util.Map ; 24 25 34 public class TraceableResourceLimitingPool 35 extends InstrumentedResourceLimitingPool 36 { 37 40 41 private boolean m_tracing; 42 43 44 private Map m_elementMap; 45 46 49 66 public TraceableResourceLimitingPool( final ObjectFactory factory, 67 int max, 68 boolean maxStrict, 69 boolean blocking, 70 long blockTimeout, 71 long trimInterval, 72 boolean trace ) 73 { 74 75 super( factory, max, maxStrict, blocking, blockTimeout, trimInterval ); 76 77 m_tracing = trace; 78 if ( m_tracing ) 79 { 80 m_elementMap = new HashMap (); 81 } 82 } 83 84 87 97 public Poolable get() throws Exception 98 { 99 if ( m_tracing ) 100 { 101 synchronized ( m_semaphore ) 102 { 103 Poolable poolable = (Poolable)super.get(); 104 105 PoolElement element = (PoolElement)m_elementMap.get( poolable ); 106 if ( element == null ) 107 { 108 element = new PoolElement( poolable ); 109 m_elementMap.put( poolable, element ); 110 } 111 element.trace(); 112 113 return poolable; 114 } 115 } 116 else 117 { 118 return super.get(); 119 } 120 } 121 122 127 public void put( Poolable poolable ) 128 { 129 if ( m_tracing ) 130 { 131 synchronized ( m_semaphore ) 132 { 133 PoolElement element = (PoolElement)m_elementMap.get( poolable ); 134 if ( element == null ) 135 { 136 getLogger().error( "PoolElement not found in put for poolable: " + poolable ); 137 } 138 else 139 { 140 element.clear(); 141 } 142 143 super.put( poolable ); 144 } 145 } 146 else 147 { 148 super.put( poolable ); 149 } 150 } 151 152 161 protected void removePoolable( Poolable poolable ) 162 { 163 if ( m_tracing ) 164 { 165 PoolElement element = (PoolElement)m_elementMap.remove( poolable ); 166 if ( element == null ) 167 { 168 getLogger().error( 169 "PoolElement not found in removePoolable for poolable: " + poolable ); 170 } 171 } 172 173 super.removePoolable( poolable ); 174 } 175 176 179 184 public State getState() 185 { 186 if ( m_tracing ) 187 { 188 synchronized ( m_semaphore ) 189 { 190 int count = 0; 192 for ( Iterator iter = m_elementMap.values().iterator(); iter.hasNext(); ) 193 { 194 PoolElement element = (PoolElement)iter.next(); 195 if ( element.m_thread != null ) 196 { 197 count++; 198 } 199 } 200 201 Thread [] threads = new Thread [count]; 203 TraceException[] traceExceptions = new TraceException[count]; 204 long[] traceTimes = new long[count]; 205 if ( count > 0 ) 206 { 207 int i = 0; 208 for ( Iterator iter = m_elementMap.values().iterator(); iter.hasNext(); ) 209 { 210 PoolElement element = (PoolElement)iter.next(); 211 if ( element.m_thread != null ) 212 { 213 threads[i] = element.m_thread; 214 traceExceptions[i] = element.m_traceException; 215 traceTimes[i] = element.m_time; 216 i++; 217 } 218 } 219 } 220 221 return new State( getSize(), getReadySize(), threads, traceExceptions, traceTimes ); 222 } 223 } 224 else 225 { 226 throw new IllegalStateException ( "Trace is disabled for this pool." ); 227 } 228 } 229 230 233 public static class State 234 { 235 private int m_size; 236 private int m_readySize; 237 private Thread [] m_threads; 238 private TraceException[] m_traceExceptions; 239 private long[] m_traceTimes; 240 241 private State( int size, int readySize, 242 Thread [] threads, 243 TraceException[] traceExceptions, 244 long[] traceTimes ) 245 { 246 m_size = size; 247 m_readySize = readySize; 248 m_threads = threads; 249 m_traceExceptions = traceExceptions; 250 m_traceTimes = traceTimes; 251 } 252 253 public int getSize() 254 { 255 return m_size; 256 } 257 258 public int getReadySize() 259 { 260 return m_readySize; 261 } 262 263 public Thread [] getTraceThreads() 264 { 265 return m_threads; 266 } 267 268 public TraceException[] getTraceExceptions() 269 { 270 return m_traceExceptions; 271 } 272 273 public long[] getTraceTimes() 274 { 275 return m_traceTimes; 276 } 277 } 278 279 private static class PoolElement 280 { 281 private Poolable m_poolable; 282 private Thread m_thread; 283 private TraceException m_traceException; 284 private long m_time; 285 286 private PoolElement( Poolable poolable ) 287 { 288 m_poolable = poolable; 289 } 290 291 private void trace() 292 { 293 m_thread = Thread.currentThread(); 294 m_traceException = new TraceException(); 295 m_traceException.fillInStackTrace(); 296 m_time = System.currentTimeMillis(); 297 } 298 299 private void clear() 300 { 301 m_thread = null; 302 m_traceException = null; 303 } 304 } 305 306 public static class TraceException extends RuntimeException 307 { 308 private TraceException() 309 { 310 } 311 } 312 } 313 314 | Popular Tags |