1 2 3 package org.enhydra.shark.processlocking; 4 5 import java.util.*; 6 7 import org.enhydra.shark.api.RootException; 8 import org.enhydra.shark.api.SharkTransaction; 9 import org.enhydra.shark.api.internal.processlocking.LockMaster; 10 import org.enhydra.shark.api.internal.working.CallbackUtilities; 11 12 13 20 public class SimpleLockMaster implements LockMaster { 21 22 private static final String ENG_PARAM_NAME = "enginename"; 23 private static final String TOUT_PARM_NAME = "SimpleLockMaster.Timeout"; 24 private static final String LWT_PARAM_NAME = "SimpleLockMaster.LockWaitTime"; 25 26 private Long defaultTimeout; 27 private Map locks; 28 private long lockWaitTime; 29 private CallbackUtilities callback; 30 31 34 public SimpleLockMaster() { 35 locks = new HashMap(); 36 defaultTimeout = null; 37 } 38 39 47 public void configure(CallbackUtilities cbImpl) throws RootException { 48 if (null == cbImpl) 49 throw new RootException("Cannot configure without call back impl."); 50 callback = cbImpl; 51 String lockMasterName = callback.getProperty(ENG_PARAM_NAME,"simpleLockMaster"); 52 defaultTimeout = new Long (callback.getProperty(TOUT_PARM_NAME, "-1")); 53 lockWaitTime = Long.parseLong(callback.getProperty(LWT_PARAM_NAME,"100")); 54 callback.debug(new StringBuffer (lockMasterName) 55 .append(" startup, timeout is ") 56 .append(defaultTimeout) 57 .toString()); 58 } 59 60 74 public boolean lock(SharkTransaction t, 75 String processId, 76 Long timeout) throws RootException { 77 boolean ret = true; 78 if (null != processId) { 79 if (null == timeout) 80 timeout = defaultTimeout; 81 long limit = timeout.longValue(); 82 boolean checkTimeout = 0 < limit; 83 limit += System.currentTimeMillis(); 84 85 while (hasLock(processId)) { 86 ret = false; 87 try { 88 Thread.sleep(lockWaitTime); 89 } catch (Exception e) {} 90 if (checkTimeout && (System.currentTimeMillis() > limit)) { 91 RootException tme = new RootException 92 (new StringBuffer ("Timeout expired waiting on ") 93 .append(processId) 94 .toString()); 95 callback.error("SimpleLockMaster", tme); 96 throw tme; 97 } 98 } 99 } 100 return ret; 101 } 102 103 111 public boolean lock(SharkTransaction t, 112 String processId) throws RootException { 113 return lock(t, processId, null); 114 } 115 116 120 public void unlock(SharkTransaction t, 121 String processId) throws RootException { 122 if (null != processId) { 123 removeLock(processId); 124 } 125 } 126 127 133 public synchronized void unlock(SharkTransaction t) throws RootException { 134 List processLocks = retrieveLocks(); 135 if (null == processLocks) { 136 throw new RootException("Transaction hasn't locked anything"); 137 } 138 for (Iterator it = processLocks.iterator(); it.hasNext();) { 139 locks.remove(it.next()); 140 } 141 } 142 143 150 public List getLocks(SharkTransaction t) throws RootException { 151 List transactionLocks = retrieveLocks(); 152 if (null == transactionLocks) 153 throw new RootException("Transaction hasn't locked anything"); 154 return transactionLocks; 155 } 156 157 158 private synchronized List retrieveLocks() { 159 List ret = new ArrayList(); 160 Set entries = locks.entrySet(); 161 Thread th = Thread.currentThread(); 162 for (Iterator it = entries.iterator(); it.hasNext();) { 163 Map.Entry me = (Map.Entry)it.next(); 164 if (th.equals(me.getValue())) { 165 ret.add(me.getKey()); 166 } 167 } 168 return ret; 169 } 170 171 172 private synchronized boolean hasLock(String processId) { 173 Thread lockOwner = (Thread )locks.get(processId); 174 if (null == lockOwner) { 175 locks.put(processId, Thread.currentThread()); 176 return false; 177 } else if (lockOwner.equals(Thread.currentThread())) { 178 return false; 179 } else { 180 return true; 181 } 182 } 183 184 185 private synchronized void removeLock(String processId) throws RootException { 186 Thread lockOwner = (Thread )locks.get(processId); 187 if (Thread.currentThread().equals(lockOwner)) { 188 locks.remove(processId); 189 } else { 190 RootException tme = new RootException 191 (new StringBuffer ("Trying to unlock ") 192 .append(processId) 193 .append(" while it hasn't been locked ?!?") 194 .toString()); 195 callback.error("SimpleLockMaster", tme); 196 throw tme; 197 } 198 } 199 synchronized void info() { 200 System.err.print(locks.size()+" locks "); 201 } 202 } 203 204 | Popular Tags |