/* */ package org.jboss.jms.client;
/* */
/* */ import EDU.oswego.cs.dl.util.concurrent.ConcurrentHashMap;
/* */ import EDU.oswego.cs.dl.util.concurrent.ReadWriteLock;
/* */ import EDU.oswego.cs.dl.util.concurrent.ReentrantWriterPreferenceReadWriteLock;
/* */ import EDU.oswego.cs.dl.util.concurrent.Sync;
/* */ import java.io.PrintWriter;
/* */ import java.io.StringWriter;
/* */ import java.util.Iterator;
/* */ import java.util.Map;
/* */ import java.util.Map.Entry;
/* */ import java.util.Set;
/* */ import java.util.Stack;
/* */ import org.jboss.jms.client.delegate.DelegateSupport;
/* */ import org.jboss.jms.client.state.ConnectionState;
/* */ import org.jboss.logging.Logger;
/* */
/* */ public class FailoverValve
/* */ {
/* 43 */ private static final Logger log = Logger.getLogger(FailoverValve.class);
/* */ public static final long DEFAULT_ATTEMPT_TIMEOUT = 5000L;
/* 49 */ private static boolean trace = log.isTraceEnabled();
/* */
/* 55 */ private ThreadLocal counterLocal = new ThreadLocal();
/* */ private ReadWriteLock lock;
/* 59 */ private int activeCloses = 0;
/* */ private ThreadLocal stackCloses;
/* */ private ThreadLocal stackEnters;
/* */ private Map debugCloses;
/* */ private Map debugEnters;
/* */ private FailoverCommandCenter fcc;
/* */ private long writeLockAttemptTimeout;
/* */
/* */ public FailoverValve()
/* */ {
/* 76 */ this(null, 5000L);
/* */ }
/* */
/* */ public FailoverValve(long attemptTiemout)
/* */ {
/* 81 */ this(null, attemptTiemout);
/* */ }
/* */
/* */ public FailoverValve(FailoverCommandCenter fcc)
/* */ {
/* 86 */ this(fcc, 5000L);
/* */ }
/* */
/* */ public FailoverValve(FailoverCommandCenter fcc, long attemptTiemout)
/* */ {
/* 94 */ this.fcc = fcc;
/* */
/* 100 */ this.lock = new ReentrantWriterPreferenceReadWriteLock();
/* */
/* 102 */ this.writeLockAttemptTimeout = attemptTiemout;
/* */
/* 104 */ if (trace)
/* */ {
/* 106 */ this.stackCloses = new ThreadLocal();
/* 107 */ this.stackEnters = new ThreadLocal();
/* 108 */ this.debugCloses = new ConcurrentHashMap();
/* 109 */ this.debugEnters = new ConcurrentHashMap();
/* */ }
/* */ }
/* */
/* */ public void enter()
/* */ throws InterruptedException
/* */ {
/* 117 */ this.lock.readLock().acquire();
/* */
/* 119 */ getCounter().counter += 1;
/* */
/* 121 */ if (trace)
/* */ {
/* 123 */ Exception ex = new Exception();
/* 124 */ getStackEnters().push(ex);
/* 125 */ this.debugEnters.put(ex, Thread.currentThread());
/* */ }
/* */ }
/* */
/* */ public void leave() throws InterruptedException
/* */ {
/* 131 */ this.lock.readLock().release();
/* */
/* 134 */ if (getCounter().counter-- < 0)
/* */ {
/* 136 */ throw new IllegalStateException("leave() was called without a prior enter() call");
/* */ }
/* */
/* 139 */ if (trace)
/* */ {
/* 141 */ Exception ex = (Exception)getStackEnters().pop();
/* 142 */ this.debugEnters.remove(ex);
/* */ }
/* */ }
/* */
/* */ public void close() throws InterruptedException
/* */ {
/* 148 */ log.debug(this + " close ...");
/* */
/* 162 */ int counter = getCounter().counter;
/* */
/* 164 */ for (int i = 0; i < counter; i++)
/* */ {
/* 166 */ this.lock.readLock().release();
/* */ }
/* */
/* 169 */ boolean acquired = false;
/* */ do
/* */ {
/* 173 */ acquired = this.lock.writeLock().attempt(this.writeLockAttemptTimeout);
/* */
/* 175 */ if (acquired)
/* */ continue;
/* 177 */ log.debug(this + " could not close, trying again ...", new Exception());
/* 178 */ if (!trace) continue; log.trace(debugValve());
/* */ }
/* */
/* 181 */ while (!acquired);
/* */
/* 183 */ log.debug(this + " closed");
/* */
/* 185 */ this.activeCloses += 1;
/* */
/* 188 */ if (this.activeCloses > 1)
/* */ {
/* 190 */ this.lock.writeLock().release();
/* 191 */ throw new IllegalStateException("Valve closed twice");
/* */ }
/* */
/* 194 */ if (trace)
/* */ {
/* 196 */ Exception ex = new Exception();
/* 197 */ getStackCloses().push(ex);
/* 198 */ this.debugCloses.put(ex, Thread.currentThread());
/* */ }
/* */ }
/* */
/* */ public void open() throws InterruptedException
/* */ {
/* 204 */ if (this.activeCloses <= 0)
/* */ {
/* 206 */ throw new IllegalStateException("Valve not closed");
/* */ }
/* */
/* 209 */ log.debug(this + " opening ...");
/* */
/* 211 */ this.activeCloses -= 1;
/* */
/* 213 */ this.lock.writeLock().release();
/* */
/* 216 */ int counter = getCounter().counter;
/* 217 */ for (int i = 0; i < counter; i++)
/* */ {
/* 219 */ this.lock.readLock().acquire();
/* */ }
/* */
/* 222 */ if (trace)
/* */ {
/* 224 */ Exception ex = (Exception)getStackCloses().pop();
/* 225 */ this.debugCloses.remove(ex);
/* */ }
/* */
/* 228 */ log.debug(this + " opened");
/* */ }
/* */
/* */ public long getWriteLockAttemptTimeout()
/* */ {
/* 233 */ return this.writeLockAttemptTimeout;
/* */ }
/* */
/* */ public String toString()
/* */ {
/* 238 */ return "FailoverValve[" + (this.fcc == null ? "UNINITIALIZED" : new StringBuilder().append("connectionID=").append(this.fcc.getConnectionState().getDelegate().getID()).toString()) + "]";
/* */ }
/* */
/* */ private Counter getCounter()
/* */ {
/* 256 */ Counter localCounter = (Counter)this.counterLocal.get();
/* */
/* 258 */ if (localCounter == null)
/* */ {
/* 260 */ localCounter = new Counter(null);
/* 261 */ this.counterLocal.set(localCounter);
/* */ }
/* */
/* 264 */ return localCounter;
/* */ }
/* */
/* */ private Stack getStackCloses()
/* */ {
/* 270 */ if (this.stackCloses.get() == null)
/* */ {
/* 272 */ this.stackCloses.set(new Stack());
/* */ }
/* */
/* 275 */ return (Stack)this.stackCloses.get();
/* */ }
/* */
/* */ private Stack getStackEnters()
/* */ {
/* 280 */ if (this.stackEnters.get() == null)
/* */ {
/* 282 */ this.stackEnters.set(new Stack());
/* */ }
/* 284 */ return (Stack)this.stackEnters.get();
/* */ }
/* */
/* */ private synchronized String debugValve()
/* */ {
/* 292 */ StringWriter buffer = new StringWriter();
/* 293 */ PrintWriter writer = new PrintWriter(buffer);
/* */
/* 295 */ writer.println("********************** Debug Valve Information *************************");
/* 296 */ writer.println("Close owners");
/* */
/* 301 */ for (Iterator iter = this.debugCloses.entrySet().iterator(); iter.hasNext(); )
/* */ {
/* 303 */ Map.Entry entry = (Map.Entry)iter.next();
/* 304 */ writer.println("Thread that owns a close =" + entry.getValue());
/* 305 */ writer.println("StackTrace:");
/* 306 */ Exception e = (Exception)entry.getKey();
/* 307 */ e.printStackTrace(writer);
/* */ }
/* */
/* 310 */ writer.println("Valve owners");
/* 311 */ for (Iterator iter = this.debugEnters.entrySet().iterator(); iter.hasNext(); )
/* */ {
/* 313 */ Map.Entry entry = (Map.Entry)iter.next();
/* 314 */ writer.println("Thread that owns valve =" + entry.getValue());
/* 315 */ writer.println("StackTrace:");
/* 316 */ Exception e = (Exception)entry.getKey();
/* 317 */ e.printStackTrace(writer);
/* */ }
/* */
/* 320 */ return buffer.toString();
/* */ }
/* */
/* */ private static class Counter
/* */ {
/* */ int counter;
/* */ }
/* */ }
/* Location: /home/mnovotny/projects/EMBEDDED_JBOSS_BETA3_COMMUNITY/embedded/output/lib/embedded-jboss/lib/jboss-embedded-all.jar
* Qualified Name: org.jboss.jms.client.FailoverValve
* JD-Core Version: 0.6.0
*/