KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > commons > transaction > locking > GenericLockTest


1 /*
2  * $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//transaction/src/test/org/apache/commons/transaction/locking/GenericLockTest.java,v 1.12 2005/01/13 16:44:03 ozeigermann Exp $
3  * $Revision$
4  * $Date: 2005-02-26 14:16:14 +0100 (Sa, 26 Feb 2005) $
5  *
6  * ====================================================================
7  *
8  * Copyright 2004 The Apache Software Foundation
9  *
10  * Licensed under the Apache License, Version 2.0 (the "License");
11  * you may not use this file except in compliance with the License.
12  * You may obtain a copy of the License at
13  *
14  * http://www.apache.org/licenses/LICENSE-2.0
15  *
16  * Unless required by applicable law or agreed to in writing, software
17  * distributed under the License is distributed on an "AS IS" BASIS,
18  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19  * See the License for the specific language governing permissions and
20  * limitations under the License.
21  *
22  */

23
24 package org.apache.commons.transaction.locking;
25
26 import java.io.PrintWriter JavaDoc;
27
28 import junit.framework.Test;
29 import junit.framework.TestCase;
30 import junit.framework.TestSuite;
31
32 import org.apache.commons.transaction.util.LoggerFacade;
33 import org.apache.commons.transaction.util.PrintWriterLogger;
34 import org.apache.commons.transaction.util.RendezvousBarrier;
35 import org.apache.commons.transaction.util.TurnBarrier;
36
37 /**
38  * Tests for generic locks.
39  *
40  * @version $Revision$
41  */

42 public class GenericLockTest extends TestCase {
43
44     private static final LoggerFacade sLogger = new PrintWriterLogger(new PrintWriter JavaDoc(System.out),
45             GenericLockTest.class.getName(), false);
46
47     protected static final int READ_LOCK = 1;
48     protected static final int WRITE_LOCK = 2;
49     
50     private static final int CONCURRENT_TESTS = 25;
51     
52     protected static final long TIMEOUT = 1000000;
53     
54     private static int deadlockCnt = 0;
55     private static String JavaDoc first = null;
56
57     public static Test suite() {
58         TestSuite suite = new TestSuite(GenericLockTest.class);
59         return suite;
60     }
61
62     public static void main(java.lang.String JavaDoc[] args) {
63         junit.textui.TestRunner.run(suite());
64     }
65
66     public GenericLockTest(String JavaDoc testName) {
67         super(testName);
68     }
69
70     // we do not wait, as we only want the check the results and do not want real locking
71
protected boolean acquireNoWait(GenericLock lock, String JavaDoc owner, int targetLockLevel) {
72         try {
73             return lock.acquire(owner, targetLockLevel, false, true, -1);
74         } catch (InterruptedException JavaDoc e) {
75             return false;
76         }
77     }
78
79     public void testBasic() throws Throwable JavaDoc {
80
81         sLogger.logInfo("\n\nChecking basic map features\n\n");
82
83         String JavaDoc owner1 = "owner1";
84         String JavaDoc owner2 = "owner2";
85         String JavaDoc owner3 = "owner3";
86         
87         // a read / write lock
88
GenericLock lock = new GenericLock("Test read write lock", WRITE_LOCK, sLogger);
89         
90         // of course more than one can read
91
boolean canRead1 = acquireNoWait(lock, owner1, READ_LOCK);
92         assertTrue(canRead1);
93         boolean canRead2 = acquireNoWait(lock, owner2, READ_LOCK);
94         assertTrue(canRead2);
95         
96         // as there already are read locks, this write should not be possible
97
boolean canWrite3 = acquireNoWait(lock, owner3, WRITE_LOCK);
98         assertFalse(canWrite3);
99         
100         // release one read lock
101
lock.release(owner2);
102         // this should not change anything with the write as there is still one read lock left
103
canWrite3 = acquireNoWait(lock, owner3, WRITE_LOCK);
104         assertFalse(canWrite3);
105
106         // release the other and final read lock as well
107
lock.release(owner1);
108         // no we should be able to get write access
109
canWrite3 = acquireNoWait(lock, owner3, WRITE_LOCK);
110         assertTrue(canWrite3);
111         // but of course no more read access
112
canRead2 = acquireNoWait(lock, owner2, READ_LOCK);
113         assertFalse(canRead2);
114         
115         // relase the write lock and make sure we can read again
116
lock.release(owner3);
117         canRead2 = acquireNoWait(lock, owner2, READ_LOCK);
118         assertTrue(canRead2);
119         
120         // now we do something weired, we try to block all locks lower than write...
121
boolean canBlock3 = lock.acquire(owner3, WRITE_LOCK, false, GenericLock.COMPATIBILITY_SUPPORT, -1);
122         // which of course does not work, as there already is an incompatible read lock
123
assertFalse(canBlock3);
124         
125         // ok, release read lock (no we have no more locks) and try again
126
lock.release(owner2);
127         canBlock3 = lock.acquire(owner3, WRITE_LOCK, false, GenericLock.COMPATIBILITY_SUPPORT, -1);
128         // which now should work creating an ordinary lock
129
assertTrue(canBlock3);
130         
131         // as this just an ordinary lock, we should not get a read lock:
132
canRead1 = acquireNoWait(lock, owner1, READ_LOCK);
133         assertFalse(canRead1);
134         
135         // this is the trick now, we *can* get an addtional write lock with this request as it has
136
// the same level as the write lock already set. This works, as we do not care for the
137
// write lock level, but only want to inhibit the read lock:
138
boolean canBlock2 = lock.acquire(owner2, WRITE_LOCK, false, GenericLock.COMPATIBILITY_SUPPORT, -1);
139         assertTrue(canBlock2);
140         
141         // now if we release one of the blocks supporting each other we still should not get a
142
// read lock
143
lock.release(owner3);
144         canRead1 = acquireNoWait(lock, owner1, READ_LOCK);
145         assertFalse(canRead1);
146
147         // but of course after we release the second as well
148
lock.release(owner2);
149         canRead1 = acquireNoWait(lock, owner1, READ_LOCK);
150         assertTrue(canRead1);
151     }
152
153     public void testTimeout() {
154         
155         sLogger.logInfo("\n\nChecking timeouts\n\n");
156
157         ReadWriteLockManager lockManager = new ReadWriteLockManager(sLogger, 1000);
158         boolean timedOut = false;
159         try {
160             lockManager.readLock("owner1", "resource");
161             lockManager.writeLock("owner2", "resource");
162         } catch (LockException le) {
163             assertEquals(le.getCode(), LockException.CODE_TIMED_OUT);
164             timedOut = true;
165         }
166         assertTrue(timedOut);
167         lockManager = new ReadWriteLockManager(sLogger, 100);
168         timedOut = false;
169         try {
170             lockManager.readLock("owner1", "resource");
171             lockManager.writeLock("owner2", "resource");
172         } catch (LockException le) {
173             assertEquals(le.getCode(), LockException.CODE_TIMED_OUT);
174             timedOut = true;
175         }
176         assertTrue(timedOut);
177         lockManager = new ReadWriteLockManager(sLogger, 0);
178         timedOut = false;
179         try {
180             lockManager.readLock("owner1", "resource");
181             lockManager.writeLock("owner2", "resource");
182         } catch (LockException le) {
183             assertEquals(le.getCode(), LockException.CODE_TIMED_OUT);
184             timedOut = true;
185         }
186         assertTrue(timedOut);
187     }
188     
189
190     public void testDeadlock() throws Throwable JavaDoc {
191
192         sLogger.logInfo("\n\nChecking deadlock detection\n\n");
193
194         final String JavaDoc owner1 = "owner1";
195         final String JavaDoc owner2 = "owner2";
196
197         final String JavaDoc res1 = "res1";
198         final String JavaDoc res2 = "res2";
199
200         // a read / write lock
201
final ReadWriteLockManager manager = new ReadWriteLockManager(sLogger, TIMEOUT);
202         
203         final RendezvousBarrier restart = new RendezvousBarrier("restart",
204                 TIMEOUT, sLogger);
205
206         for (int i = 0; i < CONCURRENT_TESTS; i++) {
207
208            System.out.print(".");
209             
210             final RendezvousBarrier deadlockBarrier1 = new RendezvousBarrier("deadlock1" + i,
211                     TIMEOUT, sLogger);
212
213             Thread JavaDoc deadlock = new Thread JavaDoc(new Runnable JavaDoc() {
214                 public void run() {
215                     try {
216                         // first both threads get a lock, this one on res2
217
manager.writeLock(owner2, res2);
218                         synchronized (deadlockBarrier1) {
219                             deadlockBarrier1.meet();
220                             deadlockBarrier1.reset();
221                         }
222                         // if I am first, the other thread will be dead, i.e.
223
// exactly one
224
manager.writeLock(owner2, res1);
225                     } catch (LockException le) {
226                         assertEquals(le.getCode(), LockException.CODE_DEADLOCK_VICTIM);
227                         deadlockCnt++;
228                     } catch (InterruptedException JavaDoc ie) {
229                     } finally {
230                         manager.releaseAll(owner2);
231                         try {
232                             synchronized (restart) {
233                                 restart.meet();
234                                 restart.reset();
235                             }
236                             } catch (InterruptedException JavaDoc ie) {}
237                     }
238                 }
239             }, "Deadlock Thread");
240
241             deadlock.start();
242
243             try {
244                 // first both threads get a lock, this one on res2
245
manager.readLock(owner1, res1);
246                 synchronized (deadlockBarrier1) {
247                     deadlockBarrier1.meet();
248                     deadlockBarrier1.reset();
249                 }
250                 // if I am first, the other thread will be dead, i.e. exactly
251
// one
252
manager.readLock(owner1, res2);
253             } catch (LockException le) {
254                 assertEquals(le.getCode(), LockException.CODE_DEADLOCK_VICTIM);
255                 deadlockCnt++;
256             } finally {
257                 manager.releaseAll(owner1);
258                 synchronized (restart) {
259                     restart.meet();
260                     restart.reset();
261                 }
262             }
263
264             // XXX in special scenarios the current implementation might cause both
265
// owners to be deadlock victims
266
if (deadlockCnt != 1) {
267                 sLogger.logWarning("More than one thread was deadlock victim!");
268             }
269             assertTrue(deadlockCnt >= 1);
270             deadlockCnt = 0;
271         }
272     }
273
274     /*
275      *
276      * Test detection of an indirect deadlock:
277      *
278      * Owner Owner Owner
279      * Step #1 #2 #3
280      * 1 read res1 (ok)
281      * 2 read res2 (ok)
282      * 3 read res3 (ok)
283      * 4 write res2 (blocked because of #2)
284      * 5 write res1
285      * (blocked
286      * because of #1)
287      * 6 write res3
288      * (blocked
289      * because #3)
290      *
291      * - Thread#1 waits for Thread#3 on res3
292      * - Thread#2 waits for Thread#1 on res1
293      * - Thread#3 waits for Thread#2 on res2
294      *
295      * This needs recursion of the deadlock detection algorithm
296      *
297      */

298     public void testIndirectDeadlock() throws Throwable JavaDoc {
299
300         sLogger.logInfo("\n\nChecking detection of indirect deadlock \n\n");
301
302         final String JavaDoc jamowner1 = "jamowner1";
303         final String JavaDoc jamowner2 = "jamowner2";
304
305         final String JavaDoc owner1 = "owner1";
306         final String JavaDoc owner2 = "owner2";
307         final String JavaDoc owner3 = "owner3";
308
309         final String JavaDoc res1 = "res1";
310         final String JavaDoc res2 = "res2";
311         final String JavaDoc res3 = "res3";
312
313         // a read / write lock
314
final ReadWriteLockManager manager = new ReadWriteLockManager(sLogger,
315                 TIMEOUT);
316
317         final RendezvousBarrier restart = new RendezvousBarrier("restart", 5, TIMEOUT, sLogger);
318
319         final TurnBarrier cb = new TurnBarrier("cb1", TIMEOUT, sLogger, 1);
320
321         for (int i = 0; i < CONCURRENT_TESTS; i++) {
322             
323             System.out.print(".");
324
325             // thread that accesses lock of res1 just to cause interference and
326
// possibly detect concurrency problems
327
Thread JavaDoc jamThread1 = new Thread JavaDoc(new Runnable JavaDoc() {
328                 public void run() {
329                     try {
330                         for (int i = 0; i < 10; i++) {
331                             manager.readLock(jamowner1, res1);
332                             Thread.sleep(10);
333                             manager.releaseAll(jamowner1);
334                             Thread.sleep(10);
335                             manager.writeLock(jamowner1, res1);
336                             Thread.sleep(10);
337                             manager.releaseAll(jamowner1);
338                             Thread.sleep(10);
339                         }
340                     } catch (LockException le) {
341                         fail("Jam Thread should not fail");
342                     } catch (InterruptedException JavaDoc ie) {
343                     } finally {
344                         manager.releaseAll(jamowner1);
345                         synchronized (restart) {
346                             try {
347                                 synchronized (restart) {
348                                     restart.meet();
349                                     restart.reset();
350                                 }
351                                 } catch (InterruptedException JavaDoc ie) {}
352                         }
353                     }
354                 }
355             }, "Jam Thread #1");
356
357             jamThread1.start();
358
359             // thread that accesses lock of res1 just to cause interference and
360
// possibly detect concurrency problems
361
Thread JavaDoc jamThread2 = new Thread JavaDoc(new Runnable JavaDoc() {
362                 public void run() {
363                     try {
364                         for (int i = 0; i < 10; i++) {
365                             manager.writeLock(jamowner2, res1);
366                             Thread.sleep(10);
367                             manager.releaseAll(jamowner2);
368                             Thread.sleep(10);
369                             manager.readLock(jamowner2, res1);
370                             Thread.sleep(10);
371                             manager.releaseAll(jamowner2);
372                             Thread.sleep(10);
373                         }
374                     } catch (LockException le) {
375                         fail("Jam Thread should not fail");
376                     } catch (InterruptedException JavaDoc ie) {
377                     } finally {
378                         manager.releaseAll(jamowner2);
379                         synchronized (restart) {
380                             try {
381                                 synchronized (restart) {
382                                     restart.meet();
383                                     restart.reset();
384                                 }
385                                 } catch (InterruptedException JavaDoc ie) {}
386                         }
387                     }
388                 }
389             }, "Jam Thread #2");
390
391             jamThread2.start();
392
393             Thread JavaDoc t1 = new Thread JavaDoc(new Runnable JavaDoc() {
394                 public void run() {
395                     try {
396                         cb.waitForTurn(2);
397                         manager.readLock(owner2, res2);
398                         cb.signalTurn(3);
399                         cb.waitForTurn(5);
400                         synchronized (manager.getLock(res1)) {
401                             cb.signalTurn(6);
402                             manager.writeLock(owner2, res1);
403                         }
404                     } catch (LockException le) {
405                         assertEquals(le.getCode(), LockException.CODE_DEADLOCK_VICTIM);
406                         deadlockCnt++;
407                     } catch (InterruptedException JavaDoc ie) {
408                     } finally {
409                         manager.releaseAll(owner2);
410                         synchronized (restart) {
411                             try {
412                                 synchronized (restart) {
413                                     restart.meet();
414                                     restart.reset();
415                                 }
416                                 } catch (InterruptedException JavaDoc ie) {}
417                         }
418                     }
419                 }
420             }, "Thread #1");
421
422             t1.start();
423
424             Thread JavaDoc t2 = new Thread JavaDoc(new Runnable JavaDoc() {
425                 public void run() {
426                     try {
427                         cb.waitForTurn(3);
428                         manager.readLock(owner3, res3);
429                         synchronized (manager.getLock(res2)) {
430                             cb.signalTurn(5);
431                             manager.writeLock(owner3, res2);
432                         }
433                     } catch (LockException le) {
434                         assertEquals(le.getCode(), LockException.CODE_DEADLOCK_VICTIM);
435                         deadlockCnt++;
436                     } catch (InterruptedException JavaDoc ie) {
437                     } finally {
438                         manager.releaseAll(owner3);
439                         synchronized (restart) {
440                             try {
441                                 synchronized (restart) {
442                                     restart.meet();
443                                     restart.reset();
444                                 }
445                                 } catch (InterruptedException JavaDoc ie) {}
446                         }
447                     }
448                 }
449             }, "Thread #2");
450
451             t2.start();
452
453             try {
454                 cb.waitForTurn(1);
455                 manager.readLock(owner1, res1);
456                 cb.signalTurn(2);
457                 cb.waitForTurn(6);
458                 manager.writeLock(owner1, res3);
459             } catch (LockException le) {
460                 assertEquals(le.getCode(), LockException.CODE_DEADLOCK_VICTIM);
461                 deadlockCnt++;
462             } catch (InterruptedException JavaDoc ie) {
463             } finally {
464                 manager.releaseAll(owner1);
465                 synchronized (restart) {
466                     try {
467                         synchronized (restart) {
468                             restart.meet();
469                             restart.reset();
470                         }
471                     } catch (InterruptedException JavaDoc ie) {
472                     }
473                 }
474             }
475
476             // XXX in special scenarios the current implementation might cause more than one
477
// owner to be a deadlock victim
478
if (deadlockCnt != 1) {
479                 sLogger.logWarning("\nMore than one thread was deadlock victim!\n");
480             }
481             assertTrue(deadlockCnt >= 1);
482             deadlockCnt = 0;
483             cb.reset();
484         }
485     }
486
487     /*
488      *
489      * Test shows the following
490      * - upgrade works with read locks no matter if they are acquired before or later (1-4)
491      * - write is blocked by read (5)
492      * - read is blocked by intention lock (6)
493      * - write lock coming from an intention lock always has preference over others (7)
494      *
495      *
496      * Owner Owner Owner
497      * Step #1 #2 #3
498      * 1 read (ok)
499      * 2 upgrade (ok)
500      * 3 release (ok)
501      * 4 read (ok)
502      * 5 write (blocked
503      * because of #1)
504      * 6 read (blocked
505      * because intention of #2)
506      * 7 release resumed
507      * 8 release resumed
508      * 9 release
509      */

510     public void testUpgrade() throws Throwable JavaDoc {
511
512         sLogger.logInfo("\n\nChecking upgrade and preference lock\n\n");
513         
514         final String JavaDoc owner1 = "owner1";
515         final String JavaDoc owner2 = "owner2";
516         final String JavaDoc owner3 = "owner3";
517
518         final String JavaDoc res1 = "res1";
519
520         // a read / write lock
521
final ReadWriteUpgradeLockManager manager = new ReadWriteUpgradeLockManager(sLogger,
522                 TIMEOUT);
523
524         final RendezvousBarrier restart = new RendezvousBarrier("restart", 3, TIMEOUT, sLogger);
525
526         final TurnBarrier cb = new TurnBarrier("cb1", TIMEOUT, sLogger, 1);
527
528         for (int i = 0; i < CONCURRENT_TESTS; i++) {
529             
530             System.out.print(".");
531
532             Thread JavaDoc t1 = new Thread JavaDoc(new Runnable JavaDoc() {
533                 public void run() {
534                     try {
535                         cb.waitForTurn(2);
536                         manager.upgradeLock(owner2, res1);
537                         cb.signalTurn(3);
538                         cb.waitForTurn(5);
539                         synchronized (manager.getLock(res1)) {
540                             cb.signalTurn(6);
541                             manager.writeLock(owner2, res1);
542                         }
543                         // we must always be first as we will be preferred over
544
// as I had the upgrade
545
// lock before
546
synchronized (this) {
547                             if (first == null)
548                                 first = owner2;
549                         }
550                         manager.releaseAll(owner2);
551                         synchronized (restart) {
552                             restart.meet();
553                             restart.reset();
554                         }
555                     } catch (InterruptedException JavaDoc ie) {
556                     }
557                 }
558             }, "Thread #1");
559
560             t1.start();
561
562             Thread JavaDoc t2 = new Thread JavaDoc(new Runnable JavaDoc() {
563                 public void run() {
564                     try {
565                         // I wait until the others are blocked
566
// when I release my single read lock, thread #1 always
567
// should be the
568
// next to get the lock as it is preferred over the main
569
// thread
570
// that only waits for a read lock
571
cb.waitForTurn(6);
572                         synchronized (manager.getLock(res1)) {
573                             cb.signalTurn(7);
574                             manager.readLock(owner3, res1);
575                         }
576                         synchronized (this) {
577                             if (first == null)
578                                 first = owner3;
579                         }
580                         manager.releaseAll(owner3);
581                         synchronized (restart) {
582                             restart.meet();
583                             restart.reset();
584                         }
585                     } catch (InterruptedException JavaDoc ie) {
586                     }
587                 }
588             }, "Thread #2");
589
590             t2.start();
591
592             cb.waitForTurn(1);
593             manager.readLock(owner1, res1);
594             cb.signalTurn(2);
595             cb.waitForTurn(3);
596             manager.release(owner1, res1);
597             manager.readLock(owner1, res1);
598             cb.signalTurn(5);
599             cb.waitForTurn(7);
600             synchronized (manager.getLock(res1)) {
601                 manager.releaseAll(owner1);
602             }
603             synchronized (restart) {
604                 restart.meet();
605                 restart.reset();
606             }
607
608             assertEquals(first, owner2);
609             first = null;
610             cb.reset();
611         }
612
613     }
614     
615     /*
616      *
617      * Test shows that two preference locks that are imcompatible do not cause a lock out
618      * which was the case with GenericLock 1.5
619      * Before the fix this test would dealock
620      *
621      * Owner Owner Owner
622      * Step #1 #2 #3
623      * 1 read (ok)
624      * 2 write preferred
625      * (blocked
626      * because of #1)
627      * 3 write preferred
628      * (blocked
629      * because of #1 and #2)
630      * 4 release
631      * 5 resumed or resumed
632      * (as both are preferred, problem
633      * is that that would exclude each other
634      * in the algorithm used)
635      * 6 released or released
636      * 7 resumed or resumed
637      * 8 released or released
638      *
639      *
640      */

641     public void testPreference() throws Throwable JavaDoc {
642
643         sLogger.logInfo("\n\nChecking incompatible preference locks\n\n");
644         
645         final String JavaDoc owner1 = "owner1";
646         final String JavaDoc owner2 = "owner2";
647         final String JavaDoc owner3 = "owner3";
648
649         final String JavaDoc res1 = "res1";
650
651         final ReadWriteLock lock = new ReadWriteLock(res1, sLogger);
652
653         final RendezvousBarrier restart = new RendezvousBarrier("restart", 3, TIMEOUT, sLogger);
654
655         final TurnBarrier cb = new TurnBarrier("cb1", TIMEOUT, sLogger, 1);
656
657         for (int i = 0; i < CONCURRENT_TESTS; i++) {
658             
659             System.out.print(".");
660
661             Thread JavaDoc t1 = new Thread JavaDoc(new Runnable JavaDoc() {
662                 public void run() {
663                     try {
664                         cb.waitForTurn(2);
665                         synchronized (lock) {
666                             cb.signalTurn(3);
667                             lock.acquire(owner2, ReadWriteLock.WRITE_LOCK, true,
668                                     GenericLock.COMPATIBILITY_REENTRANT, true, TIMEOUT);
669                         }
670                         lock.release(owner2);
671                         synchronized (restart) {
672                             restart.meet();
673                             restart.reset();
674                         }
675                     } catch (InterruptedException JavaDoc ie) {
676                     }
677                 }
678             }, "Thread #1");
679
680             t1.start();
681
682             Thread JavaDoc t2 = new Thread JavaDoc(new Runnable JavaDoc() {
683                 public void run() {
684                     try {
685                         cb.waitForTurn(3);
686                         synchronized (lock) {
687                             cb.signalTurn(4);
688                             lock.acquire(owner3, ReadWriteLock.WRITE_LOCK, true,
689                                     GenericLock.COMPATIBILITY_REENTRANT, true, TIMEOUT);
690                         }
691                         lock.release(owner3);
692                         synchronized (restart) {
693                             restart.meet();
694                             restart.reset();
695                         }
696                     } catch (InterruptedException JavaDoc ie) {
697                     }
698                 }
699             }, "Thread #2");
700
701             t2.start();
702
703             cb.waitForTurn(1);
704             lock.acquireRead(owner1, TIMEOUT);
705             cb.signalTurn(2);
706             cb.waitForTurn(4);
707             synchronized (lock) {
708                 lock.release(owner1);
709             }
710             synchronized (restart) {
711                 restart.meet();
712                 restart.reset();
713             }
714
715             cb.reset();
716         }
717
718     }
719     
720     public void testGlobalTimeout() throws Throwable JavaDoc {
721
722         sLogger.logInfo("\n\nChecking global timeouts\n\n");
723         
724         final String JavaDoc owner1 = "owner1";
725         final String JavaDoc owner2 = "owner2";
726
727         final String JavaDoc res1 = "res1";
728
729         final GenericLockManager manager = new GenericLockManager(1, sLogger, TIMEOUT, -1);
730
731         final RendezvousBarrier restart = new RendezvousBarrier("restart", 2, TIMEOUT, sLogger);
732
733         final TurnBarrier cb = new TurnBarrier("cb1", TIMEOUT, sLogger, 1);
734
735         for (int i = 0; i < CONCURRENT_TESTS; i++) {
736             
737             System.out.print(".");
738
739             Thread JavaDoc t1 = new Thread JavaDoc(new Runnable JavaDoc() {
740                 public void run() {
741                     try {
742                         cb.waitForTurn(2);
743                         manager.lock(owner2, res1, 1, true);
744                         cb.signalTurn(3);
745                         manager.releaseAll(owner2);
746                         synchronized (restart) {
747                             restart.meet();
748                             restart.reset();
749                         }
750                     } catch (InterruptedException JavaDoc ie) {
751                     }
752                 }
753             }, "Thread #1");
754
755             t1.start();
756
757             cb.waitForTurn(1);
758             manager.startGlobalTimeout(owner1, 500);
759             manager.lock(owner1, res1, 1, true);
760             cb.signalTurn(2);
761             cb.waitForTurn(3);
762             boolean failed = false;
763             try {
764                 manager.tryLock(owner1, res1, 1, true);
765             } catch (LockException le) {
766                 failed = true;
767             }
768             assertTrue(failed);
769             manager.releaseAll(owner1);
770             failed = false;
771             try {
772                 manager.tryLock(owner1, res1, 1, true);
773             } catch (LockException le) {
774                 failed = true;
775             }
776             assertFalse(failed);
777             manager.releaseAll(owner1);
778             synchronized (restart) {
779                 restart.meet();
780                 restart.reset();
781             }
782
783             cb.reset();
784         }
785
786     }
787
788     public void testStress() throws Throwable JavaDoc {
789
790         sLogger.logInfo("\n\nStress checking locks\n\n");
791         
792         final String JavaDoc owner1 = "owner1";
793         final String JavaDoc owner2 = "owner2";
794         final String JavaDoc owner3 = "owner3";
795         final String JavaDoc owner4 = "owner4";
796         final String JavaDoc owner5 = "owner5";
797         final String JavaDoc owner6 = "owner6";
798         final String JavaDoc owner7 = "owner7";
799         final String JavaDoc owner8 = "owner8";
800         final String JavaDoc owner9 = "owner9";
801         final String JavaDoc owner10 = "owner10";
802
803         final String JavaDoc res1 = "res1";
804         final String JavaDoc res2 = "res2";
805         final String JavaDoc res3 = "res3";
806
807         // choose low timeout so sometimes an owner times out
808
final ReadWriteUpgradeLockManager manager = new ReadWriteUpgradeLockManager(sLogger, 100);
809
810         final RendezvousBarrier restart = new RendezvousBarrier("restart", 5, TIMEOUT, sLogger);
811         final RendezvousBarrier start = new RendezvousBarrier("start", 5, TIMEOUT, sLogger);
812
813         for (int i = 0; i < CONCURRENT_TESTS; i++) {
814             
815             System.out.print(".");
816
817             Thread JavaDoc t1 = new Thread JavaDoc(new Runnable JavaDoc() {
818                 public void run() {
819                     try {
820                         try {
821                             synchronized (start) {
822                                 start.meet();
823                                 start.reset();
824                             }
825                             manager.readLock(owner1, res1);
826                             manager.readLock(owner1, res2);
827                             manager.upgradeLock(owner1, res3);
828                             manager.writeLock(owner1, res3);
829                         } catch (LockException ie) {
830                         } finally {
831                             manager.releaseAll(owner1);
832                             synchronized (restart) {
833                                 restart.meet();
834                                 restart.reset();
835                             }
836                         }
837                     } catch (InterruptedException JavaDoc ie) {
838                     }
839                 }
840             }, "Thread #1");
841             t1.start();
842
843             Thread JavaDoc t2 = new Thread JavaDoc(new Runnable JavaDoc() {
844                 public void run() {
845                     try {
846                         try {
847                             synchronized (start) {
848                                 start.meet();
849                                 start.reset();
850                             }
851                             manager.readLock(owner2, res1);
852                             manager.readLock(owner2, res2);
853                             manager.upgradeLock(owner2, res3);
854                             manager.writeLock(owner2, res3);
855                         } catch (LockException ie) {
856                         } finally {
857                             manager.releaseAll(owner2);
858                             synchronized (restart) {
859                                 restart.meet();
860                                 restart.reset();
861                             }
862                         }
863                     } catch (InterruptedException JavaDoc ie) {
864                     }
865                 }
866             }, "Thread #2");
867             t2.start();
868
869             Thread JavaDoc t3 = new Thread JavaDoc(new Runnable JavaDoc() {
870                 public void run() {
871                     try {
872                         try {
873                             synchronized (start) {
874                                 start.meet();
875                                 start.reset();
876                             }
877                             manager.readLock(owner3, res1);
878                             manager.readLock(owner3, res2);
879                             manager.upgradeLock(owner3, res3);
880                             manager.writeLock(owner3, res3);
881                         } catch (LockException ie) {
882                         } finally {
883                             manager.releaseAll(owner3);
884                             synchronized (restart) {
885                                 restart.meet();
886                                 restart.reset();
887                             }
888                         }
889                     } catch (InterruptedException JavaDoc ie) {
890                     }
891                 }
892             }, "Thread #3");
893             t3.start();
894
895             Thread JavaDoc t4 = new Thread JavaDoc(new Runnable JavaDoc() {
896                 public void run() {
897                     try {
898                         try {
899                             synchronized (start) {
900                                 start.meet();
901                                 start.reset();
902                             }
903                             manager.readLock(owner4, res1);
904                             manager.readLock(owner4, res2);
905                             manager.upgradeLock(owner4, res3);
906                             manager.writeLock(owner4, res3);
907                         } catch (LockException ie) {
908                         } finally {
909                             manager.releaseAll(owner4);
910                             synchronized (restart) {
911                                 restart.meet();
912                                 restart.reset();
913                             }
914                         }
915                     } catch (InterruptedException JavaDoc ie) {
916                     }
917                 }
918             }, "Thread #4");
919             t4.start();
920
921             try {
922                 try {
923                     synchronized (start) {
924                         start.meet();
925                         start.reset();
926                     }
927                     manager.readLock("reader", res1);
928                     manager.readLock("reader", res2);
929                     manager.readLock("reader", res3);
930
931                 } catch (LockException ie) {
932                 } finally {
933                     manager.releaseAll("reader");
934                     try {
935                         synchronized (restart) {
936                             restart.meet();
937                             restart.reset();
938                         }
939                     } catch (InterruptedException JavaDoc ie) {
940                     }
941                 }
942             } catch (InterruptedException JavaDoc ie) {
943             }
944         }
945
946     }
947
948     public void testChaos() throws Throwable JavaDoc {
949
950         sLogger.logInfo("\n\nChaos testing locks for internal deadlocks resp. concurrent mods\n\n");
951
952         final String JavaDoc owner1 = "owner1";
953         final String JavaDoc owner2 = "owner2";
954         final String JavaDoc owner3 = "owner3";
955         final String JavaDoc owner4 = "owner4";
956         final String JavaDoc owner5 = "owner5";
957         final String JavaDoc owner6 = "owner6";
958         final String JavaDoc owner7 = "owner7";
959         final String JavaDoc owner8 = "owner8";
960         final String JavaDoc owner9 = "owner9";
961         final String JavaDoc owner10 = "owner10";
962
963         final String JavaDoc res1 = "res1";
964         final String JavaDoc res2 = "res2";
965         final String JavaDoc res3 = "res3";
966
967         // choose low timeout so sometimes an owner times out
968
final ReadWriteUpgradeLockManager manager = new ReadWriteUpgradeLockManager(sLogger, 100);
969
970         int concurrentThreads = 7;
971         int threads = CONCURRENT_TESTS * concurrentThreads;
972         
973         final RendezvousBarrier end = new RendezvousBarrier("end", threads + 1, TIMEOUT, sLogger);
974         
975         sLogger.logInfo("\n\nStarting "+threads+" threads\n\n");
976
977         for (int i = 0; i < CONCURRENT_TESTS; i++) {
978
979             final int cnt = i;
980             
981             System.out.print(".");
982
983             Thread JavaDoc t1 = new Thread JavaDoc(new Runnable JavaDoc() {
984                 public void run() {
985                     try {
986                         manager.readLock(owner1, res1);
987                         manager.readLock(owner1, res2);
988                         manager.upgradeLock(owner1, res3);
989                         manager.writeLock(owner1, res3);
990                     } catch (LockException ie) {
991                         System.out.print("-");
992                     } finally {
993                         manager.releaseAll(owner1);
994                         end.call();
995                     }
996                 }
997             }, "Thread #1");
998
999             Thread JavaDoc t2 = new Thread JavaDoc(new Runnable JavaDoc() {
1000                public void run() {
1001                    try {
1002                        manager.readLock(owner2, res1);
1003                        manager.readLock(owner2, res2);
1004                        manager.upgradeLock(owner2, res3);
1005                        manager.writeLock(owner2, res3);
1006                    } catch (LockException ie) {
1007                        System.out.print("-");
1008                    } finally {
1009                        manager.releaseAll(owner2);
1010                        end.call();
1011                    }
1012                }
1013            }, "Thread #2");
1014
1015            Thread JavaDoc t3 = new Thread JavaDoc(new Runnable JavaDoc() {
1016                public void run() {
1017                    try {
1018                        manager.startGlobalTimeout(owner3, 10 + cnt);
1019                        manager.readLock(owner3, res1);
1020                        manager.readLock(owner3, res2);
1021                        manager.upgradeLock(owner3, res3);
1022                        manager.writeLock(owner3, res3);
1023                    } catch (LockException le) {
1024                        if (le.getCode() == LockException.CODE_TIMED_OUT) {
1025                            System.out.print("*");
1026                        } else {
1027                            System.out.print("-");
1028                        }
1029                    } finally {
1030                        manager.releaseAll(owner3);
1031                        end.call();
1032                    }
1033                }
1034            }, "Thread #3");
1035
1036            Thread JavaDoc t4 = new Thread JavaDoc(new Runnable JavaDoc() {
1037                public void run() {
1038                    try {
1039                        manager.readLock(owner4, res1);
1040                        manager.readLock(owner4, res2);
1041                        manager.upgradeLock(owner4, res3);
1042                        manager.writeLock(owner4, res3);
1043                    } catch (LockException le) {
1044                        System.out.print("-");
1045                    } finally {
1046                        manager.releaseAll(owner4);
1047                        end.call();
1048                    }
1049                }
1050            }, "Thread #4");
1051
1052                Thread JavaDoc deadlock1 = new Thread JavaDoc(new Runnable JavaDoc() {
1053                public void run() {
1054                    try {
1055                        manager.writeLock(owner5, res2);
1056                        manager.writeLock(owner5, res1);
1057                    } catch (LockException le) {
1058                        assertEquals(le.getCode(), LockException.CODE_DEADLOCK_VICTIM);
1059                        System.out.print("-");
1060                    } finally {
1061                        manager.releaseAll(owner5);
1062                        end.call();
1063                    }
1064                }
1065            }, "Deadlock1 Thread");
1066
1067            Thread JavaDoc deadlock2 = new Thread JavaDoc(new Runnable JavaDoc() {
1068                public void run() {
1069                    try {
1070                        manager.readLock(owner6, res1);
1071                        manager.readLock(owner6, res2);
1072                    } catch (LockException le) {
1073                        assertEquals(le.getCode(), LockException.CODE_DEADLOCK_VICTIM);
1074                        System.out.print("-");
1075                    } finally {
1076                        manager.releaseAll(owner6);
1077                        end.call();
1078                    }
1079                }
1080            }, "Deadlock1 Thread");
1081
1082            Thread JavaDoc reader = new Thread JavaDoc(new Runnable JavaDoc() {
1083                public void run() {
1084                    try {
1085                        manager.readLock("reader", res1);
1086                        manager.readLock("reader", res2);
1087                        manager.readLock("reader", res3);
1088                    } catch (LockException ie) {
1089                        System.out.print("-");
1090                    } finally {
1091                        manager.releaseAll("reader");
1092                        end.call();
1093                    }
1094                }
1095            }, "Reader Thread");
1096
1097
1098            t4.start();
1099            t3.start();
1100            reader.start();
1101            t1.start();
1102            deadlock2.start();
1103            t2.start();
1104            deadlock1.start();
1105        }
1106        // wait until all threads have really terminated
1107
end.meet();
1108
1109    }
1110}
1111
Popular Tags