package org.multiverse.stms.gamma.integration.composability;
import org.junit.Before;
import org.junit.Test;
import org.multiverse.api.LockMode;
import org.multiverse.api.StmUtils;
import org.multiverse.api.Txn;
import org.multiverse.api.callables.TxnVoidCallable;
import org.multiverse.api.references.TxnLong;
import org.multiverse.stms.gamma.GammaStm;
import org.multiverse.stms.gamma.transactionalobjects.GammaTxnLong;
import static org.junit.Assert.assertEquals;
import static org.multiverse.api.GlobalStmInstance.getGlobalStmInstance;
import static org.multiverse.api.TxnThreadLocal.clearThreadLocalTxn;
public class ComposabilityAndLockingTest {
private GammaStm stm;
@Before
public void setUp() {
stm = (GammaStm) getGlobalStmInstance();
clearThreadLocalTxn();
}
@Test
public void whenEnsuredInOuter_thenCanSafelyBeEnsuredInInner() {
final int initialValue = 10;
final TxnLong ref = new GammaTxnLong(stm, initialValue);
StmUtils.atomic(new TxnVoidCallable() {
@Override
public void call(Txn tx) throws Exception {
ref.getLock().acquire(LockMode.Write);
StmUtils.atomic(new TxnVoidCallable() {
@Override
public void call(Txn tx) throws Exception {
ref.getLock().acquire(LockMode.Write);
assertEquals(LockMode.Write, ref.getLock().getLockMode());
}
});
}
});
assertEquals(LockMode.None, ref.getLock().atomicGetLockMode());
assertEquals(initialValue, ref.atomicGet());
}
@Test
public void whenEnsuredInOuter_thenCanSafelyBePrivatizedInInner() {
final int initialValue = 10;
final TxnLong ref = new GammaTxnLong(stm, initialValue);
StmUtils.atomic(new TxnVoidCallable() {
@Override
public void call(Txn tx) throws Exception {
ref.getLock().acquire(LockMode.Write);
StmUtils.atomic(new TxnVoidCallable() {
@Override
public void call(Txn tx) throws Exception {
ref.getLock().acquire(LockMode.Exclusive);
assertEquals(LockMode.Exclusive, ref.getLock().getLockMode());
}
});
}
});
assertEquals(LockMode.None, ref.getLock().atomicGetLockMode());
assertEquals(initialValue, ref.atomicGet());
}
@Test
public void whenPrivatizedInOuter_thenCanSafelyBeEnsuredInInner() {
final int initialValue = 10;
final TxnLong ref = new GammaTxnLong(stm, initialValue);
StmUtils.atomic(new TxnVoidCallable() {
@Override
public void call(Txn tx) throws Exception {
ref.getLock().acquire(LockMode.Exclusive);
StmUtils.atomic(new TxnVoidCallable() {
@Override
public void call(Txn tx) throws Exception {
ref.getLock().acquire(LockMode.Write);
assertEquals(LockMode.Exclusive, ref.getLock().getLockMode());
}
});
}
});
assertEquals(LockMode.None, ref.getLock().atomicGetLockMode());
assertEquals(initialValue, ref.atomicGet());
}
@Test
public void whenPrivatizedInOuter_thenCanSafelyBePrivatizedInInner() {
final int initialValue = 10;
final TxnLong ref = new GammaTxnLong(stm, initialValue);
StmUtils.atomic(new TxnVoidCallable() {
@Override
public void call(Txn tx) throws Exception {
ref.getLock().acquire(LockMode.Exclusive);
StmUtils.atomic(new TxnVoidCallable() {
@Override
public void call(Txn tx) throws Exception {
ref.getLock().acquire(LockMode.Exclusive);
assertEquals(LockMode.Exclusive, ref.getLock().getLockMode());
}
});
}
});
assertEquals(LockMode.None, ref.getLock().atomicGetLockMode());
assertEquals(initialValue, ref.atomicGet());
}
}