1 5 6 package com.hp.hpl.jena.rdf.model.impl ; 7 import com.hp.hpl.jena.rdf.model.ModelLock ; 8 import com.hp.hpl.jena.shared.JenaException; 9 10 import EDU.oswego.cs.dl.util.concurrent.WriterPreferenceReadWriteLock; 11 import EDU.oswego.cs.dl.util.concurrent.SynchronizedInt; 12 import java.util.*; 13 import org.apache.commons.logging.*; 14 15 28 29 public class ModelLockImpl implements ModelLock 30 { 31 33 static Log log = LogFactory.getLog(ModelLockImpl.class) ; 34 35 Map threadStates = new HashMap() ; 37 int threadStatesSize = threadStates.size() ; 39 40 WriterPreferenceReadWriteLock lock = new WriterPreferenceReadWriteLock(); 42 43 SynchronizedInt activeReadLocks = new SynchronizedInt(0); 44 SynchronizedInt activeWriteLocks = new SynchronizedInt(0); 45 46 ModelLockImpl() { 47 if ( log.isDebugEnabled() ) 48 log.debug("ModelLockImpl() : "+Thread.currentThread().getName()) ; 49 } 50 51 52 63 64 final public void enterCriticalSection(boolean readLockRequested) 65 { 66 72 ModelLockState state = getLockState() ; 73 74 78 if ( log.isDebugEnabled() ) 79 log.debug(Thread.currentThread().getName()+" >> enterCS: "+report(state)) ; 80 81 if (state.readLocks > 0 && state.writeLocks == 0 && !readLockRequested) 84 { 85 state.readLocks++ ; 88 activeReadLocks.increment() ; 89 90 if ( log.isDebugEnabled() ) 91 log.debug(Thread.currentThread().getName()+" << enterCS: promotion attempt: "+report(state)) ; 92 93 throw new JenaException("enterCriticalSection: Write lock request while holding read lock - potential deadlock"); 94 } 95 96 if ( state.writeLocks > 0 && readLockRequested ) 98 readLockRequested = false ; 99 100 try { 101 if (readLockRequested) 102 { 103 if (state.readLocks == 0) 104 lock.readLock().acquire(); 105 state.readLocks ++ ; 106 activeReadLocks.increment() ; 107 } 108 else 109 { 110 if (state.writeLocks == 0) 111 lock.writeLock().acquire(); 112 state.writeLocks ++ ; 113 activeWriteLocks.increment() ; 114 } 115 } 116 catch (InterruptedException intEx) 117 { 118 } 119 finally 120 { 121 if ( log.isDebugEnabled() ) 122 log.debug(Thread.currentThread().getName()+" << enterCS: "+report(state)) ; 123 } 124 } 125 126 130 131 final public void leaveCriticalSection() 132 { 133 134 ModelLockState state = getLockState() ; 135 136 if ( log.isDebugEnabled() ) 137 log.debug(Thread.currentThread().getName()+" >> leaveCS: "+report(state)) ; 138 139 try { 140 if ( state.readLocks > 0) 141 { 142 state.readLocks -- ; 143 activeReadLocks.decrement() ; 144 145 if ( state.readLocks == 0 ) 146 lock.readLock().release() ; 147 148 state.clean() ; 149 return ; 150 } 151 152 if ( state.writeLocks > 0) 153 { 154 state.writeLocks -- ; 155 activeWriteLocks.decrement() ; 156 157 if ( state.writeLocks == 0 ) 158 lock.writeLock().release() ; 159 160 state.clean() ; 161 return ; 162 } 163 164 166 throw new JenaException("leaveCriticalSection: No lock held ("+Thread.currentThread().getName()+")") ; 167 } finally 168 { 169 if ( log.isDebugEnabled() ) 170 log.debug(Thread.currentThread().getName()+" << leaveCS: "+report(state)) ; 171 } 172 } 173 174 private String report(ModelLockState state) 175 { 176 StringBuffer sb = new StringBuffer () ; 177 sb.append("Thread R/W: ") ; 178 sb.append(Integer.toString(state.readLocks)) ; 179 sb.append("/") ; 180 sb.append(Integer.toString(state.writeLocks)) ; 181 sb.append(" :: Model R/W: ") ; 182 sb.append(Integer.toString(activeReadLocks.get())) ; 183 sb.append("/") ; 184 sb.append(Integer.toString(activeWriteLocks.get())) ; 185 sb.append(" (thread: ") ; 186 sb.append(state.thread.getName()) ; 187 sb.append(")") ; 188 return sb.toString() ; 189 } 190 191 193 synchronized ModelLockState getLockState() 194 { 195 Thread thisThread = Thread.currentThread() ; 196 ModelLockState state = (ModelLockState)threadStates.get(thisThread) ; 197 if ( state == null ) 198 { 199 state = new ModelLockState(this) ; 200 threadStates.put(thisThread, state) ; 201 threadStatesSize = threadStates.size() ; 202 } 203 return state ; 204 } 205 206 synchronized void removeLockState(Thread thread) 207 { 208 threadStates.remove(thread) ; 209 } 210 211 static class ModelLockState 212 { 213 218 int readLocks = 0 ; 219 int writeLocks = 0 ; 220 ModelLockImpl modelLock ; 221 Thread thread ; 222 223 ModelLockState(ModelLockImpl lock) 226 { 227 modelLock = lock ; 228 thread = Thread.currentThread() ; 229 } 230 231 void clean() 232 { 233 if (modelLock.activeReadLocks.get() == 0 && modelLock.activeWriteLocks.get() == 0) 234 { 235 modelLock.removeLockState(thread) ; 240 } 241 } 242 } 243 } 244 245 271 272 | Popular Tags |