/*
* JCarder -- cards Java programs to keep threads disentangled
*
* Copyright (C) 2006-2007 Enea AB
* Copyright (C) 2007 Ulrik Svensson
* Copyright (C) 2007 Joel Rosdahl
*
* This program is made available under the GNU GPL version 2, with a special
* exception for linking with JUnit. See the accompanying file LICENSE.txt for
* details.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE.
*/
package com.enea.jcarder.testclasses.agent;
import com.enea.jcarder.agent.LockEvent;
import com.enea.jcarder.common.Lock;
import com.enea.jcarder.common.LockingContext;
import static org.junit.Assert.assertTrue;
public final class RepeatOlderSynchronization
implements SynchronizationTestIfc {
private final Object mSync0 = new Object();
private final Object mSync1 = new Object();
public void go() {
synchronized (mSync0) {
assertTrue(Thread.holdsLock(mSync0));
foo();
}
}
// This method is extracted from go() in order to give an example
// when it is not obvious what to do, since the method foo() might
// also be invoked from somewhere else.
public void foo() {
synchronized (mSync1) {
assertTrue(Thread.holdsLock(mSync1));
// It can be argued if the mSync1 -> mSync0 transition should be
// reported or not. If foo() is only called from run() it
// should be safe to ignore the transtion, but if foo() can
// be called directly that transition is needed to be able to
// find potential deadlocks.
//
// The transition is NOT reported in the current implementation
// in order to avoid false warnings and we rely on that all
// possible invocations of foo() is covered with the users test
// scenarios.
synchronized (mSync0) {
assertTrue(Thread.holdsLock(mSync0));
}
}
}
public LockEvent[] getExpectedLockEvents() {
final Lock lockSync0 = new Lock(mSync0);
final Lock lockSync1 = new Lock(mSync1);
final String threadName = Thread.currentThread().getName();
final String method = getClass().getName() + ".go()";
final LockingContext contextSync0 =
new LockingContext(threadName,
getClass().getName() + ".mSync0",
method);
final LockingContext contextSync1 =
new LockingContext(threadName,
getClass().getName() + ".mSync1",
getClass().getName() + ".foo()");
return new LockEvent[] {
new LockEvent(lockSync1, contextSync1, lockSync0, contextSync0)
};
}
}