1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.transaction.locking;
18
19 import java.io.PrintWriter;
20
21 import junit.framework.Test;
22 import junit.framework.TestCase;
23 import junit.framework.TestSuite;
24
25 import org.apache.commons.transaction.util.LoggerFacade;
26 import org.apache.commons.transaction.util.PrintWriterLogger;
27 import org.apache.commons.transaction.util.RendezvousBarrier;
28 import org.apache.commons.transaction.util.TurnBarrier;
29
30
31
32
33
34
35 public class GenericLockTest extends TestCase {
36
37 private static final LoggerFacade sLogger = new PrintWriterLogger(new PrintWriter(System.out),
38 GenericLockTest.class.getName(), false);
39
40 protected static final int READ_LOCK = 1;
41 protected static final int WRITE_LOCK = 2;
42
43 private static final int CONCURRENT_TESTS = 25;
44
45 protected static final long TIMEOUT = 1000000;
46
47 private static int deadlockCnt = 0;
48 private static String first = null;
49
50 public static Test suite() {
51 TestSuite suite = new TestSuite(GenericLockTest.class);
52 return suite;
53 }
54
55 public static void main(java.lang.String[] args) {
56 junit.textui.TestRunner.run(suite());
57 }
58
59 public GenericLockTest(String testName) {
60 super(testName);
61 }
62
63
64 protected boolean acquireNoWait(GenericLock lock, String owner, int targetLockLevel) {
65 try {
66 return lock.acquire(owner, targetLockLevel, false, true, -1);
67 } catch (InterruptedException e) {
68 return false;
69 }
70 }
71
72 public void testBasic() throws Throwable {
73
74 sLogger.logInfo("\n\nChecking basic map features\n\n");
75
76 String owner1 = "owner1";
77 String owner2 = "owner2";
78 String owner3 = "owner3";
79
80
81 GenericLock lock = new GenericLock("Test read write lock", WRITE_LOCK, sLogger);
82
83
84 boolean canRead1 = acquireNoWait(lock, owner1, READ_LOCK);
85 assertTrue(canRead1);
86 boolean canRead2 = acquireNoWait(lock, owner2, READ_LOCK);
87 assertTrue(canRead2);
88
89
90 boolean canWrite3 = acquireNoWait(lock, owner3, WRITE_LOCK);
91 assertFalse(canWrite3);
92
93
94 lock.release(owner2);
95
96 canWrite3 = acquireNoWait(lock, owner3, WRITE_LOCK);
97 assertFalse(canWrite3);
98
99
100 lock.release(owner1);
101
102 canWrite3 = acquireNoWait(lock, owner3, WRITE_LOCK);
103 assertTrue(canWrite3);
104
105 canRead2 = acquireNoWait(lock, owner2, READ_LOCK);
106 assertFalse(canRead2);
107
108
109 lock.release(owner3);
110 canRead2 = acquireNoWait(lock, owner2, READ_LOCK);
111 assertTrue(canRead2);
112
113
114 boolean canBlock3 = lock.acquire(owner3, WRITE_LOCK, false, GenericLock.COMPATIBILITY_SUPPORT, -1);
115
116 assertFalse(canBlock3);
117
118
119 lock.release(owner2);
120 canBlock3 = lock.acquire(owner3, WRITE_LOCK, false, GenericLock.COMPATIBILITY_SUPPORT, -1);
121
122 assertTrue(canBlock3);
123
124
125 canRead1 = acquireNoWait(lock, owner1, READ_LOCK);
126 assertFalse(canRead1);
127
128
129
130
131 boolean canBlock2 = lock.acquire(owner2, WRITE_LOCK, false, GenericLock.COMPATIBILITY_SUPPORT, -1);
132 assertTrue(canBlock2);
133
134
135
136 lock.release(owner3);
137 canRead1 = acquireNoWait(lock, owner1, READ_LOCK);
138 assertFalse(canRead1);
139
140
141 lock.release(owner2);
142 canRead1 = acquireNoWait(lock, owner1, READ_LOCK);
143 assertTrue(canRead1);
144 }
145
146 public void testTimeout() {
147
148 sLogger.logInfo("\n\nChecking timeouts\n\n");
149
150 ReadWriteLockManager lockManager = new ReadWriteLockManager(sLogger, 1000);
151 boolean timedOut = false;
152 try {
153 lockManager.readLock("owner1", "resource");
154 lockManager.writeLock("owner2", "resource");
155 } catch (LockException le) {
156 assertEquals(le.getCode(), LockException.CODE_TIMED_OUT);
157 timedOut = true;
158 }
159 assertTrue(timedOut);
160 lockManager = new ReadWriteLockManager(sLogger, 100);
161 timedOut = false;
162 try {
163 lockManager.readLock("owner1", "resource");
164 lockManager.writeLock("owner2", "resource");
165 } catch (LockException le) {
166 assertEquals(le.getCode(), LockException.CODE_TIMED_OUT);
167 timedOut = true;
168 }
169 assertTrue(timedOut);
170 lockManager = new ReadWriteLockManager(sLogger, 0);
171 timedOut = false;
172 try {
173 lockManager.readLock("owner1", "resource");
174 lockManager.writeLock("owner2", "resource");
175 } catch (LockException le) {
176 assertEquals(le.getCode(), LockException.CODE_TIMED_OUT);
177 timedOut = true;
178 }
179 assertTrue(timedOut);
180 }
181
182
183 public void testDeadlock() throws Throwable {
184
185 sLogger.logInfo("\n\nChecking deadlock detection\n\n");
186
187 final String owner1 = "owner1";
188 final String owner2 = "owner2";
189
190 final String res1 = "res1";
191 final String res2 = "res2";
192
193
194 final ReadWriteLockManager manager = new ReadWriteLockManager(sLogger, TIMEOUT);
195
196 final RendezvousBarrier restart = new RendezvousBarrier("restart",
197 TIMEOUT, sLogger);
198
199 for (int i = 0; i < CONCURRENT_TESTS; i++) {
200
201 System.out.print(".");
202
203 final RendezvousBarrier deadlockBarrier1 = new RendezvousBarrier("deadlock1" + i,
204 TIMEOUT, sLogger);
205
206 Thread deadlock = new Thread(new Runnable() {
207 public void run() {
208 try {
209
210 manager.writeLock(owner2, res2);
211 synchronized (deadlockBarrier1) {
212 deadlockBarrier1.meet();
213 deadlockBarrier1.reset();
214 }
215
216
217 manager.writeLock(owner2, res1);
218 } catch (LockException le) {
219 assertEquals(le.getCode(), LockException.CODE_DEADLOCK_VICTIM);
220 deadlockCnt++;
221 } catch (InterruptedException ie) {
222 } finally {
223 manager.releaseAll(owner2);
224 try {
225 synchronized (restart) {
226 restart.meet();
227 restart.reset();
228 }
229 } catch (InterruptedException ie) {}
230 }
231 }
232 }, "Deadlock Thread");
233
234 deadlock.start();
235
236 try {
237
238 manager.readLock(owner1, res1);
239 synchronized (deadlockBarrier1) {
240 deadlockBarrier1.meet();
241 deadlockBarrier1.reset();
242 }
243
244
245 manager.readLock(owner1, res2);
246 } catch (LockException le) {
247 assertEquals(le.getCode(), LockException.CODE_DEADLOCK_VICTIM);
248 deadlockCnt++;
249 } finally {
250 manager.releaseAll(owner1);
251 synchronized (restart) {
252 restart.meet();
253 restart.reset();
254 }
255 }
256
257
258
259 if (deadlockCnt != 1) {
260 sLogger.logWarning("More than one thread was deadlock victim!");
261 }
262 assertTrue(deadlockCnt >= 1);
263 deadlockCnt = 0;
264 }
265 }
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291 public void testIndirectDeadlock() throws Throwable {
292
293 sLogger.logInfo("\n\nChecking detection of indirect deadlock \n\n");
294
295 final String jamowner1 = "jamowner1";
296 final String jamowner2 = "jamowner2";
297
298 final String owner1 = "owner1";
299 final String owner2 = "owner2";
300 final String owner3 = "owner3";
301
302 final String res1 = "res1";
303 final String res2 = "res2";
304 final String res3 = "res3";
305
306
307 final ReadWriteLockManager manager = new ReadWriteLockManager(sLogger,
308 TIMEOUT);
309
310 final RendezvousBarrier restart = new RendezvousBarrier("restart", 5, TIMEOUT, sLogger);
311
312 final TurnBarrier cb = new TurnBarrier("cb1", TIMEOUT, sLogger, 1);
313
314 for (int i = 0; i < CONCURRENT_TESTS; i++) {
315
316 System.out.print(".");
317
318
319
320 Thread jamThread1 = new Thread(new Runnable() {
321 public void run() {
322 try {
323 for (int i = 0; i < 10; i++) {
324 manager.readLock(jamowner1, res1);
325 Thread.sleep(10);
326 manager.releaseAll(jamowner1);
327 Thread.sleep(10);
328 manager.writeLock(jamowner1, res1);
329 Thread.sleep(10);
330 manager.releaseAll(jamowner1);
331 Thread.sleep(10);
332 }
333 } catch (LockException le) {
334 fail("Jam Thread should not fail");
335 } catch (InterruptedException ie) {
336 } finally {
337 manager.releaseAll(jamowner1);
338 synchronized (restart) {
339 try {
340 synchronized (restart) {
341 restart.meet();
342 restart.reset();
343 }
344 } catch (InterruptedException ie) {}
345 }
346 }
347 }
348 }, "Jam Thread #1");
349
350 jamThread1.start();
351
352
353
354 Thread jamThread2 = new Thread(new Runnable() {
355 public void run() {
356 try {
357 for (int i = 0; i < 10; i++) {
358 manager.writeLock(jamowner2, res1);
359 Thread.sleep(10);
360 manager.releaseAll(jamowner2);
361 Thread.sleep(10);
362 manager.readLock(jamowner2, res1);
363 Thread.sleep(10);
364 manager.releaseAll(jamowner2);
365 Thread.sleep(10);
366 }
367 } catch (LockException le) {
368 fail("Jam Thread should not fail");
369 } catch (InterruptedException ie) {
370 } finally {
371 manager.releaseAll(jamowner2);
372 synchronized (restart) {
373 try {
374 synchronized (restart) {
375 restart.meet();
376 restart.reset();
377 }
378 } catch (InterruptedException ie) {}
379 }
380 }
381 }
382 }, "Jam Thread #2");
383
384 jamThread2.start();
385
386 Thread t1 = new Thread(new Runnable() {
387 public void run() {
388 try {
389 cb.waitForTurn(2);
390 manager.readLock(owner2, res2);
391 cb.signalTurn(3);
392 cb.waitForTurn(5);
393 synchronized (manager.getLock(res1)) {
394 cb.signalTurn(6);
395 manager.writeLock(owner2, res1);
396 }
397 } catch (LockException le) {
398 assertEquals(le.getCode(), LockException.CODE_DEADLOCK_VICTIM);
399 deadlockCnt++;
400 } catch (InterruptedException ie) {
401 } finally {
402 manager.releaseAll(owner2);
403 synchronized (restart) {
404 try {
405 synchronized (restart) {
406 restart.meet();
407 restart.reset();
408 }
409 } catch (InterruptedException ie) {}
410 }
411 }
412 }
413 }, "Thread #1");
414
415 t1.start();
416
417 Thread t2 = new Thread(new Runnable() {
418 public void run() {
419 try {
420 cb.waitForTurn(3);
421 manager.readLock(owner3, res3);
422 synchronized (manager.getLock(res2)) {
423 cb.signalTurn(5);
424 manager.writeLock(owner3, res2);
425 }
426 } catch (LockException le) {
427 assertEquals(le.getCode(), LockException.CODE_DEADLOCK_VICTIM);
428 deadlockCnt++;
429 } catch (InterruptedException ie) {
430 } finally {
431 manager.releaseAll(owner3);
432 synchronized (restart) {
433 try {
434 synchronized (restart) {
435 restart.meet();
436 restart.reset();
437 }
438 } catch (InterruptedException ie) {}
439 }
440 }
441 }
442 }, "Thread #2");
443
444 t2.start();
445
446 try {
447 cb.waitForTurn(1);
448 manager.readLock(owner1, res1);
449 cb.signalTurn(2);
450 cb.waitForTurn(6);
451 manager.writeLock(owner1, res3);
452 } catch (LockException le) {
453 assertEquals(le.getCode(), LockException.CODE_DEADLOCK_VICTIM);
454 deadlockCnt++;
455 } catch (InterruptedException ie) {
456 } finally {
457 manager.releaseAll(owner1);
458 synchronized (restart) {
459 try {
460 synchronized (restart) {
461 restart.meet();
462 restart.reset();
463 }
464 } catch (InterruptedException ie) {
465 }
466 }
467 }
468
469
470
471 if (deadlockCnt != 1) {
472 sLogger.logWarning("\nMore than one thread was deadlock victim!\n");
473 }
474 assertTrue(deadlockCnt >= 1);
475 deadlockCnt = 0;
476 cb.reset();
477 }
478 }
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503 public void testUpgrade() throws Throwable {
504
505 sLogger.logInfo("\n\nChecking upgrade and preference lock\n\n");
506
507 final String owner1 = "owner1";
508 final String owner2 = "owner2";
509 final String owner3 = "owner3";
510
511 final String res1 = "res1";
512
513
514 final ReadWriteUpgradeLockManager manager = new ReadWriteUpgradeLockManager(sLogger,
515 TIMEOUT);
516
517 final RendezvousBarrier restart = new RendezvousBarrier("restart", 3, TIMEOUT, sLogger);
518
519 final TurnBarrier cb = new TurnBarrier("cb1", TIMEOUT, sLogger, 1);
520
521 for (int i = 0; i < CONCURRENT_TESTS; i++) {
522
523 System.out.print(".");
524
525 Thread t1 = new Thread(new Runnable() {
526 public void run() {
527 try {
528 cb.waitForTurn(2);
529 manager.upgradeLock(owner2, res1);
530 cb.signalTurn(3);
531 cb.waitForTurn(5);
532 synchronized (manager.getLock(res1)) {
533 cb.signalTurn(6);
534 manager.writeLock(owner2, res1);
535 }
536
537
538
539 synchronized (this) {
540 if (first == null)
541 first = owner2;
542 }
543 manager.releaseAll(owner2);
544 synchronized (restart) {
545 restart.meet();
546 restart.reset();
547 }
548 } catch (InterruptedException ie) {
549 }
550 }
551 }, "Thread #1");
552
553 t1.start();
554
555 Thread t2 = new Thread(new Runnable() {
556 public void run() {
557 try {
558
559
560
561
562
563
564 cb.waitForTurn(6);
565 synchronized (manager.getLock(res1)) {
566 cb.signalTurn(7);
567 manager.readLock(owner3, res1);
568 }
569 synchronized (this) {
570 if (first == null)
571 first = owner3;
572 }
573 manager.releaseAll(owner3);
574 synchronized (restart) {
575 restart.meet();
576 restart.reset();
577 }
578 } catch (InterruptedException ie) {
579 }
580 }
581 }, "Thread #2");
582
583 t2.start();
584
585 cb.waitForTurn(1);
586 manager.readLock(owner1, res1);
587 cb.signalTurn(2);
588 cb.waitForTurn(3);
589 manager.release(owner1, res1);
590 manager.readLock(owner1, res1);
591 cb.signalTurn(5);
592 cb.waitForTurn(7);
593 synchronized (manager.getLock(res1)) {
594 manager.releaseAll(owner1);
595 }
596 synchronized (restart) {
597 restart.meet();
598 restart.reset();
599 }
600
601 assertEquals(first, owner2);
602 first = null;
603 cb.reset();
604 }
605
606 }
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634 public void testPreference() throws Throwable {
635
636 sLogger.logInfo("\n\nChecking incompatible preference locks\n\n");
637
638 final String owner1 = "owner1";
639 final String owner2 = "owner2";
640 final String owner3 = "owner3";
641
642 final String res1 = "res1";
643
644 final ReadWriteLock lock = new ReadWriteLock(res1, sLogger);
645
646 final RendezvousBarrier restart = new RendezvousBarrier("restart", 3, TIMEOUT, sLogger);
647
648 final TurnBarrier cb = new TurnBarrier("cb1", TIMEOUT, sLogger, 1);
649
650 for (int i = 0; i < CONCURRENT_TESTS; i++) {
651
652 System.out.print(".");
653
654 Thread t1 = new Thread(new Runnable() {
655 public void run() {
656 try {
657 cb.waitForTurn(2);
658 synchronized (lock) {
659 cb.signalTurn(3);
660 lock.acquire(owner2, ReadWriteLock.WRITE_LOCK, true,
661 GenericLock.COMPATIBILITY_REENTRANT, true, TIMEOUT);
662 }
663 lock.release(owner2);
664 synchronized (restart) {
665 restart.meet();
666 restart.reset();
667 }
668 } catch (InterruptedException ie) {
669 }
670 }
671 }, "Thread #1");
672
673 t1.start();
674
675 Thread t2 = new Thread(new Runnable() {
676 public void run() {
677 try {
678 cb.waitForTurn(3);
679 synchronized (lock) {
680 cb.signalTurn(4);
681 lock.acquire(owner3, ReadWriteLock.WRITE_LOCK, true,
682 GenericLock.COMPATIBILITY_REENTRANT, true, TIMEOUT);
683 }
684 lock.release(owner3);
685 synchronized (restart) {
686 restart.meet();
687 restart.reset();
688 }
689 } catch (InterruptedException ie) {
690 }
691 }
692 }, "Thread #2");
693
694 t2.start();
695
696 cb.waitForTurn(1);
697 lock.acquireRead(owner1, TIMEOUT);
698 cb.signalTurn(2);
699 cb.waitForTurn(4);
700 synchronized (lock) {
701 lock.release(owner1);
702 }
703 synchronized (restart) {
704 restart.meet();
705 restart.reset();
706 }
707
708 cb.reset();
709 }
710
711 }
712
713 public void testGlobalTimeout() throws Throwable {
714
715 sLogger.logInfo("\n\nChecking global timeouts\n\n");
716
717 final String owner1 = "owner1";
718 final String owner2 = "owner2";
719
720 final String res1 = "res1";
721
722 final GenericLockManager manager = new GenericLockManager(1, sLogger, TIMEOUT, -1);
723
724 final RendezvousBarrier restart = new RendezvousBarrier("restart", 2, TIMEOUT, sLogger);
725
726 final TurnBarrier cb = new TurnBarrier("cb1", TIMEOUT, sLogger, 1);
727
728 for (int i = 0; i < CONCURRENT_TESTS; i++) {
729
730 System.out.print(".");
731
732 Thread t1 = new Thread(new Runnable() {
733 public void run() {
734 try {
735 cb.waitForTurn(2);
736 manager.lock(owner2, res1, 1, true);
737 cb.signalTurn(3);
738 manager.releaseAll(owner2);
739 synchronized (restart) {
740 restart.meet();
741 restart.reset();
742 }
743 } catch (InterruptedException ie) {
744 }
745 }
746 }, "Thread #1");
747
748 t1.start();
749
750 cb.waitForTurn(1);
751 manager.startGlobalTimeout(owner1, 500);
752 manager.lock(owner1, res1, 1, true);
753 cb.signalTurn(2);
754 cb.waitForTurn(3);
755 boolean failed = false;
756 try {
757 manager.tryLock(owner1, res1, 1, true);
758 } catch (LockException le) {
759 failed = true;
760 }
761 assertTrue(failed);
762 manager.releaseAll(owner1);
763 failed = false;
764 try {
765 manager.tryLock(owner1, res1, 1, true);
766 } catch (LockException le) {
767 failed = true;
768 }
769 assertFalse(failed);
770 manager.releaseAll(owner1);
771 synchronized (restart) {
772 restart.meet();
773 restart.reset();
774 }
775
776 cb.reset();
777 }
778
779 }
780
781 public void testStress() throws Throwable {
782
783 sLogger.logInfo("\n\nStress checking locks\n\n");
784
785 final String owner1 = "owner1";
786 final String owner2 = "owner2";
787 final String owner3 = "owner3";
788 final String owner4 = "owner4";
789 final String owner5 = "owner5";
790 final String owner6 = "owner6";
791 final String owner7 = "owner7";
792 final String owner8 = "owner8";
793 final String owner9 = "owner9";
794 final String owner10 = "owner10";
795
796 final String res1 = "res1";
797 final String res2 = "res2";
798 final String res3 = "res3";
799
800
801 final ReadWriteUpgradeLockManager manager = new ReadWriteUpgradeLockManager(sLogger, 100);
802
803 final RendezvousBarrier restart = new RendezvousBarrier("restart", 5, TIMEOUT, sLogger);
804 final RendezvousBarrier start = new RendezvousBarrier("start", 5, TIMEOUT, sLogger);
805
806 for (int i = 0; i < CONCURRENT_TESTS; i++) {
807
808 System.out.print(".");
809
810 Thread t1 = new Thread(new Runnable() {
811 public void run() {
812 try {
813 try {
814 synchronized (start) {
815 start.meet();
816 start.reset();
817 }
818 manager.readLock(owner1, res1);
819 manager.readLock(owner1, res2);
820 manager.upgradeLock(owner1, res3);
821 manager.writeLock(owner1, res3);
822 } catch (LockException ie) {
823 } finally {
824 manager.releaseAll(owner1);
825 synchronized (restart) {
826 restart.meet();
827 restart.reset();
828 }
829 }
830 } catch (InterruptedException ie) {
831 }
832 }
833 }, "Thread #1");
834 t1.start();
835
836 Thread t2 = new Thread(new Runnable() {
837 public void run() {
838 try {
839 try {
840 synchronized (start) {
841 start.meet();
842 start.reset();
843 }
844 manager.readLock(owner2, res1);
845 manager.readLock(owner2, res2);
846 manager.upgradeLock(owner2, res3);
847 manager.writeLock(owner2, res3);
848 } catch (LockException ie) {
849 } finally {
850 manager.releaseAll(owner2);
851 synchronized (restart) {
852 restart.meet();
853 restart.reset();
854 }
855 }
856 } catch (InterruptedException ie) {
857 }
858 }
859 }, "Thread #2");
860 t2.start();
861
862 Thread t3 = new Thread(new Runnable() {
863 public void run() {
864 try {
865 try {
866 synchronized (start) {
867 start.meet();
868 start.reset();
869 }
870 manager.readLock(owner3, res1);
871 manager.readLock(owner3, res2);
872 manager.upgradeLock(owner3, res3);
873 manager.writeLock(owner3, res3);
874 } catch (LockException ie) {
875 } finally {
876 manager.releaseAll(owner3);
877 synchronized (restart) {
878 restart.meet();
879 restart.reset();
880 }
881 }
882 } catch (InterruptedException ie) {
883 }
884 }
885 }, "Thread #3");
886 t3.start();
887
888 Thread t4 = new Thread(new Runnable() {
889 public void run() {
890 try {
891 try {
892 synchronized (start) {
893 start.meet();
894 start.reset();
895 }
896 manager.readLock(owner4, res1);
897 manager.readLock(owner4, res2);
898 manager.upgradeLock(owner4, res3);
899 manager.writeLock(owner4, res3);
900 } catch (LockException ie) {
901 } finally {
902 manager.releaseAll(owner4);
903 synchronized (restart) {
904 restart.meet();
905 restart.reset();
906 }
907 }
908 } catch (InterruptedException ie) {
909 }
910 }
911 }, "Thread #4");
912 t4.start();
913
914 try {
915 try {
916 synchronized (start) {
917 start.meet();
918 start.reset();
919 }
920 manager.readLock("reader", res1);
921 manager.readLock("reader", res2);
922 manager.readLock("reader", res3);
923
924 } catch (LockException ie) {
925 } finally {
926 manager.releaseAll("reader");
927 try {
928 synchronized (restart) {
929 restart.meet();
930 restart.reset();
931 }
932 } catch (InterruptedException ie) {
933 }
934 }
935 } catch (InterruptedException ie) {
936 }
937 }
938
939 }
940
941 public void testChaos() throws Throwable {
942
943 sLogger.logInfo("\n\nChaos testing locks for internal deadlocks resp. concurrent mods\n\n");
944
945 final String owner1 = "owner1";
946 final String owner2 = "owner2";
947 final String owner3 = "owner3";
948 final String owner4 = "owner4";
949 final String owner5 = "owner5";
950 final String owner6 = "owner6";
951 final String owner7 = "owner7";
952 final String owner8 = "owner8";
953 final String owner9 = "owner9";
954 final String owner10 = "owner10";
955
956 final String res1 = "res1";
957 final String res2 = "res2";
958 final String res3 = "res3";
959
960
961 final ReadWriteUpgradeLockManager manager = new ReadWriteUpgradeLockManager(sLogger, 100);
962
963 int concurrentThreads = 7;
964 int threads = CONCURRENT_TESTS * concurrentThreads;
965
966 final RendezvousBarrier end = new RendezvousBarrier("end", threads + 1, TIMEOUT, sLogger);
967
968 sLogger.logInfo("\n\nStarting "+threads+" threads\n\n");
969
970 for (int i = 0; i < CONCURRENT_TESTS; i++) {
971
972 final int cnt = i;
973
974 System.out.print(".");
975
976 Thread t1 = new Thread(new Runnable() {
977 public void run() {
978 try {
979 manager.readLock(owner1, res1);
980 manager.readLock(owner1, res2);
981 manager.upgradeLock(owner1, res3);
982 manager.writeLock(owner1, res3);
983 } catch (LockException ie) {
984 System.out.print("-");
985 } finally {
986 manager.releaseAll(owner1);
987 end.call();
988 }
989 }
990 }, "Thread #1");
991
992 Thread t2 = new Thread(new Runnable() {
993 public void run() {
994 try {
995 manager.readLock(owner2, res1);
996 manager.readLock(owner2, res2);
997 manager.upgradeLock(owner2, res3);
998 manager.writeLock(owner2, res3);
999 } catch (LockException ie) {
1000 System.out.print("-");
1001 } finally {
1002 manager.releaseAll(owner2);
1003 end.call();
1004 }
1005 }
1006 }, "Thread #2");
1007
1008 Thread t3 = new Thread(new Runnable() {
1009 public void run() {
1010 try {
1011 manager.startGlobalTimeout(owner3, 10 + cnt);
1012 manager.readLock(owner3, res1);
1013 manager.readLock(owner3, res2);
1014 manager.upgradeLock(owner3, res3);
1015 manager.writeLock(owner3, res3);
1016 } catch (LockException le) {
1017 if (le.getCode() == LockException.CODE_TIMED_OUT) {
1018 System.out.print("*");
1019 } else {
1020 System.out.print("-");
1021 }
1022 } finally {
1023 manager.releaseAll(owner3);
1024 end.call();
1025 }
1026 }
1027 }, "Thread #3");
1028
1029 Thread t4 = new Thread(new Runnable() {
1030 public void run() {
1031 try {
1032 manager.readLock(owner4, res1);
1033 manager.readLock(owner4, res2);
1034 manager.upgradeLock(owner4, res3);
1035 manager.writeLock(owner4, res3);
1036 } catch (LockException le) {
1037 System.out.print("-");
1038 } finally {
1039 manager.releaseAll(owner4);
1040 end.call();
1041 }
1042 }
1043 }, "Thread #4");
1044
1045 Thread deadlock1 = new Thread(new Runnable() {
1046 public void run() {
1047 try {
1048 manager.writeLock(owner5, res2);
1049 manager.writeLock(owner5, res1);
1050 } catch (LockException le) {
1051 assertEquals(le.getCode(), LockException.CODE_DEADLOCK_VICTIM);
1052 System.out.print("-");
1053 } finally {
1054 manager.releaseAll(owner5);
1055 end.call();
1056 }
1057 }
1058 }, "Deadlock1 Thread");
1059
1060 Thread deadlock2 = new Thread(new Runnable() {
1061 public void run() {
1062 try {
1063 manager.readLock(owner6, res1);
1064 manager.readLock(owner6, res2);
1065 } catch (LockException le) {
1066 assertEquals(le.getCode(), LockException.CODE_DEADLOCK_VICTIM);
1067 System.out.print("-");
1068 } finally {
1069 manager.releaseAll(owner6);
1070 end.call();
1071 }
1072 }
1073 }, "Deadlock1 Thread");
1074
1075 Thread reader = new Thread(new Runnable() {
1076 public void run() {
1077 try {
1078 manager.readLock("reader", res1);
1079 manager.readLock("reader", res2);
1080 manager.readLock("reader", res3);
1081 } catch (LockException ie) {
1082 System.out.print("-");
1083 } finally {
1084 manager.releaseAll("reader");
1085 end.call();
1086 }
1087 }
1088 }, "Reader Thread");
1089
1090
1091 t4.start();
1092 t3.start();
1093 reader.start();
1094 t1.start();
1095 deadlock2.start();
1096 t2.start();
1097 deadlock1.start();
1098 }
1099
1100 end.meet();
1101
1102 }
1103 }