1 21 22 package org.apache.derby.impl.services.locks; 23 24 import org.apache.derby.iapi.services.monitor.Monitor; 25 26 import org.apache.derby.iapi.services.locks.LockFactory; 27 import org.apache.derby.iapi.services.locks.C_LockFactory; 28 import org.apache.derby.iapi.services.locks.Lockable; 29 import org.apache.derby.iapi.services.locks.Latch; 30 import org.apache.derby.iapi.services.locks.Limit; 31 32 import org.apache.derby.iapi.error.StandardException; 33 34 import org.apache.derby.iapi.services.property.PropertyUtil; 35 import org.apache.derby.iapi.services.daemon.Serviceable; 36 37 import org.apache.derby.iapi.services.sanity.SanityManager; 38 import org.apache.derby.iapi.util.Matchable; 39 import org.apache.derby.iapi.reference.Property; 40 41 import java.util.Hashtable ; 42 import java.util.Properties ; 43 import java.io.Serializable ; 44 import java.util.Dictionary ; 45 import java.util.Enumeration ; 46 47 import org.apache.derby.iapi.services.stream.HeaderPrintWriter; 49 50 64 65 public class SinglePool extends Hashtable 66 implements LockFactory 67 { 68 74 protected final LockSet lockTable; 75 76 95 96 99 int deadlockMonitor; 100 101 public SinglePool() { 102 lockTable = new LockSet(this); 103 } 104 105 108 109 119 public boolean latchObject(Object compatabilitySpace, Lockable ref, Object qualifier, int timeout) 120 throws StandardException { 121 122 Lock latch = lockTable.lockObject(compatabilitySpace, ref, qualifier, timeout, (Latch) null); 123 124 if (SanityManager.DEBUG) { 125 if (latch == null) 126 SanityManager.ASSERT(timeout == C_LockFactory.NO_WAIT, "timeout not NO_WAIT"); 127 } 128 return latch != null; 129 } 130 131 139 public void unlatch(Latch heldLatch) { 140 lockTable.unlock(heldLatch, 1); 141 } 142 143 153 protected Lock lockAnObject(Object compatabilitySpace, Object group, Lockable ref, Object qualifier, int timeout, Latch heldLatch) 154 throws StandardException 155 { 156 if (SanityManager.DEBUG) { 157 if (SanityManager.DEBUG_ON(Constants.LOCK_TRACE)) { 158 159 D_LockControl.debugLock("Lock Request before Grant: ", 160 compatabilitySpace, group, ref, qualifier, timeout); 161 162 if (SanityManager.DEBUG_ON(Constants.LOCK_STACK_TRACE)) 163 { 164 Throwable t = new Throwable (); 167 java.io.PrintWriter istream = SanityManager.GET_DEBUG_STREAM(); 168 169 istream.println("Stack trace of lock request:"); 170 t.printStackTrace(istream); 171 } 172 } 173 } 174 175 Lock lock = 176 lockTable.lockObject(compatabilitySpace, ref, qualifier, timeout, heldLatch); 177 178 if (lock == null) { 180 if (SanityManager.DEBUG) { 181 SanityManager.ASSERT(timeout == C_LockFactory.NO_WAIT, "timeout not NO_WAIT"); 182 } 183 return null; 184 } 185 186 if (SanityManager.DEBUG) { 187 if (SanityManager.DEBUG_ON(Constants.LOCK_TRACE)) { 188 D_LockControl.debugLock( 189 "Lock Request Granted: ", 190 compatabilitySpace, group, ref, qualifier, timeout); 191 } 192 } 193 194 synchronized (this) { 196 197 LockSpace ls = (LockSpace) get(compatabilitySpace); 198 if (ls == null) { 199 ls = new LockSpace(this, compatabilitySpace); 200 put(compatabilitySpace, ls); 201 } 202 203 208 ls.addLock(group, lock); 209 } 210 211 return lock; 212 } 213 214 224 public boolean lockObject(Object compatabilitySpace, Object group, Lockable ref, Object qualifier, int timeout) 225 throws StandardException { 226 227 return lockAnObject(compatabilitySpace, group, ref, qualifier, timeout, (Latch) null) != null; 228 } 229 230 240 public boolean lockObject(Object group, Lockable ref, Object qualifier, int timeout, Latch latch) 241 throws StandardException { 242 243 if (SanityManager.DEBUG) { 244 if (timeout == C_LockFactory.NO_WAIT) 245 SanityManager.THROWASSERT("no wait lock requested in lockObject() with latch"); 246 } 247 248 Lock lock = lockAnObject(latch.getCompatabilitySpace(), group, ref, qualifier, timeout, latch); 249 return lock instanceof ActiveLock; 250 } 251 252 260 261 public int unlock(Object compatabilitySpace, Object group, Lockable ref, Object qualifier) 262 { 263 if (SanityManager.DEBUG) { 264 if (SanityManager.DEBUG_ON(Constants.LOCK_TRACE)) { 265 D_LockControl.debugLock("Lock Unlock: ", 266 compatabilitySpace, group, ref, qualifier, -1); 267 } 268 } 269 270 LockSpace ls = (LockSpace) get(compatabilitySpace); 271 if (ls == null) 272 return 0; 273 274 int count = ls.unlockReference(lockTable, ref, qualifier, group); 275 276 if (SanityManager.DEBUG) { 277 SanityManager.ASSERT( 278 (count == 0) || (count == 1), "count = " + count); 279 } 280 281 return count; 282 } 283 284 295 public void unlockGroup(Object compatabilitySpace, Object group) { 296 297 if (SanityManager.DEBUG) { 298 if (SanityManager.DEBUG_ON(Constants.LOCK_TRACE)) { 299 D_LockControl.debugLock("Lock Unlock Group: ", compatabilitySpace, group); 300 } 301 } 302 303 LockSpace ls = (LockSpace) get(compatabilitySpace); 304 if (ls == null) 305 return; 306 307 ls.unlockGroup(lockTable, group); 308 } 309 310 public void unlockGroup(Object compatabilitySpace, Object group, Matchable key) { 311 312 if (SanityManager.DEBUG) { 313 if (SanityManager.DEBUG_ON(Constants.LOCK_TRACE)) { 314 D_LockControl.debugLock("Lock Unlock Group: ", compatabilitySpace, group); 315 } 316 } 317 318 LockSpace ls = (LockSpace) get(compatabilitySpace); 319 if (ls == null) 320 return; 321 322 ls.unlockGroup(lockTable, group, key); 323 324 325 } 326 327 335 public void transfer(Object compatabilitySpace, Object oldGroup, Object newGroup) { 336 337 if (SanityManager.DEBUG) { 338 if (SanityManager.DEBUG_ON(Constants.LOCK_TRACE)) { 339 StringBuffer sb = new StringBuffer ("Lock Transfer:"); 340 341 D_LockControl.debugAppendObject( 342 sb, " CompatabilitySpace=", compatabilitySpace); 343 D_LockControl.debugAppendObject(sb, " Old Group=", oldGroup); 344 D_LockControl.debugAppendObject(sb, " New Group=", newGroup); 345 346 D_LockControl.debugAddThreadInfo(sb); 347 348 SanityManager.DEBUG(Constants.LOCK_TRACE, sb.toString()); 349 } 350 } 351 352 LockSpace ls = (LockSpace) get(compatabilitySpace); 353 if (ls == null) 354 return; 355 356 361 ls.transfer(oldGroup, newGroup); 362 } 363 364 367 public boolean anyoneBlocked() { 368 return lockTable.anyoneBlocked(); 369 } 370 371 381 public boolean areLocksHeld(Object compatabilitySpace, Object group) { 382 383 LockSpace ls = (LockSpace) get(compatabilitySpace); 384 if (ls == null) 385 return false; 386 387 392 return ls.areLocksHeld(group); 393 } 394 395 403 public boolean areLocksHeld(Object compatabilitySpace) { 404 LockSpace ls = (LockSpace) get(compatabilitySpace); 405 if (ls == null) 406 return false; 407 return !ls.isEmpty(); 408 } 409 410 public boolean zeroDurationlockObject(Object compatabilitySpace, Lockable ref, Object qualifier, int timeout) 411 throws StandardException { 412 413 if (SanityManager.DEBUG) { 414 if (SanityManager.DEBUG_ON(Constants.LOCK_TRACE)) { 415 416 D_LockControl.debugLock("Zero Duration Lock Request before Grant: ", 417 compatabilitySpace, (Object ) null, ref, qualifier, timeout); 418 419 if (SanityManager.DEBUG_ON(Constants.LOCK_STACK_TRACE)) 420 { 421 Throwable t = new Throwable (); 424 java.io.PrintWriter istream = SanityManager.GET_DEBUG_STREAM(); 425 426 istream.println("Stack trace of lock request:"); 427 t.printStackTrace(istream); 428 } 429 } 430 } 431 432 synchronized (lockTable) { 441 442 Control control = (Control) lockTable.get(ref); 443 if (control == null) { 444 return true; 445 } 446 447 if (control.isGrantable(true, compatabilitySpace, qualifier)) 452 return true; 453 454 if (timeout == C_LockFactory.NO_WAIT) 456 return false; 457 } 458 459 Lock lock = 460 lockTable.lockObject(compatabilitySpace, ref, qualifier, timeout, (Latch) null); 461 462 if (SanityManager.DEBUG) { 463 if (SanityManager.DEBUG_ON(Constants.LOCK_TRACE)) { 464 D_LockControl.debugLock( 465 "Zero Lock Request Granted: ", 466 compatabilitySpace, (Object ) null, ref, qualifier, timeout); 467 } 468 } 469 470 lockTable.unlock(lock, 1); 472 473 return true; 474 } 475 476 public boolean isLockHeld(Object compatabilitySpace, Object group, Lockable ref, Object qualifier) { 477 478 LockSpace ls = (LockSpace) get(compatabilitySpace); 479 if (ls == null) 480 return false; 481 482 return ls.isLockHeld(group, ref, qualifier); 483 } 484 485 public synchronized void setLimit(Object compatabilitySpace, Object group, int limit, Limit callback) { 486 487 LockSpace ls = (LockSpace) get(compatabilitySpace); 488 if (ls == null) { 489 ls = new LockSpace(this, compatabilitySpace); 490 put(compatabilitySpace, ls); 491 } 492 493 ls.setLimit(group, limit, callback); 494 495 } 496 497 500 public void clearLimit(Object compatabilitySpace, Object group) { 501 LockSpace ls = (LockSpace) get(compatabilitySpace); 502 if (ls == null) 503 return; 504 505 ls.clearLimit(group); 506 } 507 508 510 513 514 public Enumeration makeVirtualLockTable() 515 { 516 LockTableVTI myclone = new LockTableVTI(lockTable.shallowClone()); 518 519 return myclone; 520 } 521 523 524 527 528 530 public String toDebugString() 531 { 532 return(lockTable.toDebugString()); 533 } 534 535 537 540 541 public void init(boolean dbOnly, Dictionary p) { 542 543 getAndApply(dbOnly, p, Property.DEADLOCK_TIMEOUT); 544 getAndApply(dbOnly, p, Property.LOCKWAIT_TIMEOUT); 545 getAndApply(dbOnly, p, Property.DEADLOCK_MONITOR); 546 getAndApply(dbOnly, p, Property.DEADLOCK_TRACE); 548 } 550 551 private void getAndApply(boolean dbOnly, Dictionary p, String key) { 552 553 try { 554 555 Serializable value = (String ) PropertyUtil.getPropertyFromSet(dbOnly, p, key); 556 if (value != null) { 557 validate(key, value, p); 558 apply(key, value, p); 559 } 560 } catch (StandardException se) { 561 } 563 } 564 565 566 public boolean validate(String key, Serializable value, Dictionary p) 567 throws StandardException { 568 569 if (!key.startsWith(Property.LOCKS_INTRO)) 570 return false; 571 572 if (value != null) { 573 574 if (key.equals(Property.DEADLOCK_TIMEOUT)) 575 getWaitValue((String ) value, Property.DEADLOCK_TIMEOUT_DEFAULT); 576 else if (key.equals(Property.LOCKWAIT_TIMEOUT)) 577 getWaitValue((String ) value, Property.WAIT_TIMEOUT_DEFAULT); 578 else if (key.equals(Property.DEADLOCK_MONITOR)) 579 PropertyUtil.booleanProperty(Property.DEADLOCK_MONITOR, value, false); 580 else if (key.equals(Property.DEADLOCK_TRACE)) 581 PropertyUtil.booleanProperty(Property.DEADLOCK_TRACE, value, false); 582 } 583 584 return true; 585 } 586 587 public Serviceable apply(String key, Serializable value, Dictionary p) 588 throws StandardException { 589 590 if (value == null) { 591 value = PropertyUtil.getPropertyFromSet(p, key); 593 } 594 595 String svalue = (String ) value; 596 597 if (key.equals(Property.DEADLOCK_TIMEOUT)) 598 lockTable.deadlockTimeout = getWaitValue(svalue, Property.DEADLOCK_TIMEOUT_DEFAULT); 599 else if (key.equals(Property.LOCKWAIT_TIMEOUT)) 600 lockTable.waitTimeout = getWaitValue(svalue, Property.WAIT_TIMEOUT_DEFAULT); 601 else if (key.equals(Property.DEADLOCK_MONITOR)) { 602 deadlockMonitor = PropertyUtil.booleanProperty(Property.DEADLOCK_MONITOR, svalue, false) ? 603 StandardException.REPORT_ALWAYS : StandardException.REPORT_DEFAULT; 604 } 605 else if (key.equals(Property.DEADLOCK_TRACE)) 607 lockTable.setDeadlockTrace(PropertyUtil.booleanProperty(Property.DEADLOCK_TRACE, svalue, false)); 608 610 return null; 611 } 612 613 public Serializable map(String key, Serializable value, Dictionary p) { 614 return null; 615 } 616 617 620 621 private static int getWaitValue(String value, int defaultValue ) { 622 623 int wait = PropertyUtil.handleInt(value, Integer.MIN_VALUE, Integer.MAX_VALUE / 1000, defaultValue); 625 626 if (wait < 0) 627 wait = C_LockFactory.WAIT_FOREVER; 628 else 629 wait *= 1000; 631 632 return wait; 633 } 634 } 635 | Popular Tags |