package org.multiverse.stms.gamma; import org.junit.Before; import org.junit.Test; import org.multiverse.TestThread; import org.multiverse.api.TxnExecutor; import org.multiverse.api.Txn; import org.multiverse.api.callables.TxnVoidCallable; import org.multiverse.api.exceptions.RetryInterruptedException; import org.multiverse.stms.gamma.transactionalobjects.GammaTxnLong; import org.multiverse.stms.gamma.transactionalobjects.Tranlocal; import org.multiverse.stms.gamma.transactions.GammaTxn; import java.util.concurrent.TimeUnit; import static org.junit.Assert.assertEquals; import static org.multiverse.TestUtils.assertAlive; import static org.multiverse.TestUtils.sleepMs; import static org.multiverse.api.StmUtils.retry; import static org.multiverse.api.TxnThreadLocal.clearThreadLocalTxn; public class GammaTxnExecutor_interruptibleTest implements GammaConstants { private GammaStm stm; @Before public void setUp() { clearThreadLocalTxn(); stm = new GammaStm(); } @Test public void whenNoTimeoutAndInterruptible() throws InterruptedException { final GammaTxnLong ref = new GammaTxnLong(stm); TxnExecutor executor = stm.newTxnFactoryBuilder() .setInterruptible(true) .newTxnExecutor(); WaitWithoutTimeoutThread t = new WaitWithoutTimeoutThread(ref, executor); t.setPrintStackTrace(false); t.start(); sleepMs(1000); assertAlive(t); t.interrupt(); t.join(); t.assertFailedWithException(RetryInterruptedException.class); assertEquals(0, ref.atomicGet()); } @Test public void whenTimeoutAndInterruptible() throws InterruptedException { final GammaTxnLong ref = new GammaTxnLong(stm); TxnExecutor executor = stm.newTxnFactoryBuilder() .setTimeoutNs(TimeUnit.SECONDS.toNanos(10)) .setInterruptible(true) .newTxnExecutor(); WaitWithoutTimeoutThread t = new WaitWithoutTimeoutThread(ref, executor); t.setPrintStackTrace(false); t.start(); sleepMs(1000); assertAlive(t); t.interrupt(); t.join(); t.assertFailedWithException(RetryInterruptedException.class); assertEquals(0, ref.atomicGet()); } class WaitWithoutTimeoutThread extends TestThread { final GammaTxnLong ref; private final TxnExecutor executor; public WaitWithoutTimeoutThread(GammaTxnLong ref, TxnExecutor executor) { this.ref = ref; this.executor = executor; } @Override public void doRun() throws Exception { executor.execute(new TxnVoidCallable() { @Override public void call(Txn tx) throws Exception { GammaTxn btx = (GammaTxn) tx; Tranlocal write = ref.openForWrite(btx, LOCKMODE_NONE); if (write.long_value == 0) { retry(); } write.long_value = 100; } }); } } }