package org.multiverse.commitbarriers;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.multiverse.TestThread;
import org.multiverse.api.Txn;
import org.multiverse.api.callables.TxnVoidCallable;
import org.multiverse.api.references.TxnLong;
import org.multiverse.stms.gamma.GammaStm;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.multiverse.TestUtils.*;
import static org.multiverse.api.TxnThreadLocal.clearThreadLocalTxn;
public class CountDownCommitBarrier_IntegrationTest {
private GammaStm stm;
@Before
public void setUp() {
stm = new GammaStm();
clearThreadLocalTxn();
clearCurrentThreadInterruptedStatus();
}
@After
public void tearDown() {
clearCurrentThreadInterruptedStatus();
}
@Test
public void testMultipleWaiters() {
CountDownCommitBarrier barrier = new CountDownCommitBarrier(2);
AwaitThread t1 = new AwaitThread(barrier);
t1.start();
sleepMs(1000);
assertTrue(t1.isAlive());
AwaitThread t2 = new AwaitThread(barrier);
t2.start();
joinAll(t1, t2);
assertEquals(0, barrier.getNumberWaiting());
assertIsCommitted(t2.txn);
assertIsCommitted(t1.txn);
}
@Test
public void testSingleWaiter() {
CountDownCommitBarrier barrier = new CountDownCommitBarrier(1);
AwaitThread t1 = new AwaitThread(barrier);
t1.start();
joinAll(t1);
assertEquals(0, barrier.getNumberWaiting());
assertTrue(barrier.isCommitted());
assertIsCommitted(t1.txn);
}
public class AwaitThread extends TestThread {
private Txn txn;
private final CountDownCommitBarrier barrier;
public AwaitThread(CountDownCommitBarrier barrier) {
super("AwaitThread");
this.barrier = barrier;
}
@Override
public void doRun() throws Exception {
final TxnLong ref = stm.getDefaultRefFactory().newTxnLong(1);
stm.getDefaultTxnExecutor().execute(new TxnVoidCallable() {
@Override
public void call(Txn txn) throws Exception {
AwaitThread.this.txn = txn;
ref.set(txn, 10);
barrier.joinCommitUninterruptibly(txn);
}
});
}
}
}