1 24 25 package com.mckoi.database; 26 27 import com.mckoi.debug.*; 28 import java.util.HashMap ; 29 30 74 75 public final class LockingMechanism { 76 77 81 public final static int SHARED_MODE = 1; 82 public final static int EXCLUSIVE_MODE = 2; 83 84 88 private HashMap queues_map = new HashMap (); 89 90 94 private boolean in_exclusive_mode = false; 95 96 101 private int shared_mode = 0; 102 103 106 private final DebugLogger debug; 107 108 111 public LockingMechanism(DebugLogger logger) { 112 this.debug = logger; 113 } 114 115 123 private LockingQueue getQueueFor(DataTable table) { 124 LockingQueue queue = (LockingQueue) queues_map.get(table); 125 126 if (queue == null) { 128 queue = new LockingQueue(table); 129 queues_map.put(table, queue); 130 } 131 132 return queue; 133 } 134 135 139 public void reset() { 140 141 synchronized (this) { 142 if (!isInExclusiveMode()) { 144 debug.writeException(new RuntimeException ("Should not clear a " + 147 "LockingMechanism that's not in exclusive mode.")); 148 } 149 queues_map.clear(); 150 } 151 152 } 153 154 171 public LockHandle lockTables(DataTable[] t_write, DataTable[] t_read) { 172 173 175 final int lock_count = t_read.length + t_write.length; 176 final LockHandle handle = new LockHandle(lock_count, debug); 177 178 synchronized (this) { 179 180 Lock lock; 181 LockingQueue queue; 182 int queue_index; 183 184 186 for (int i = t_write.length - 1; i >= 0; --i) { 187 DataTable to_write_lock = t_write[i]; 188 queue = getQueueFor(to_write_lock); 189 lock = new Lock(Lock.WRITE, queue, debug); 191 handle.addLock(lock); 192 193 debug.write(Lvl.INFORMATION, this, 194 "[LockingMechanism] Locking for WRITE: " + 195 to_write_lock.getTableName()); 196 } 197 198 for (int i = t_read.length - 1; i >= 0; --i) { 199 DataTable to_read_lock = t_read[i]; 200 queue = getQueueFor(to_read_lock); 201 lock = new Lock(Lock.READ, queue, debug); 203 handle.addLock(lock); 204 205 debug.write(Lvl.INFORMATION, this, 206 "[LockingMechanism] Locking for READ: " + 207 to_read_lock.getTableName()); 208 } 209 210 } 211 212 debug.write(Lvl.INFORMATION, this, "Locked Tables"); 213 214 return handle; 215 216 } 217 218 226 public void unlockTables(LockHandle handle) { 227 synchronized (this) { 228 handle.unlockAll(); 229 } 230 debug.write(Lvl.INFORMATION, this, "UnLocked Tables"); 231 } 232 233 236 public synchronized boolean isInExclusiveMode() { 237 return in_exclusive_mode; 238 } 239 240 251 public synchronized void setMode(int mode) { 252 253 255 while (in_exclusive_mode == true) { 256 try { 257 wait(); 259 } 261 catch (InterruptedException e) {} 262 } 263 264 if (mode == EXCLUSIVE_MODE) { 265 266 269 in_exclusive_mode = true; 270 while (shared_mode > 0) { 271 try { 272 wait(); 274 } 276 catch (InterruptedException e) {} 277 } 278 279 debug.write(Lvl.INFORMATION, this, "Locked into ** EXCLUSIVE MODE **"); 280 281 } 282 else if (mode == SHARED_MODE) { 283 284 286 ++shared_mode; 287 288 debug.write(Lvl.INFORMATION, this, "Locked into SHARED MODE"); 289 290 } 291 else { 292 throw new Error ("Invalid mode"); 293 } 294 } 295 296 303 public synchronized void finishMode(int mode) { 304 if (mode == EXCLUSIVE_MODE) { 305 in_exclusive_mode = false; 306 notifyAll(); 307 308 debug.write(Lvl.INFORMATION, this, "UnLocked from ** EXCLUSIVE MODE **"); 309 310 } 311 else if (mode == SHARED_MODE) { 312 --shared_mode; 313 if (shared_mode == 0 && in_exclusive_mode) { 314 notifyAll(); 315 } 316 else if (shared_mode < 0) { 317 shared_mode = 0; 318 notifyAll(); 319 throw new RuntimeException ("Too many 'finishMode(SHARED_MODE)' calls"); 320 } 321 322 debug.write(Lvl.INFORMATION, this, "UnLocked from SHARED MODE"); 323 324 } 325 else { 326 throw new Error ("Invalid mode"); 327 } 328 } 329 330 } 331 | Popular Tags |