1 25 26 package org.objectweb.perseus.concurrency.optimistic; 27 28 import org.objectweb.perseus.concurrency.lib.Semaphore; 29 import org.objectweb.perseus.concurrency.lib.TimeStamp; 30 import org.objectweb.perseus.concurrency.api.ConcurrencyException; 31 import org.objectweb.perseus.concurrency.api.ConcurrencyManager; 32 import org.objectweb.perseus.dependency.api.DependencyGraph; 33 import org.objectweb.fractal.api.control.BindingController; 34 import org.objectweb.util.monolog.api.Logger; 35 36 import java.util.HashMap ; 37 import java.util.Iterator ; 38 import java.util.Map ; 39 40 43 public abstract class OptimisticConcurrencyManager 44 implements ConcurrencyManager, BindingController { 45 46 public final static String DEPENDENCY_GRAPH_BINDING = "dependency-graph"; 47 48 private Semaphore sem; 49 50 protected Logger logger = null; 51 52 private DependencyGraph dg = null; 53 54 57 protected Map timeStamps; 58 59 public OptimisticConcurrencyManager() { 60 super(); 61 sem = new Semaphore(); 62 timeStamps = new HashMap (); 63 } 64 65 78 protected abstract Object getState(Object ctx, 79 Object resourceId, 80 TimeStamp timeStamp, 81 boolean isDirtyBefore, 82 boolean isWrite) throws ConcurrencyException; 83 84 87 public String [] listFc() { 88 return new String [] {DEPENDENCY_GRAPH_BINDING}; 89 } 90 91 public Object lookupFc(String s) { 92 if (DEPENDENCY_GRAPH_BINDING.equals(s)) { 93 return dg; 94 } 95 return null; 96 } 97 98 public void bindFc(String s, Object o) { 99 if ("logger".equals(s)) { 100 logger = (Logger) o; 101 } else if (DEPENDENCY_GRAPH_BINDING.equals(s)) { 102 dg = (DependencyGraph) o; 103 } 104 } 105 106 public void unbindFc(String s) { 107 if (DEPENDENCY_GRAPH_BINDING.equals(s)) { 108 dg = null; 109 } 110 } 111 112 115 public void begin(Object ctx) { 116 } 118 119 public boolean validate(Object ctx) { 120 sem.P(); 123 Iterator tss = timeStamps.values().iterator(); 124 while (tss.hasNext()) { 125 TimeStamp timeStamp = (TimeStamp) tss.next(); 126 if (!timeStamp.validate(ctx)) { 127 return false; 128 } 129 } 130 tss = timeStamps.values().iterator(); 131 while (tss.hasNext()) { 132 TimeStamp timeStamp = (TimeStamp) tss.next(); 133 timeStamp.finalize(ctx); 134 } 135 return true; 136 } 137 138 public void finalize(Object ctx) { 139 freeLocks(ctx); 140 } 141 private void freeLocks(Object ctx) { 142 if (sem.getUser() != Thread.currentThread()) { 143 throw new RuntimeException ("Bad use of the concurrency manager: the validate must be call before the finalize method"); 144 } 145 try { 146 Iterator tsIt = timeStamps.values().iterator(); 147 while (tsIt.hasNext()) { 148 TimeStamp timeStamp = null; 149 timeStamp = (TimeStamp) tsIt.next(); 150 if (timeStamp.close(ctx)) { 151 closeTimeStamp(timeStamp, ctx); 152 tsIt.remove(); 153 } 154 } 155 } finally { 158 sem.V(); 159 } 160 } 161 162 public void closeTimeStamp(TimeStamp timeStamp, Object ctx) { 163 } 164 165 public void abort(Object ctx) { 166 freeLocks(ctx); 167 } 168 169 protected Object getResourceId(Object object) { 170 return object; 171 } 172 173 176 public Object readIntention(Object ctx, Object resource, Object thinLock) 177 throws ConcurrencyException { 178 Object resourceId = getResourceId(resource); 179 sem.P(); 180 TimeStamp timeStamp = getTimeStamp(resourceId, null); 181 boolean isDirtyBefore = timeStamp.isDirty(ctx); 182 timeStamp.P(); 183 timeStamp.readIntention(ctx); 184 sem.V(); 185 try { 186 return getState(ctx, resource, timeStamp, isDirtyBefore, false); 187 } catch(ConcurrencyException e) { 188 removeUnavailableResource(ctx, resourceId, thinLock, timeStamp); 189 throw e; 190 } finally { 191 timeStamp.V(); 192 } 193 } 194 195 198 public Object writeIntention(Object ctx, Object resource, Object thinLock) 199 throws ConcurrencyException { 200 Object resourceId = getResourceId(resource); 201 sem.P(); 202 TimeStamp timeStamp = getTimeStamp(resourceId, thinLock); 203 boolean isDirtyBefore = timeStamp.isDirty(ctx); 204 timeStamp.P(); 205 timeStamp.writeIntention(ctx); 206 sem.V(); 207 try { 208 return getState(ctx, resource, timeStamp, isDirtyBefore, true); 209 } catch(ConcurrencyException e) { 210 removeUnavailableResource(ctx, resourceId, thinLock, timeStamp); 211 throw e; 212 } finally { 213 timeStamp.V(); 214 } 215 } 216 217 private void removeUnavailableResource(Object ctx, 218 Object resourceId, 219 Object thinLock, 220 TimeStamp timeStamp) { 221 if (timeStamp.close(ctx)) { 223 timeStamp.V(); 224 sem.P(); 225 timeStamp.P(); 226 if (timeStamp.close(ctx)) { 227 timeStamps.remove(resourceId); 228 } 229 sem.V(); 230 } 231 } 232 233 236 241 private TimeStamp getTimeStamp(Object oid, Object lockHints) { 242 TimeStamp timeStamp = (TimeStamp) timeStamps.get(oid); 243 if (timeStamp == null) { 244 timeStamp = new TimeStamp(oid); 245 timeStamps.put(oid, timeStamp); 246 } 247 timeStamp.reserve(); 248 return timeStamp; 249 } 250 } 251 | Popular Tags |