1.1 --- a/openide.util/test/unit/src/org/openide/util/MutexTest.java Fri Nov 04 10:54:10 2005 +0000
1.2 +++ b/openide.util/test/unit/src/org/openide/util/MutexTest.java Mon Nov 07 13:37:49 2005 +0000
1.3 @@ -498,6 +498,91 @@
1.4
1.5 /**
1.6 * The scenario:
1.7 + * Cast:
1.8 + * Thread A: M.reader [X] trying to lock(L)
1.9 + * Thread B: L owner [X] trying to enter M.read
1.10 + * Thread C: M.reader trying to M.writeReenter on leave
1.11 + *
1.12 + * Actions:
1.13 + * - first let A and B reach point [X]
1.14 + * - unfuse A so it block on lock(L)
1.15 + * - start C, it will reach exitReadAccess and block on reenter as writer
1.16 + * - unfuse B so it should perform its legitimate read access
1.17 + *
1.18 + * What should happen then (if Mutex works OK):
1.19 + * - B unlocks L and die
1.20 + * - A locks/unlocks L, leave readAccess and die
1.21 + * - C performs its write and die
1.22 + */
1.23 + public void testStarvation68106() throws Exception {
1.24 + final Mutex.Privileged PR = new Mutex.Privileged();
1.25 + final Mutex M = new Mutex(PR);
1.26 + final Object L = new Object();
1.27 + final boolean[] done = new boolean[3];
1.28 +
1.29 + final Ticker tickX1 = new Ticker();
1.30 + final Ticker tickX2 = new Ticker();
1.31 + final Ticker tickX3 = new Ticker();
1.32 +
1.33 + Thread A = new Thread() { public void run() {
1.34 + PR.enterReadAccess();
1.35 +
1.36 + tickX1.tick();
1.37 + tickX2.waitOn();
1.38 +
1.39 + synchronized(L) {
1.40 + done[0] = true;
1.41 + }
1.42 + }};
1.43 +
1.44 + Thread B = new Thread() { public void run() {
1.45 + synchronized(L) {
1.46 +
1.47 + tickX2.tick();
1.48 + tickX3.tick();
1.49 + tickX1.waitOn();
1.50 +
1.51 + PR.enterReadAccess();
1.52 + done[1] = true;
1.53 + PR.exitReadAccess();
1.54 + }
1.55 + }};
1.56 +
1.57 + Thread C = new Thread() { public void run() {
1.58 + PR.enterReadAccess();
1.59 + M.postWriteRequest(new Runnable() {public void run() {
1.60 + done[2] = true;
1.61 + }});
1.62 + PR.exitReadAccess();
1.63 + }};
1.64 +
1.65 + A.start();
1.66 + tickX1.waitOn();
1.67 + // A reached point X
1.68 +
1.69 + B.start();
1.70 + tickX3.waitOn();
1.71 + // B reached point X, unlocked A so in would block on lock(L)
1.72 +
1.73 + C.start();
1.74 + // C is blocking in leave/privilegedEnter
1.75 +
1.76 + tickX1.tick();
1.77 + // push B, everything should finish after this
1.78 +
1.79 + // wait for them for a while
1.80 + A.join(2000);
1.81 + B.join(2000);
1.82 + C.join(2000);
1.83 +
1.84 + assertTrue("Thread A finished", done[0]);
1.85 + assertTrue("Thread B finished", done[1]);
1.86 + assertTrue("Thread C finished", done[2]);
1.87 + }
1.88 +
1.89 +
1.90 + /**
1.91 + * The scenario:
1.92 * - Have 3 threads, A, B and C
1.93 * - writeLock mutex1 in A
1.94 * - writeLock mutex2 in B