1 5 package com.tc.object.lockmanager.api; 6 7 import EDU.oswego.cs.dl.util.concurrent.BrokenBarrierException; 8 import EDU.oswego.cs.dl.util.concurrent.CyclicBarrier; 9 import EDU.oswego.cs.dl.util.concurrent.LinkedQueue; 10 import EDU.oswego.cs.dl.util.concurrent.SynchronizedBoolean; 11 12 import com.tc.exception.TCRuntimeException; 13 import com.tc.logging.NullTCLogger; 14 import com.tc.logging.TCLogger; 15 import com.tc.object.lockmanager.api.TestRemoteLockManager.LockResponder; 16 import com.tc.object.lockmanager.impl.ClientLockManagerImpl; 17 import com.tc.object.session.SessionID; 18 import com.tc.object.session.SessionManager; 19 import com.tc.object.session.SessionProvider; 20 import com.tc.object.session.TestSessionManager; 21 import com.tc.object.tx.WaitInvocation; 22 import com.tc.util.concurrent.NoExceptionLinkedQueue; 23 import com.tc.util.concurrent.ThreadUtil; 24 25 import java.util.ArrayList ; 26 import java.util.Collection ; 27 import java.util.Collections ; 28 import java.util.HashSet ; 29 import java.util.Iterator ; 30 import java.util.LinkedList ; 31 import java.util.List ; 32 import java.util.Set ; 33 34 import junit.framework.TestCase; 35 36 39 public class ClientLockManagerTest extends TestCase { 40 private ClientLockManager lockManager; 41 42 private TestRemoteLockManager rmtLockManager; 43 44 private TestSessionManager sessionManager; 45 46 protected void setUp() throws Exception { 47 super.setUp(); 48 sessionManager = new TestSessionManager(); 49 rmtLockManager = new TestRemoteLockManager(sessionManager); 50 lockManager = new ClientLockManagerImpl(new NullTCLogger(), rmtLockManager, sessionManager); 51 rmtLockManager.setClientLockManager(lockManager); 52 } 53 54 public void testNestedSynchronousWrite() { 55 final LockID lockID_1 = new LockID("1"); 56 final LockID lockID_2 = new LockID("2"); 57 final ThreadID threadID_1 = new ThreadID(1); 58 final ThreadID threadID_2 = new ThreadID(2); 59 60 rmtLockManager.resetFlushCount(); 61 62 assertEquals(0, rmtLockManager.getFlushCount()); 63 lockManager.lock(lockID_1, threadID_1, LockLevel.WRITE); 64 lockManager.lock(lockID_1, threadID_1, LockLevel.READ); 65 lockManager.lock(lockID_1, threadID_1, LockLevel.SYNCHRONOUS_WRITE); 66 lockManager.lock(lockID_1, threadID_1, LockLevel.WRITE); 67 lockManager.lock(lockID_1, threadID_1, LockLevel.SYNCHRONOUS_WRITE); 68 assertEquals(0, rmtLockManager.getFlushCount()); 69 lockManager.unlock(lockID_1, threadID_1); 70 assertEquals(1, rmtLockManager.getFlushCount()); 71 lockManager.unlock(lockID_1, threadID_1); 72 assertEquals(1, rmtLockManager.getFlushCount()); 73 lockManager.unlock(lockID_1, threadID_1); 74 assertEquals(2, rmtLockManager.getFlushCount()); 75 lockManager.unlock(lockID_1, threadID_1); 76 assertEquals(2, rmtLockManager.getFlushCount()); 77 lockManager.unlock(lockID_1, threadID_1); 78 assertEquals(3, rmtLockManager.getFlushCount()); 79 80 rmtLockManager.resetFlushCount(); 81 rmtLockManager.makeLocksGreedy(); 82 83 assertEquals(0, rmtLockManager.getFlushCount()); 84 lockManager.lock(lockID_2, threadID_2, LockLevel.WRITE); 85 lockManager.lock(lockID_2, threadID_2, LockLevel.READ); 86 lockManager.lock(lockID_2, threadID_2, LockLevel.SYNCHRONOUS_WRITE); 87 lockManager.lock(lockID_2, threadID_2, LockLevel.WRITE); 88 lockManager.lock(lockID_2, threadID_2, LockLevel.SYNCHRONOUS_WRITE); 89 assertEquals(0, rmtLockManager.getFlushCount()); 90 lockManager.unlock(lockID_2, threadID_2); 91 assertEquals(1, rmtLockManager.getFlushCount()); 92 lockManager.unlock(lockID_2, threadID_2); 93 assertEquals(1, rmtLockManager.getFlushCount()); 94 lockManager.unlock(lockID_2, threadID_2); 95 assertEquals(2, rmtLockManager.getFlushCount()); 96 lockManager.unlock(lockID_2, threadID_2); 97 lockManager.unlock(lockID_2, threadID_2); 98 assertEquals(2, rmtLockManager.getFlushCount()); 99 rmtLockManager.resetFlushCount(); 100 rmtLockManager.makeLocksNotGreedy(); 101 } 102 103 public void testSynchronousWriteUnlock() { 104 final LockID lockID_1 = new LockID("1"); 105 final LockID lockID_2 = new LockID("2"); 106 final ThreadID threadID_1 = new ThreadID(1); 107 final ThreadID threadID_2 = new ThreadID(2); 108 109 rmtLockManager.resetFlushCount(); 110 111 assertEquals(0, rmtLockManager.getFlushCount()); 112 lockManager.lock(lockID_1, threadID_1, LockLevel.SYNCHRONOUS_WRITE); 113 assertEquals(0, rmtLockManager.getFlushCount()); 114 lockManager.unlock(lockID_1, threadID_1); 115 assertEquals(1, rmtLockManager.getFlushCount()); 116 117 rmtLockManager.makeLocksGreedy(); 118 119 lockManager.lock(lockID_2, threadID_2, LockLevel.SYNCHRONOUS_WRITE); 120 assertEquals(1, rmtLockManager.getFlushCount()); 121 lockManager.unlock(lockID_2, threadID_2); 122 assertEquals(2, rmtLockManager.getFlushCount()); 123 124 rmtLockManager.resetFlushCount(); 125 rmtLockManager.makeLocksNotGreedy(); 126 } 127 128 public void testSynchronousWriteWait() { 129 130 final LockID lockID_1 = new LockID("1"); 131 final LockID lockID_2 = new LockID("2"); 132 final ThreadID threadID_1 = new ThreadID(1); 133 final ThreadID threadID_2 = new ThreadID(2); 134 135 rmtLockManager.resetFlushCount(); 136 137 assertEquals(0, rmtLockManager.getFlushCount()); 138 lockManager.lock(lockID_1, threadID_1, LockLevel.SYNCHRONOUS_WRITE); 139 assertEquals(0, rmtLockManager.getFlushCount()); 140 141 WaitInvocation waitInvocation = new WaitInvocation(); 142 NoExceptionLinkedQueue barrier = new NoExceptionLinkedQueue(); 143 WaitLockRequest waitLockRequest = new WaitLockRequest(lockID_1, threadID_1, LockLevel.SYNCHRONOUS_WRITE, 144 waitInvocation); 145 LockWaiter waiterThread = new LockWaiter(barrier, waitLockRequest, new Object ()); 146 waiterThread.start(); 147 Object o = barrier.take(); 148 assertNotNull(o); 149 150 assertEquals(1, rmtLockManager.getFlushCount()); 151 152 rmtLockManager.makeLocksGreedy(); 153 154 lockManager.lock(lockID_2, threadID_2, LockLevel.SYNCHRONOUS_WRITE); 155 assertEquals(1, rmtLockManager.getFlushCount()); 156 157 waitInvocation = new WaitInvocation(); 158 waitLockRequest = new WaitLockRequest(lockID_2, threadID_2, LockLevel.SYNCHRONOUS_WRITE, waitInvocation); 159 waiterThread = new LockWaiter(barrier, waitLockRequest, new Object ()); 160 waiterThread.start(); 161 o = barrier.take(); 162 assertNotNull(o); 163 164 assertEquals(2, rmtLockManager.getFlushCount()); 165 166 rmtLockManager.resetFlushCount(); 167 rmtLockManager.makeLocksNotGreedy(); 168 } 169 170 public void testTryLock() { 171 class TryLockRemoteLockManager extends TestRemoteLockManager { 172 private CyclicBarrier requestBarrier; 173 private CyclicBarrier awardBarrier; 174 175 public TryLockRemoteLockManager(SessionProvider sessionProvider, CyclicBarrier requestBarrier, 176 CyclicBarrier awardBarrier) { 177 super(sessionProvider); 178 this.requestBarrier = requestBarrier; 179 this.awardBarrier = awardBarrier; 180 } 181 182 public void tryRequestLock(LockID lockID, ThreadID threadID, int lockType) { 183 try { 184 requestBarrier.barrier(); 185 awardBarrier.barrier(); 186 } catch (BrokenBarrierException e) { 187 throw new TCRuntimeException(e); 188 } catch (InterruptedException e) { 189 throw new TCRuntimeException(e); 190 } 191 } 192 } 193 194 class TryLockClientLockManager extends ClientLockManagerImpl { 195 private CyclicBarrier awardBarrier; 196 197 public TryLockClientLockManager(TCLogger logger, RemoteLockManager remoteLockManager, 198 SessionManager sessionManager, CyclicBarrier awardBarrier) { 199 super(logger, remoteLockManager, sessionManager); 200 this.awardBarrier = awardBarrier; 201 } 202 203 public void awardLock(SessionID sessionID, LockID lockID, ThreadID threadID, int level) { 204 try { 205 awardBarrier.barrier(); 206 super.awardLock(sessionID, lockID, threadID, level); 207 } catch (BrokenBarrierException e) { 208 throw new TCRuntimeException(e); 209 } catch (InterruptedException e) { 210 throw new TCRuntimeException(e); 211 } 212 } 213 } 214 215 final CyclicBarrier requestBarrier = new CyclicBarrier(2); 216 final CyclicBarrier awardBarrier = new CyclicBarrier(2); 217 218 rmtLockManager = new TryLockRemoteLockManager(sessionManager, requestBarrier, awardBarrier); 219 lockManager = new TryLockClientLockManager(new NullTCLogger(), rmtLockManager, sessionManager, awardBarrier); 220 221 final LockID lockID1 = new LockID("1"); 222 final ThreadID txID = new ThreadID(1); 223 224 Thread t1 = new Thread (new Runnable () { 225 public void run() { 226 try { 227 requestBarrier.barrier(); 228 lockManager.awardLock(sessionManager.getSessionID(), lockID1, ThreadID.VM_ID, LockLevel 229 .makeGreedy(LockLevel.WRITE)); 230 } catch (BrokenBarrierException e) { 231 throw new TCRuntimeException(e); 232 } catch (InterruptedException e) { 233 throw new TCRuntimeException(e); 234 } 235 } 236 }); 237 t1.start(); 238 239 lockManager.tryLock(lockID1, txID, LockLevel.WRITE); 240 241 } 242 243 public void testGreedyLockRequest() { 244 final LockID lockID1 = new LockID("1"); 245 final ThreadID tx1 = new ThreadID(1); 246 final ThreadID tx2 = new ThreadID(2); 247 final NoExceptionLinkedQueue queue = new NoExceptionLinkedQueue(); 248 249 rmtLockManager.lockResponder = new LockResponder() { 250 251 public void respondToLockRequest(LockRequest request) { 252 queue.put(request); 253 lockManager.awardLock(sessionManager.getSessionID(), request.lockID(), ThreadID.VM_ID, LockLevel 254 .makeGreedy(request.lockLevel())); 255 } 256 }; 257 258 lockManager.lock(lockID1, tx1, LockLevel.WRITE); 260 LockRequest request = (LockRequest) queue.poll(1000l); 261 assertNotNull(request); 262 assertEquals(tx1, request.threadID()); 263 assertEquals(lockID1, request.lockID()); 264 assertEquals(LockLevel.WRITE, request.lockLevel()); 265 266 lockManager.lock(lockID1, tx1, LockLevel.READ); 268 lockManager.unlock(lockID1, tx1); 269 lockManager.unlock(lockID1, tx1); 270 lockManager.lock(lockID1, tx1, LockLevel.READ); 271 lockManager.lock(lockID1, tx2, LockLevel.READ); 272 273 assertNull(queue.poll(1000l)); 274 } 275 276 public void testNotified() throws Exception { 277 final LockID lockID1 = new LockID("1"); 278 final LockID lockID2 = new LockID("2"); 279 final ThreadID tx1 = new ThreadID(1); 280 final ThreadID tx2 = new ThreadID(2); 281 final Set heldLocks = new HashSet (); 282 final Set waiters = new HashSet (); 283 284 heldLocks.add(new LockRequest(lockID1, tx1, LockLevel.WRITE)); 285 lockManager.lock(lockID1, tx1, LockLevel.WRITE); 286 assertNotNull(rmtLockManager.lockRequestCalls.poll(1)); 287 288 NoExceptionLinkedQueue barrier = new NoExceptionLinkedQueue(); 289 WaitInvocation waitInvocation = new WaitInvocation(); 290 291 lockManager.lock(lockID2, tx2, LockLevel.WRITE); 299 assertNotNull(rmtLockManager.lockRequestCalls.poll(1)); 300 301 WaitLockRequest waitLockRequest = new WaitLockRequest(lockID2, tx2, LockLevel.WRITE, waitInvocation); 302 waiters.add(waitLockRequest); 303 final LockWaiter waiterThread = new LockWaiter(barrier, waitLockRequest, new Object ()); 304 waiterThread.start(); 305 306 barrier.take(); 307 assertTrue(barrier.isEmpty()); 308 if (!waiterThread.exceptions.isEmpty()) { 309 for (Iterator i = waiterThread.exceptions.iterator(); i.hasNext();) { 310 ((Throwable ) i.next()).printStackTrace(); 311 } 312 fail("Waiter thread had exceptions!"); 313 } 314 315 pauseAndStart(); 318 319 Set s = new HashSet (); 320 lockManager.addAllHeldLocksTo(s); 321 assertEquals(heldLocks, s); 322 323 s.clear(); 324 lockManager.addAllWaitersTo(s); 325 assertEquals(waiters, s); 326 s.clear(); 327 328 lockManager.addAllPendingLockRequestsTo(s); 329 assertTrue(s.size() == 0); 330 331 rmtLockManager.lockResponder = rmtLockManager.NULL_LOCK_RESPONDER; 333 assertTrue(rmtLockManager.lockRequestCalls.isEmpty()); 334 335 lockManager.unpause(); 336 337 lockManager.notified(waitLockRequest.lockID(), waitLockRequest.threadID()); 340 341 pauseAndStart(); 342 s.clear(); 344 lockManager.addAllHeldLocksTo(s); 345 assertEquals(heldLocks, s); 346 347 s.clear(); 349 lockManager.addAllWaitersTo(s); 350 assertEquals(Collections.EMPTY_SET, s); 351 352 lockManager.addAllPendingLockRequestsTo(s); 353 assertTrue(s.size() == 1); 354 LockRequest lr = (LockRequest) s.iterator().next(); 355 assertNotNull(lr); 356 assertEquals(waitLockRequest.lockID(), lr.lockID()); 357 assertEquals(waitLockRequest.threadID(), lr.threadID()); 358 assertTrue(waitLockRequest.lockLevel() == lr.lockLevel()); 359 360 lockManager.unpause(); 361 362 lockManager.awardLock(sessionManager.getSessionID(), waitLockRequest.lockID(), waitLockRequest.threadID(), 364 waitLockRequest.lockLevel()); 365 heldLocks.add(waitLockRequest); 366 367 pauseAndStart(); 368 s.clear(); 371 lockManager.addAllHeldLocksTo(s); 372 assertEquals(heldLocks, s); 373 374 s.clear(); 376 lockManager.addAllWaitersTo(s); 377 assertEquals(Collections.EMPTY_SET, s); 378 379 assertTrue(rmtLockManager.lockRequestCalls.isEmpty()); 381 lockManager.addAllPendingLockRequestsTo(null); 382 assertTrue(rmtLockManager.lockRequestCalls.isEmpty()); 383 } 384 385 public void testAddAllOutstandingLocksTo() throws Exception { 386 387 final LockID lockID = new LockID("my lock"); 391 final ThreadID tx1 = new ThreadID(1); 392 final int writeLockLevel = LockLevel.WRITE; 393 394 final LockID readLock = new LockID("my read lock"); 395 final ThreadID tx2 = new ThreadID(2); 396 final int readLockLevel = LockLevel.READ; 397 398 402 Set lockRequests = new HashSet (); 403 lockRequests.add(new LockRequest(lockID, tx1, writeLockLevel)); 404 lockRequests.add(new LockRequest(readLock, tx2, readLockLevel)); 405 407 lockManager.lock(lockID, tx1, writeLockLevel); 408 lockManager.lock(readLock, tx2, readLockLevel); 409 411 Set s = new HashSet (); 412 try { 413 lockManager.addAllHeldLocksTo(s); 414 fail("Expected an assertion error."); 415 } catch (AssertionError e) { 416 } 418 419 pauseAndStart(); 420 lockManager.addAllHeldLocksTo(s); 421 assertEquals(lockRequests.size(), s.size()); 422 assertEquals(lockRequests, s); 423 424 lockManager.unpause(); 425 lockManager.unlock(lockID, tx1); 426 lockManager.unlock(readLock, tx2); 427 pauseAndStart(); 429 assertEquals(0, lockManager.addAllHeldLocksTo(new HashSet ()).size()); 430 } 431 432 public void testAddAllOutstandingWaitersTo() throws Exception { 433 final LockID lockID = new LockID("my lock"); 434 final ThreadID tx1 = new ThreadID(1); 435 final WaitInvocation waitInvocation = new WaitInvocation(); 436 final Object waitObject = new Object (); 437 final NoExceptionLinkedQueue barrier = new NoExceptionLinkedQueue(); 438 lockManager.lock(lockID, tx1, LockLevel.WRITE); 439 Thread t = new LockWaiter(barrier, lockID, tx1, waitInvocation, waitObject); 440 t.start(); 441 barrier.take(); 442 ThreadUtil.reallySleep(200); 443 444 Set s = new HashSet (); 445 try { 446 lockManager.addAllWaitersTo(s); 447 fail("Expected an assertion error."); 448 } catch (AssertionError e) { 449 } 451 452 pauseAndStart(); 453 lockManager.addAllWaitersTo(s); 454 List waiters = new LinkedList (s); 455 assertEquals(1, waiters.size()); 456 WaitLockRequest waitRequest = (WaitLockRequest) waiters.get(0); 457 assertEquals(lockID, waitRequest.lockID()); 458 assertEquals(tx1, waitRequest.threadID()); 459 assertEquals(waitInvocation, waitRequest.getWaitInvocation()); 460 461 assertEquals(0, lockManager.addAllHeldLocksTo(new HashSet ()).size()); 464 } 465 466 public void testPauseBlocks() throws Exception { 467 final LinkedQueue flowControl = new LinkedQueue(); 468 final LinkedQueue lockComplete = new LinkedQueue(); 469 final LinkedQueue unlockComplete = new LinkedQueue(); 470 final LockID lockID = new LockID("1"); 471 final ThreadID txID = new ThreadID(1); 472 final int lockType = LockLevel.WRITE; 473 474 Thread locker = new Thread ("LOCKER") { 475 public void run() { 476 try { 477 flowControl.put("locker: Calling lock"); 478 lockManager.lock(lockID, txID, lockType); 479 lockComplete.put("locker: lock complete."); 480 481 System.out.println(flowControl.take()); 483 lockManager.unlock(lockID, txID); 484 unlockComplete.put("locker: unlock complete."); 485 486 System.out.println(flowControl.take()); 488 rmtLockManager.lockResponder = rmtLockManager.NULL_LOCK_RESPONDER; 489 lockManager.lock(lockID, txID, lockType); 490 System.out.println("locker: Done calling lock again"); 491 492 } catch (Throwable e) { 493 e.printStackTrace(); 494 fail(); 495 } 496 } 497 }; 498 499 assertFalse(lockManager.isStarting()); 500 pauseAndStart(); 501 locker.start(); 502 503 System.out.println(flowControl.take()); 505 506 ThreadUtil.reallySleep(500); 507 508 assertTrue(lockComplete.peek() == null); 510 assertTrue(lockManager.isStarting()); 512 lockManager.unpause(); 513 assertFalse(lockManager.isStarting()); 514 System.out.println(lockComplete.take()); 516 System.out.println("Done testing lock(..)"); 517 518 pauseAndStart(); 520 flowControl.put("test: lock manager paused, it's ok for locker to call unlock(..)"); 521 ThreadUtil.reallySleep(500); 522 assertTrue(unlockComplete.peek() == null); 523 lockManager.unpause(); 525 unlockComplete.take(); 526 System.out.println("Done testing unlock(..)"); 527 528 } 532 533 public void testResendBasics() throws Exception { 534 final List requests = new ArrayList (); 535 final LinkedQueue flowControl = new LinkedQueue(); 536 final SynchronizedBoolean respond = new SynchronizedBoolean(true); 537 rmtLockManager.lockResponder = new LockResponder() { 538 public void respondToLockRequest(final LockRequest request) { 539 new Thread () { 540 public void run() { 541 requests.add(request); 542 if (respond.get()) { 543 lockManager.awardLock(sessionManager.getSessionID(), request.lockID(), request.threadID(), request 544 .lockLevel()); 545 } 546 try { 547 flowControl.put("responder: respondToLockRequest complete. Lock awarded: " + respond.get()); 548 } catch (InterruptedException e) { 549 e.printStackTrace(); 550 fail(); 551 } 552 } 553 }.start(); 554 } 555 }; 556 557 final ThreadID tid0 = new ThreadID(0); 558 final ThreadID tid1 = new ThreadID(1); 559 final LockID lid0 = new LockID("0"); 560 final LockID lid1 = new LockID("1"); 561 562 LockRequest lr0 = new LockRequest(lid0, tid0, LockLevel.WRITE); 563 LockRequest lr1 = new LockRequest(lid1, tid1, LockLevel.WRITE); 564 565 Thread t = new LockGetter(lid0, tid0, LockLevel.WRITE); 567 t.start(); 568 System.out.println(flowControl.take()); 570 assertEquals(1, requests.size()); 571 assertEquals(lr0, requests.get(0)); 572 573 requests.clear(); 575 respond.set(false); 576 577 t = new LockGetter(lid1, tid1, LockLevel.WRITE); 578 t.start(); 579 System.out.println(flowControl.take()); 580 581 assertEquals(1, requests.size()); 582 assertEquals(lr1, requests.get(0)); 583 584 requests.clear(); 586 respond.set(true); 587 pauseAndStart(); 588 lockManager.addAllPendingLockRequestsTo(requests); 589 lockManager.unpause(); 590 assertEquals(1, requests.size()); 591 assertEquals(lr1, requests.get(0)); 592 593 596 requests.clear(); 597 rmtLockManager.lockResponder = rmtLockManager.LOOPBACK_LOCK_RESPONDER; 598 599 } 600 601 public void testAwardWhenNotPending() throws Exception { 602 LockID lockID = new LockID("1"); 603 ThreadID txID = new ThreadID(1); 604 try { 605 lockManager.awardLock(sessionManager.getSessionID(), lockID, txID, LockLevel.WRITE); 606 fail("Should have thrown an error"); 607 } catch (AssertionError e) { 608 } 610 } 611 612 public void testBasics() throws Exception { 613 final ThreadID tid0 = new ThreadID(0); 614 final LockID lid0 = new LockID("0"); 615 616 final ThreadID tid1 = new ThreadID(1); 617 618 System.out.println("Get lock0 for tx0"); 619 lockManager.lock(lid0, tid0, LockLevel.WRITE); 620 System.out.println("Got lock0 for tx0"); 621 lockManager.lock(lid0, tid0, LockLevel.WRITE); 622 System.out.println("Got lock0 for tx0 AGAIN so the recursion lock is correct"); 623 final boolean[] done = new boolean[1]; 624 done[0] = false; 625 Thread t = new Thread () { 626 public void run() { 627 lockManager.lock(lid0, tid1, LockLevel.WRITE); 628 System.out.println("Got lock0 for tx1"); 629 done[0] = true; 630 } 631 }; 632 t.start(); 633 ThreadUtil.reallySleep(500); 634 assertFalse(done[0]); 635 lockManager.unlock(lid0, tid0); 636 ThreadUtil.reallySleep(500); 637 assertFalse(done[0]); 638 lockManager.unlock(lid0, tid0); 639 ThreadUtil.reallySleep(500); 640 assertTrue(done[0]); 641 } 642 643 public void testBasicUnlock() throws Exception { 644 assertEquals(0, rmtLockManager.getLockRequestCount()); 645 assertEquals(0, rmtLockManager.getUnlockRequestCount()); 646 ThreadID tid0 = new ThreadID(0); 647 LockID lid0 = new LockID("0"); 648 649 lockManager.lock(lid0, tid0, LockLevel.READ); 650 assertEquals(1, rmtLockManager.getLockRequestCount()); 651 assertEquals(0, rmtLockManager.getUnlockRequestCount()); 652 653 lockManager.unlock(lid0, tid0); 654 assertEquals(1, rmtLockManager.getLockRequestCount()); 655 assertEquals(1, rmtLockManager.getUnlockRequestCount()); 656 657 lockManager.lock(lid0, tid0, LockLevel.WRITE); 658 assertEquals(2, rmtLockManager.getLockRequestCount()); 659 assertEquals(1, rmtLockManager.getUnlockRequestCount()); 660 661 lockManager.unlock(lid0, tid0); 662 assertEquals(2, rmtLockManager.getLockRequestCount()); 663 assertEquals(2, rmtLockManager.getUnlockRequestCount()); 664 } 665 666 public void testLockChangesAfterUpgrade() throws Exception { 667 assertEquals(0, rmtLockManager.getLockRequestCount()); 668 ThreadID tid0 = new ThreadID(0); 669 LockID lid0 = new LockID("0"); 670 671 lockManager.lock(lid0, tid0, LockLevel.READ); 672 assertEquals(1, rmtLockManager.getLockRequestCount()); 673 674 lockManager.lock(lid0, tid0, LockLevel.WRITE); 676 assertEquals(2, rmtLockManager.getLockRequestCount()); 677 678 lockManager.lock(lid0, tid0, LockLevel.WRITE); 680 assertEquals(2, rmtLockManager.getLockRequestCount()); 681 lockManager.lock(lid0, tid0, LockLevel.READ); 682 assertEquals(2, rmtLockManager.getLockRequestCount()); 683 } 684 685 public void testLockUpgradeMakesRemoteRequest() throws Exception { 686 assertEquals(0, rmtLockManager.getLockRequestCount()); 687 ThreadID tid0 = new ThreadID(0); 688 LockID lid0 = new LockID("0"); 689 690 lockManager.lock(lid0, tid0, LockLevel.READ); 691 assertEquals(1, rmtLockManager.getLockRequestCount()); 692 693 lockManager.lock(lid0, tid0, LockLevel.WRITE); 695 assertEquals(2, rmtLockManager.getLockRequestCount()); 696 } 697 698 public void testNestedReadLocksGrantsLocally() throws Exception { 699 assertEquals(0, rmtLockManager.getLockRequestCount()); 700 ThreadID tid0 = new ThreadID(0); 701 LockID lid0 = new LockID("0"); 702 703 lockManager.lock(lid0, tid0, LockLevel.READ); 704 assertEquals(1, rmtLockManager.getLockRequestCount()); 705 706 final int count = 25; 707 708 for (int i = 0; i < count; i++) { 709 lockManager.lock(lid0, tid0, LockLevel.READ); 711 assertEquals(1, rmtLockManager.getLockRequestCount()); 712 } 713 714 for (int i = 0; i < count; i++) { 715 lockManager.unlock(lid0, tid0); 716 assertEquals(1, rmtLockManager.getLockRequestCount()); 717 assertEquals(0, rmtLockManager.getUnlockRequestCount()); 718 } 719 720 lockManager.unlock(lid0, tid0); 721 assertEquals(1, rmtLockManager.getLockRequestCount()); 722 assertEquals(1, rmtLockManager.getUnlockRequestCount()); 723 } 724 725 public void testUnlockAfterDowngrade() throws Exception { 726 assertEquals(0, rmtLockManager.getLockRequestCount()); 727 assertEquals(0, rmtLockManager.getUnlockRequestCount()); 728 ThreadID tid0 = new ThreadID(0); 729 LockID lid0 = new LockID("0"); 730 731 lockManager.lock(lid0, tid0, LockLevel.WRITE); 732 assertEquals(1, rmtLockManager.getLockRequestCount()); 733 assertEquals(0, rmtLockManager.getUnlockRequestCount()); 734 735 lockManager.lock(lid0, tid0, LockLevel.READ); 737 assertEquals(1, rmtLockManager.getLockRequestCount()); 738 assertEquals(0, rmtLockManager.getUnlockRequestCount()); 739 740 lockManager.unlock(lid0, tid0); 741 assertEquals(1, rmtLockManager.getLockRequestCount()); 742 assertEquals(0, rmtLockManager.getUnlockRequestCount()); 743 744 lockManager.unlock(lid0, tid0); 745 assertEquals(1, rmtLockManager.getLockRequestCount()); 746 assertEquals(1, rmtLockManager.getUnlockRequestCount()); 747 } 748 749 private void pauseAndStart() { 750 lockManager.pause(); 751 lockManager.starting(); 752 } 753 754 public static void main(String [] args) { 755 } 757 758 public class LockWaiter extends Thread implements WaitListener { 759 private final LockID lid; 760 761 private final ThreadID tid; 762 763 private final WaitInvocation call; 764 765 private final NoExceptionLinkedQueue preWaitSignalQueue; 766 767 private final Object waitObject; 768 769 private final List exceptions = new LinkedList (); 770 771 private LockWaiter(NoExceptionLinkedQueue preWaitSignalQueue, WaitLockRequest request, Object waitObject) { 772 this(preWaitSignalQueue, request.lockID(), request.threadID(), request.getWaitInvocation(), waitObject); 773 } 774 775 private LockWaiter(NoExceptionLinkedQueue preWaitSignalQueue, LockID lid, ThreadID threadID, WaitInvocation call, 776 Object waitObject) { 777 this.preWaitSignalQueue = preWaitSignalQueue; 778 this.lid = lid; 779 this.tid = threadID; 780 this.waitObject = waitObject; 781 this.call = call; 782 } 783 784 public void run() { 785 try { 786 lockManager.wait(lid, tid, call, waitObject, this); 787 } catch (Throwable t) { 788 exceptions.add(t); 789 } 790 } 791 792 public void handleWaitEvent() { 793 preWaitSignalQueue.put(new Object ()); 794 } 795 796 public Collection getExceptions() { 797 return this.exceptions; 798 } 799 } 800 801 private class LockGetter extends Thread { 802 LockID lid; 803 ThreadID tid; 804 int lockType; 805 806 private LockGetter(LockID lid, ThreadID tid, int lockType) { 807 this.lid = lid; 808 this.tid = tid; 809 this.lockType = lockType; 810 } 811 812 public void run() { 813 lockManager.lock(lid, tid, lockType); 814 } 815 } 816 } 817 | Popular Tags |