1 9 package org.ozoneDB.core; 10 11 import java.io.*; 12 import org.ozoneDB.*; 13 import org.ozoneDB.DxLib.*; 14 import org.ozoneDB.util.*; 15 16 17 25 public final class MROWLock extends AbstractLock { 26 27 protected final static long serialVersionUID = 1; 28 protected final static byte subSerialVersionUID = 1; 29 30 protected final static boolean enableReleaseOfReadlockOnFailedWritelock = false; 31 32 private int level = LEVEL_NONE; 33 34 private SharedLock readLock; 35 36 private ExclusiveLock writeLock; 37 38 protected transient String debugInfo; 39 40 41 public MROWLock() { 42 reset(); 43 } 44 45 46 public synchronized void reset() { 47 level = LEVEL_NONE; 48 readLock = new SharedLock(); 49 writeLock = new ExclusiveLock(); 50 } 51 52 53 public void setDebugInfo(String debugInfo) { 54 this.debugInfo = debugInfo; 55 } 56 57 public int tryAcquire( Transaction ta, int newLevel ) { 58 if (false&&ta.env.logWriter.hasTarget( LogWriter.DEBUG3 )) { 59 ta.env.logWriter.newEntry( this, "tryAcquire(): ta.getID()="+ta.taID()+", current:" + level + " new:" + newLevel+", writeLock.getLocker()="+writeLock.getLocker()+".", LogWriter.DEBUG3 ); 60 } 61 62 if (readLock.isAcquiredBy( ta ) && level == newLevel) { 63 return level; 64 } 65 66 if (ta.env.logWriter.hasTarget( LogWriter.DEBUG2 )) { 67 if (false&&(newLevel>level||(!ta.taID().equals(writeLock.getLocker())))) { 68 ta.env.logWriter.newEntry( this, this+".tryAcquire(): ta.getID()="+ta.taID()+", current:" + level + " new:" + newLevel+", writeLock.getLocker()="+writeLock.getLocker()+".", LogWriter.DEBUG2 ); 69 } 70 } 71 72 synchronized (this) { 73 int prevLevel = NOT_ACQUIRED; 74 75 if (newLevel <= LEVEL_NONE || newLevel >= LEVEL_MAX) { 76 ta.env.logWriter.newEntry( this, "tryAcquire(): newLevel == " + newLevel, LogWriter.WARN ); 77 } 78 79 boolean result = false; 80 81 if (level == LEVEL_NONE) { 83 prevLevel = LEVEL_NONE; 84 85 int readLockPrevLevel; 86 87 if ((readLockPrevLevel = readLock.tryAcquire(ta,LEVEL_READ)) != NOT_ACQUIRED) { 88 result = true; 89 if (newLevel > LEVEL_READ) { 90 if (writeLock.tryAcquire( ta, LEVEL_WRITE ) == NOT_ACQUIRED) { 91 result = false; 92 if (enableReleaseOfReadlockOnFailedWritelock) { 93 readLock.release( ta ); 94 } else { 95 if (readLockPrevLevel<LEVEL_READ) { readLock.release(ta); 97 } 98 } 99 } 100 } 101 } 102 } else if (readLock.isAcquiredBy( ta )) { 103 prevLevel = level; 105 result = true; 106 if (newLevel > LEVEL_READ) { 107 113 if (!readLock.areMultipleLockersHoldingLocks()) { 114 if (writeLock.tryAcquire( ta, LEVEL_WRITE ) == NOT_ACQUIRED) { 115 result = false; 116 readLock.release( ta ); 117 } 118 } else { 119 result = false; 120 121 if (enableReleaseOfReadlockOnFailedWritelock) { 122 readLock.release(ta); 124 } 125 } 126 } 127 } else { 128 if (newLevel == LEVEL_READ && level == LEVEL_READ) { 130 prevLevel = LEVEL_NONE; 131 if (readLock.tryAcquire( ta, LEVEL_READ ) != NOT_ACQUIRED) { 132 result = true; 133 } 134 } 135 } 136 137 if (result) { 138 level = newLevel > level ? newLevel : level; 139 return prevLevel; 140 } else { 141 return NOT_ACQUIRED; 142 } 143 } 144 } 145 146 147 protected synchronized boolean acquire( Transaction ta, int newLevel ) { 148 int prevLevel = readLock.tryAcquire( ta, LEVEL_READ ); 149 if (newLevel > LEVEL_READ && prevLevel > NOT_ACQUIRED) { 150 prevLevel = writeLock.tryAcquire( ta, LEVEL_WRITE ); 151 if (prevLevel == NOT_ACQUIRED) { 152 readLock.release( ta ); 153 } 154 } 155 return prevLevel != NOT_ACQUIRED; 156 } 157 158 159 public void release( Transaction ta ) { 160 if (false&&ta.env.logWriter.hasTarget( LogWriter.DEBUG2 )) { 161 ta.env.logWriter.newEntry( this, this+".release(): ta.getID()="+ta.taID()+".", LogWriter.DEBUG2 ); 162 } 163 164 if (level == LEVEL_NONE) { 165 ta.env.logWriter.newEntry( this, this+".release(): current level is LEVEL_NONE.", new Exception (),LogWriter.WARN ); 166 } 167 168 synchronized (this) { 169 if (writeLock.isAcquiredBy( ta )) { 170 writeLock.release( ta ); 171 level = LEVEL_READ; 172 } 173 if (readLock.isAcquiredBy( ta )) { 174 readLock.release( ta ); 175 if (readLock.level( null ) == LEVEL_NONE) { 176 level = LEVEL_NONE; 177 } 178 } 179 } 180 181 191 } 192 193 194 public boolean isAcquiredBy( Transaction ta ) { 195 switch (level) { 196 case LEVEL_NONE: { 197 return false; 198 } 199 case LEVEL_READ: { 200 return readLock.isAcquiredBy( ta ); 201 } 202 default: { 203 return writeLock.isAcquiredBy( ta ); 204 } 205 } 206 } 207 208 public TransactionID getWriteLockingTransactionID() { 209 return level < LEVEL_WRITE ? null : writeLock.getLocker(); 210 } 211 212 public DxCollection lockerIDs() { 213 switch (level) { 214 case LEVEL_NONE: { 215 return new DxArrayBag(); 216 } 217 default: { 218 return readLock.lockerIDs(); 221 } 222 } 223 } 224 225 226 public int level( Transaction ta ) { 227 if (ta == null) { 228 return level; 229 } else { 230 switch (level) { 231 case LEVEL_NONE: { 232 return LEVEL_NONE; 233 } 234 case LEVEL_READ: { 235 return readLock.isAcquiredBy( ta ) ? level : LEVEL_NONE; 236 } 237 default: { 238 return writeLock.isAcquiredBy( ta ) ? level : LEVEL_NONE; 239 } 240 } 241 } 242 } 243 244 public String toString() { 245 return "MROWLock[" + debugInfo + ",writeLock.getLocker()=" 246 + writeLock.getLocker() + ",readLock=" + readLock + ",level=" + level + "]"; 247 } 248 } 249 | Popular Tags |