/** * Convenience method to interrupt current strand. */ static void selfInterrupt() { Strand.currentStrand().interrupt(); }
@Suspendable @Override public void start() throws Exception { EventBus eb = vertx.eventBus(); eb.consumer(ADDRESS).handler(msg -> msg.reply("pong")); // This runs on an event loop but the event loop is at no time blocked! for (int i = 0; i < 10; i++) { System.out.println("Thread is " + Thread.currentThread()); Message<String> reply = awaitResult(h -> eb.send(ADDRESS, "ping", h)); System.out.println("got reply: " + reply.body()); // Like Thread.sleep but doesn't block the OS thread Strand.sleep(1000); } }
/** * Awaits the termination of a given strand. * This method blocks until this strand terminates. * * @param strand the strand to join. May be an object of type {@code Strand}, {@code Fiber} or {@code Thread}. * @throws ExecutionException if this strand has terminated as a result of an uncaught exception * (which will be the {@link Throwable#getCause() cause} of the thrown {@code ExecutionException}. * @throws InterruptedException */ public static void join(Object strand) throws ExecutionException, InterruptedException { Strand.join(strand); }
/** * Convenience method to park and then check if interrupted * * @return {@code true} if interrupted */ private boolean parkAndCheckInterrupt() throws SuspendExecution { Strand.park(this); return Strand.interrupted(); }
/** * Returns the current strand. * This method will return a strand representing the fiber calling this method, or the current thread if this method is not * called within a fiber. * * @return A strand representing the current fiber or thread */ public static Strand currentStrand() { return Strand.currentStrand(); }
Strand w = Strand.currentStrand(); int spins = (w.isFiber() ? 0 : -1); // no spins in fiber; otherwise, initialized after first item and cancel checks if ((w.isInterrupted() || (timed && nanos <= 0)) --spins; if (randomYields.nextInt(CHAINED_SPINS) == 0) Strand.yield(); // occasionally yield } else if (s.waiter == null) { long now = System.nanoTime(); if ((nanos -= now - lastTime) > 0) Strand.parkNanos(this, nanos); lastTime = now; } else { Strand.park(this);
public static Strand clone(Strand strand, final SuspendableCallable<?> target) { if (strand.isAlive()) throw new IllegalStateException("A strand can only be cloned after death. " + strand + " isn't dead."); if (strand instanceof FiberStrand) return clone((Fiber) strand.getUnderlying(), target); if (strand instanceof Fiber) return new Fiber((Fiber) strand, target); else return ThreadStrand.get(cloneThread((Thread) strand.getUnderlying(), toRunnable(target))); }
public static void parkAndUnpark(Strand other, Object blocker) throws SuspendExecution { if (canTransferControl(other)) Fiber.parkAndUnpark((Fiber) other, blocker); else if (!other.isFiber() && !isCurrentFiber()) { // might be made faster on Linux if SwitchTo syscall is introduced into the kernel. other.unpark(blocker); LockSupport.park(blocker); } else { other.unpark(blocker); park(blocker); } }
int lastUnarrived = 0; // to increase spins upon change final int spinDelta = Strand.isCurrentFiber() ? 0 : SPINS_PER_ARRIVAL; int spins = spinDelta; long s; && (lastUnarrived = unarrived) < NCPU) spins += spinDelta; boolean interrupted = Strand.interrupted(); if (interrupted || --spins < 0) { // need node to record intr node = new QNode(this, phase, false, false, 0L); Strand.currentStrand().interrupt(); if (p == phase && (p = (int) (state >>> PHASE_SHIFT)) == phase) return abortWait(phase); // possibly clean up on abort
@Override public void await(int iter) throws InterruptedException, SuspendExecution { final int spins; final Fiber<?> fib = Fiber.currentFiber(); if (fib != null) { spins = 0; if (iter > 0) fib.getMonitor().spuriousWakeup(); } else spins = SPINS - iter; if (spins > 0) { if (ThreadLocalRandom.current().nextInt(SPINS) == 0) Strand.yield(); } else { if (isRecording()) record("await", "%s parking", Strand.currentStrand()); Strand.park(owner); if (isRecording()) record("await", "%s awoke", Strand.currentStrand()); } if (Strand.interrupted()) throw new InterruptedException(); }
protected void maybeSetCurrentStrandAsOwner() { if (owner == null) setStrand(Strand.currentStrand()); else assert Strand.equals(owner, Strand.currentStrand()) : "This method has been called by a different strand (" + Strand.currentStrand() + ") from that owning this object (" + owner + ")"; }
throw new BrokenBarrierException(); if (Strand.interrupted()) { breakBarrier(); throw new InterruptedException(); Strand.currentStrand().interrupt();
@Override public Object register() { Strand.unpark(Strand.currentStrand()); return null; }
public void await() throws SuspendExecution { waiter = Strand.currentStrand(); while (running.get() > 0) { Strand.park(); } } }
private static class RequestExecOutcome<Res> { final long execTime; final Res response; final Exception exception; public RequestExecOutcome(final long execTime, final Res response, final Exception exception) { this.execTime = execTime; this.response = response; this.exception = exception; } }
private static boolean canTransferControl(Strand other) { Strand current = Strand.currentStrand(); return (other.isFiber() && current.isFiber() && ((Fiber) other).getScheduler() == ((Fiber) current).getScheduler()); }
final int getReadHoldCount() { if (getReadLockCount() == 0) return 0; Strand current = Strand.currentStrand(); if (firstReader == current) return firstReaderHoldCount; HoldCounter rh = cachedHoldCounter; if (rh != null && rh.tid == current.getId()) return rh.count; int count = readHolds.get().count; if (count == 0) readHolds.remove(); return count; }
private boolean onQueueFull(int iter, boolean timed, long nanos) throws SuspendExecution, InterruptedException, TimeoutException { switch (overflowPolicy) { case DROP: return false; case THROW: throw new QueueCapacityExceededException(); case BLOCK: if (timed) sendersSync.await(iter, nanos, TimeUnit.NANOSECONDS); else sendersSync.await(iter); return true; case BACKOFF: if (iter > MAX_SEND_RETRIES) throw new QueueCapacityExceededException(); if (iter > 5) Strand.sleep((iter - 5) * 5); else if (iter > 4) Strand.yield(); return true; default: throw new AssertionError("Unsupportd policy: " + overflowPolicy); } }