1 22 package org.jboss.ejb.plugins.lock; 23 24 import org.jboss.util.deadlock.ApplicationDeadlockException; 25 import org.jboss.util.deadlock.Resource; 26 import org.jboss.util.deadlock.DeadlockDetector; 27 28 import javax.transaction.Transaction ; 29 30 40 public class NonReentrantLock implements Resource 41 { 42 public static class ReentranceException extends Exception 43 { 44 public ReentranceException() 45 { 46 } 47 48 public ReentranceException(String message) 49 { 50 super(message); 51 } 52 } 53 54 56 protected Thread lockHolder; 57 protected Object lock = new Object (); 58 protected volatile int held = 0; 59 protected Transaction holdingTx = null; 60 private boolean inNonReentrant; 61 62 public Object getResourceHolder() 63 { 64 if(holdingTx != null) return holdingTx; 65 return lockHolder; 66 } 67 68 protected boolean acquireNonReentrant(long waitTime, Transaction miTx) 69 throws ApplicationDeadlockException, InterruptedException , ReentranceException 70 { 71 synchronized(lock) 72 { 73 final Thread curThread = Thread.currentThread(); 74 if(lockHolder != null) 75 { 76 if(lockHolder == curThread) 77 { 78 if(inNonReentrant) 79 { 80 throw new ReentranceException("The same thread reentered: thread-holder=" + 81 lockHolder + 82 ", holding tx=" + 83 holdingTx + 84 ", current tx=" + miTx); 85 } 86 } 87 else if(miTx != null && miTx.equals(holdingTx)) 88 { 89 if(inNonReentrant) 90 { 91 throw new ReentranceException("The same tx reentered: tx=" + 92 miTx + 93 ", holding thread=" + 94 lockHolder + 95 ", current thread=" + curThread); 96 } 97 } 98 else 99 { 100 Object deadlocker = curThread; 102 if(miTx != null) deadlocker = miTx; 103 try 104 { 105 DeadlockDetector.singleton.deadlockDetection(deadlocker, this); 106 while(lockHolder != null) 107 { 108 if(waitTime < 1) 109 { 110 lock.wait(); 111 } 112 else 113 { 114 lock.wait(waitTime); 115 } 116 if(waitTime > 0 && lockHolder != null) return false; 118 } 119 } 120 finally 121 { 122 DeadlockDetector.singleton.removeWaiting(deadlocker); 123 } 124 } 125 } 126 127 ++held; 128 lockHolder = curThread; 129 holdingTx = miTx; 130 inNonReentrant = true; 131 } 132 return true; 133 } 134 135 protected boolean acquireReentrant(long waitTime, Transaction miTx) 136 throws ApplicationDeadlockException, InterruptedException , ReentranceException 137 { 138 synchronized(lock) 139 { 140 final Thread curThread = Thread.currentThread(); 141 if(lockHolder != null) 142 { 143 if(lockHolder != curThread && (miTx == null || miTx.equals(holdingTx))) 144 { 145 Object deadlocker = curThread; 147 if(miTx != null) deadlocker = miTx; 148 try 149 { 150 DeadlockDetector.singleton.deadlockDetection(deadlocker, this); 151 while(lockHolder != null) 152 { 153 if(waitTime < 1) 154 { 155 lock.wait(); 156 } 157 else 158 { 159 lock.wait(waitTime); 160 } 161 if(waitTime > 0 && lockHolder != null) return false; 163 } 164 } 165 finally 166 { 167 DeadlockDetector.singleton.removeWaiting(deadlocker); 168 } 169 } 170 } 171 172 ++held; 173 lockHolder = curThread; 174 holdingTx = miTx; 175 } 176 return true; 177 } 178 179 public boolean attempt(long waitTime, Transaction miTx, boolean nonReentrant) 180 throws ApplicationDeadlockException, InterruptedException , ReentranceException 181 { 182 return nonReentrant ? acquireNonReentrant(waitTime, miTx) : acquireReentrant(waitTime, miTx); 183 } 184 185 public void release(boolean nonReentrant) 186 { 187 synchronized(lock) 188 { 189 held--; 190 if(held < 0) 191 { 192 throw new IllegalStateException ("Released lock too many times"); 193 } 194 else if(held == 0) 195 { 196 lockHolder = null; 197 holdingTx = null; 198 lock.notify(); 199 } 200 201 if(nonReentrant) 202 { 203 inNonReentrant = false; 204 } 205 } 206 } 207 } 208 | Popular Tags |