1 package org.objectweb.perseus.concurrency.distributed; 2 3 26 27 import org.objectweb.perseus.concurrency.api.ConcurrencyException; 28 import org.objectweb.perseus.concurrency.distributed.globallock.api.GlobalLock; 29 import org.objectweb.perseus.concurrency.distributed.globallock.api.GlobalLockManager; 30 import org.objectweb.perseus.concurrency.distributed.globallock.api.GlobalLockException; 31 import org.objectweb.perseus.concurrency.distributed.globallock.api.DeadLockException; 32 import org.objectweb.perseus.concurrency.distributed.globallock.api.GlobalLockWaiter; 33 import org.objectweb.perseus.concurrency.lib.RWLockValue; 34 import org.objectweb.perseus.concurrency.pessimistic.Lock; 35 import org.objectweb.perseus.concurrency.pessimistic.PessimisticConcurrencyManager; 36 import org.objectweb.util.monolog.api.BasicLevel; 37 import org.objectweb.fractal.api.control.IllegalBindingException; 38 import org.objectweb.fractal.api.control.AttributeController; 39 import org.objectweb.fractal.api.NoSuchInterfaceException; 40 import java.io.Serializable ; 41 import java.util.Iterator ; 42 import java.util.Map ; 43 44 public abstract class DistributedConcurrencyManager 45 extends PessimisticConcurrencyManager implements AttributeController { 46 47 public final static String GLOBAL_LOCK_MANAGER_BINDING = "global-lock-manager"; 48 49 50 private long timeout = 0; 51 private GlobalLockManager gLockMgr; 52 53 public void setTimeOut(long timeout) { 54 this.timeout = timeout; 55 } 56 57 58 public DistributedConcurrencyManager() throws ConcurrencyException { 59 super(); 60 } 61 62 public String [] listFc() { 64 String [] super_res = super.listFc(); 65 String [] res = new String [super_res.length + 1]; 66 int cpt; 67 for (cpt = 0; cpt < super_res.length; cpt++) { 68 res[cpt] = super_res[cpt]; 69 } 70 res[cpt] = GLOBAL_LOCK_MANAGER_BINDING; 71 return res; 72 } 73 74 public Object lookupFc(String s) throws NoSuchInterfaceException { 75 if (GLOBAL_LOCK_MANAGER_BINDING.equals(s)) { 76 return gLockMgr; 77 } 78 return super.lookupFc(s); 79 } 80 81 public void bindFc(String s, Object o) throws IllegalBindingException, 82 NoSuchInterfaceException { 83 if (GLOBAL_LOCK_MANAGER_BINDING.equals(s)) { 84 if (gLockMgr != null) { 85 throw new IllegalBindingException(s + ": Already bound"); 86 } 87 try { 88 gLockMgr = (GlobalLockManager) o; 89 } catch (ClassCastException e) { 90 throw new IllegalBindingException(s + ":" + e.getMessage()); 91 } 92 } else super.bindFc(s, o); 93 } 94 95 public void unbindFc(String s) throws NoSuchInterfaceException { 96 if (GLOBAL_LOCK_MANAGER_BINDING.equals(s)) { 97 gLockMgr = null; 98 } else super.unbindFc(s); 99 } 100 101 public void begin(Object ctx) { 103 super.begin(ctx); 104 } 105 106 public void finalize(Object ctx) { 107 freeLocks(ctx); 108 } 109 private void freeLocks(Object ctx) { 110 Object resourceId; 111 synchronized (locks) { 112 Iterator entries = locks.entrySet().iterator(); 113 while (entries.hasNext()) { 114 Map.Entry entry = (Map.Entry ) entries.next(); 115 Lock lock = (Lock) entry.getValue(); 116 resourceId = entry.getKey(); 117 GlobalLock gl = null; 118 try { 119 gl = getDistLock(resourceId, lock.hints, true); 120 } catch (ConcurrencyException e) { 121 logger.log(BasicLevel.ERROR, 122 "Error during the finalize of the context " + ctx 123 + ": oid=" + resourceId, e); 124 } 125 126 if (lock.close(ctx)) { 127 gl.downgrade(RWLockValue.NOLOCK); 128 entries.remove(); 129 } else { 130 gl.downgrade(lock.getMax()); 131 } 132 if (gl.getGrantable() == RWLockValue.NOLOCK) 133 invalidateState(resourceId, lock.hints); 134 } 135 } 136 contextInfos.remove(ctx); 137 } 138 139 public void abort(Object ctx) { 140 freeLocks(ctx); 141 } 142 143 private Object accessIntention(Object ctx, Object resource, 144 Object lockHints, byte lck) 145 throws ConcurrencyException { 146 Object resourceId = getResourceId(resource); 147 try { 148 Lock l = getLock(resourceId, lockHints); 149 GlobalLock gl = getDistLock(resourceId, l.hints, true); 150 GlobalLockWaiter w = gl.upgrade(lck, false, timeout); 151 if (w != null) { 152 if (w.waitLock(timeout) == false) { 153 w.signalHandled(); 154 throw new DeadLockException(); 155 } 156 } 157 if (lck == RWLockValue.READ) l.readIntention(ctx); 158 else l.writeIntention(ctx); 159 if (w != null) w.signalHandled(); 160 return getState(ctx, resourceId, l); 161 } catch (ConcurrencyException e) { 162 getContextInfo(ctx).rollback = true; 163 throw e; 164 } catch (Exception e) { 165 throw new ConcurrencyException(e); 166 } 167 168 } 169 public Object readIntention(Object ctx, Object resourceId, Object hints) 170 throws ConcurrencyException { 171 return accessIntention(ctx, resourceId, hints, RWLockValue.READ); 172 } 173 174 public Object writeIntention(Object ctx, Object resourceId, Object hints) 175 throws ConcurrencyException { 176 return accessIntention(ctx, resourceId, hints, RWLockValue.WRITE); 177 } 178 179 180 public void uncacheGlobal(Object oid) { 182 try { 183 GlobalLock gl = gLockMgr.getGlobalLock((Serializable ) oid , false); 184 if (gl != null) 185 gl.uncache(); 186 } catch (GlobalLockException e) { 187 } 188 } 189 190 public boolean isDistGrantable(Object resId, byte lck, Object hints) 191 throws ConcurrencyException { 192 GlobalLock distLock = getDistLock(resId, hints, false); 193 return (distLock.getGrantable() >= lck); 194 } 195 196 public long getTimeout() { 198 return timeout; 199 } 200 201 public void setTimeout(long timeout) { 202 this.timeout = timeout; 203 } 204 205 protected GlobalLock getDistLock(Object resourceId, Object hints, 207 boolean doInvalidate) 208 throws ConcurrencyException { 209 210 GlobalLock gl; 211 try { 212 gl = gLockMgr.getGlobalLock((Serializable ) resourceId, true); 213 } catch (GlobalLockException e) { 214 throw new ConcurrencyException(e); 215 } 216 if (doInvalidate && (gl.getGrantable() == RWLockValue.NOLOCK)) { 217 invalidateState(resourceId, hints); 218 } 219 return gl; 220 } 221 222 227 protected abstract void invalidateState(Object resourceId, Object hints); 228 229 } 230 | Popular Tags |