1 22 package org.jboss.resource.connectionmanager; 23 24 import java.security.AccessController ; 25 import java.security.PrivilegedAction ; 26 import java.util.ArrayList ; 27 28 import java.util.Collection ; 29 import java.util.Iterator ; 30 import org.jboss.logging.Logger; 31 32 40 public class IdleRemover 41 { 42 private final Logger log = Logger.getLogger(getClass()); 43 44 private final Collection pools = new ArrayList (); 45 46 private long interval = Long.MAX_VALUE; 47 48 private long next = Long.MAX_VALUE; 50 private static final IdleRemover remover = new IdleRemover(); 51 52 public static void registerPool(IdleConnectionRemovalSupport mcp, long interval) 53 { 54 remover.internalRegisterPool(mcp, interval); 55 } 56 57 public static void unregisterPool(IdleConnectionRemovalSupport mcp) 58 { 59 remover.internalUnregisterPool(mcp); 60 } 61 62 65 public static void waitForBackgroundThread() 66 { 67 synchronized (remover.pools) 68 { 69 return; 70 } 71 } 72 73 private IdleRemover () 74 { 75 AccessController.doPrivileged(new PrivilegedAction () 76 { 77 public Object run() 78 { 79 Runnable runnable = new IdleRemoverRunnable(); 80 Thread removerThread = new Thread (runnable, "IdleRemover"); 81 removerThread.setDaemon(true); 82 removerThread.start(); 83 return null; 84 } 85 }); 86 } 87 88 private void internalRegisterPool(IdleConnectionRemovalSupport mcp, long interval) 89 { 90 log.debug("internalRegisterPool: registering pool with interval " + interval + " old interval: " + this.interval); 91 synchronized (pools) 92 { 93 pools.add(mcp); 94 if (interval > 1 && interval/2 < this.interval) 95 { 96 this.interval = interval/2; 97 long maybeNext = System.currentTimeMillis() + this.interval; 98 if (next > maybeNext && maybeNext > 0) 99 { 100 next = maybeNext; 101 log.debug("internalRegisterPool: about to notify thread: old next: " + next + ", new next: " + maybeNext); 102 pools.notify(); 103 } 104 } 105 } 106 } 107 108 private void internalUnregisterPool(IdleConnectionRemovalSupport mcp) 109 { 110 synchronized (pools) 111 { 112 pools.remove(mcp); 113 if (pools.size() == 0) 114 { 115 log.debug("internalUnregisterPool: setting interval to Long.MAX_VALUE"); 116 interval = Long.MAX_VALUE; 117 } 118 } 119 } 120 121 126 private void setupContextClassLoader() 127 { 128 final ClassLoader cl = IdleRemover.class.getClassLoader(); 130 if (cl == null) 131 return; 132 133 SecurityManager sm = System.getSecurityManager(); 134 if (sm == null) 135 Thread.currentThread().setContextClassLoader(cl); 136 137 AccessController.doPrivileged(new PrivilegedAction () 138 { 139 public Object run() 140 { 141 Thread.currentThread().setContextClassLoader(cl); 142 return null; 143 } 144 }); 145 } 146 147 150 private class IdleRemoverRunnable implements Runnable 151 { 152 public void run() 153 { 154 setupContextClassLoader(); 155 156 synchronized (pools) 157 { 158 while (true) 159 { 160 try 161 { 162 pools.wait(interval); 163 log.debug("run: IdleRemover notifying pools, interval: " + interval); 164 for (Iterator i = pools.iterator(); i.hasNext(); ) 165 ((InternalManagedConnectionPool)i.next()).removeIdleConnections(); 166 next = System.currentTimeMillis() + interval; 167 if (next < 0) 168 next = Long.MAX_VALUE; 169 170 } 171 catch (InterruptedException ie) 172 { 173 log.info("run: IdleRemover has been interrupted, returning"); 174 return; 175 } 176 catch (RuntimeException e) 177 { 178 log.warn("run: IdleRemover ignored unexpected runtime exception", e); 179 } 180 catch (Error e) 181 { 182 log.warn("run: IdleRemover ignored unexpected error", e); 183 } 184 } 185 } 186 } 187 } 188 } 189 | Popular Tags |