use of co.paralleluniverse.strands.Strand in project quasar by puniverse.
the class ActorTest method spawnActor.
private <Message, V> Actor<Message, V> spawnActor(Actor<Message, V> actor) {
Fiber fiber = new Fiber("actor", scheduler, actor);
fiber.setUncaughtExceptionHandler(new Strand.UncaughtExceptionHandler() {
@Override
public void uncaughtException(Strand s, Throwable e) {
e.printStackTrace();
throw Exceptions.rethrow(e);
}
});
fiber.start();
return actor;
}
use of co.paralleluniverse.strands.Strand in project quasar by puniverse.
the class ValTest method complexTest2.
@Test
public void complexTest2() throws Exception {
final Val<Integer> val1 = new Val<>();
final Val<Integer> val2 = new Val<>();
final Val<Integer> val3 = new Val<>();
final Val<Integer> val4 = new Val<>();
final AtomicReference<Integer> res = new AtomicReference<>();
final Strand f1 = new Fiber<Integer>(new SuspendableRunnable() {
@Override
public void run() throws InterruptedException, SuspendExecution {
// 2
val2.set(val1.get() + 1);
}
}).start();
final Strand t1 = Strand.of(new Thread(Strand.toRunnable(new SuspendableRunnable() {
@Override
public void run() throws SuspendExecution {
try {
// 3
val3.set(val1.get() + val2.get());
} catch (InterruptedException ex) {
throw new RuntimeException(ex);
}
}
}))).start();
final Strand f2 = new Fiber<Integer>(new SuspendableRunnable() {
@Override
public void run() throws InterruptedException, SuspendExecution {
// 5
val4.set(val2.get() + val3.get());
}
}).start();
Thread.sleep(100);
val1.set(1);
int myRes = val4.get();
assertThat(myRes, is(5));
t1.join();
f1.join();
f2.join();
}
use of co.paralleluniverse.strands.Strand in project quasar by puniverse.
the class TwoSidedTest method twoSidedTest.
@Test
public void twoSidedTest() throws Exception {
// Publisher
final Channel<Integer> publisherChannel = Channels.newChannel(random() ? 0 : 5, OverflowPolicy.BLOCK);
final Strand publisherStrand = new Fiber<Void>(new SuspendableRunnable() {
@Override
public void run() throws SuspendExecution, InterruptedException {
for (long i = 0; i < ELEMENTS; i++) publisherChannel.send((int) (i % 1000));
publisherChannel.close();
}
}).start();
final Publisher publisher = ReactiveStreams.toPublisher(publisherChannel);
// Subscriber
final ReceivePort<Integer> subscriberChannel = ReactiveStreams.subscribe(buffer, overflowPolicy, publisher);
final Strand subscriberStrand = new Fiber<Void>(new SuspendableRunnable() {
@Override
public void run() throws SuspendExecution, InterruptedException {
long count = 0;
for (; ; ) {
Integer x = subscriberChannel.receive();
if (x == null)
break;
assertEquals(count % 1000, x.longValue());
count++;
}
subscriberChannel.close();
assertEquals(ELEMENTS, count);
}
}).start();
subscriberStrand.join(5, TimeUnit.SECONDS);
publisherStrand.join(5, TimeUnit.SECONDS);
}
use of co.paralleluniverse.strands.Strand in project quasar by puniverse.
the class StampedLock method acquireRead.
/**
* See above for explanation.
*
* @param interruptible true if should check interrupts and if so
* return INTERRUPTED
* @param deadline if nonzero, the System.nanoTime value to timeout
* at (and return zero)
* @return next state, or INTERRUPTED
*/
private long acquireRead(boolean interruptible, long deadline) throws SuspendExecution {
WNode node = null, group = null, p;
for (int spins = -1; ; ) {
for (; ; ) {
long s, m, ns;
WNode h, q;
// anti-barging guard
Strand w;
if (group == null && (h = whead) != null && (q = h.next) != null && q.mode != RMODE)
break;
if ((m = (s = state) & ABITS) < RFULL ? U.compareAndSwapLong(this, STATE, s, ns = s + RUNIT) : (m < WBIT && (ns = tryIncReaderOverflow(s)) != 0L)) {
if (group != null) {
// help release others
for (WNode r = group; ; ) {
if ((w = r.strand) != null) {
r.strand = null;
w.unpark();
}
if ((r = group.cowait) == null)
break;
U.compareAndSwapObject(group, WCOWAIT, r, r.cowait);
}
}
return ns;
}
if (m >= WBIT)
break;
}
if (spins > 0) {
if (ThreadLocalRandom.current().nextInt() >= 0)
--spins;
} else if ((p = wtail) == null) {
WNode h = new WNode(WMODE, null);
if (U.compareAndSwapObject(this, WHEAD, null, h))
wtail = h;
} else if (spins < 0)
spins = (p == whead) ? SPINS : 0;
else if (node == null)
node = new WNode(WMODE, p);
else if (node.prev != p)
node.prev = p;
else if (p.mode == RMODE && p != whead) {
// become co-waiter with group p
WNode pp = p.prev;
if (pp != null && p == wtail && U.compareAndSwapObject(p, WCOWAIT, node.cowait = p.cowait, node)) {
node.strand = Strand.currentStrand();
for (long time; ; ) {
if (interruptible && Strand.interrupted())
return cancelWaiter(node, p, true);
if (deadline == 0L)
time = 0L;
else if ((time = deadline - System.nanoTime()) <= 0L)
return cancelWaiter(node, p, false);
if (node.strand == null)
break;
if (p.prev != pp || p.status == CANCELLED || p == whead || p.prev != pp) {
node.strand = null;
break;
}
if (// must recheck
node.strand == null)
break;
park(time);
}
group = p;
}
// throw away
node = null;
} else if (U.compareAndSwapObject(this, WTAIL, p, node)) {
p.next = node;
break;
}
}
for (int spins = SPINS; ; ) {
WNode np, pp, r;
int ps;
long m, s, ns;
Strand w;
while ((np = node.prev) != p && np != null) (p = np).next = node;
if (whead == p) {
for (int k = spins; ; ) {
if ((m = (s = state) & ABITS) != WBIT) {
if (m < RFULL ? U.compareAndSwapLong(this, STATE, s, ns = s + RUNIT) : (ns = tryIncReaderOverflow(s)) != 0L) {
whead = node;
node.prev = null;
while ((r = node.cowait) != null) {
if (U.compareAndSwapObject(node, WCOWAIT, r, r.cowait) && (w = r.strand) != null) {
r.strand = null;
// release co-waiter
w.unpark();
}
}
return ns;
}
} else if (ThreadLocalRandom.current().nextInt() >= 0 && --k <= 0)
break;
}
if (spins < MAX_HEAD_SPINS)
spins <<= 1;
}
if ((ps = p.status) == 0)
U.compareAndSwapInt(p, WSTATUS, 0, WAITING);
else if (ps == CANCELLED) {
if ((pp = p.prev) != null) {
node.prev = pp;
pp.next = node;
}
} else {
long time;
if (deadline == 0L)
time = 0L;
else if ((time = deadline - System.nanoTime()) <= 0L)
return cancelWaiter(node, node, false);
node.strand = Strand.currentStrand();
if (node.prev == p && p.status == WAITING && (p != whead || (state & ABITS) != WBIT))
park(time);
node.strand = null;
if (interruptible && Strand.interrupted())
return cancelWaiter(node, node, true);
}
}
}
use of co.paralleluniverse.strands.Strand in project quasar by puniverse.
the class StampedLock method release.
/**
* Wakes up the successor of h (normally whead). This is normally
* just h.next, but may require traversal from wtail if next
* pointers are lagging. This may fail to wake up an acquiring
* strand when one or more have been cancelled, but the cancel
* methods themselves provide extra safeguards to ensure liveness.
*/
private void release(WNode h) {
if (h != null) {
WNode q;
Strand w;
U.compareAndSwapInt(h, WSTATUS, WAITING, 0);
if ((q = h.next) == null || q.status == CANCELLED) {
for (WNode t = wtail; t != null && t != h; t = t.prev) if (t.status <= 0)
q = t;
}
if (q != null) {
for (WNode r = q; ; ) {
// release co-waiters too
if ((w = r.strand) != null) {
r.strand = null;
w.unpark();
}
if ((r = q.cowait) == null)
break;
U.compareAndSwapObject(q, WCOWAIT, r, r.cowait);
}
}
}
}
Aggregations