protected void unparkIfNeeded(long size) { long acc_bytes=size > 0? accumulated_bytes.addAndGet(size) : accumulated_bytes.get(); boolean size_exceeded=acc_bytes >= transport.getMaxBundleSize() && accumulated_bytes.compareAndSet(acc_bytes, 0); boolean no_other_threads=num_threads.decrementAndGet() == 0; boolean unpark=size_exceeded || no_other_threads; // only 2 threads at a time should do this in parallel (1st cond and 2nd cond) if(unpark && unparking.compareAndSet(false, true)) { Thread thread=bundler_thread.getThread(); if(thread != null) LockSupport.unpark(thread); unparking.set(false); } }
@Test public void simpleMergeMap() { AtomicInteger data = new AtomicInteger(0); AtomicBoolean complete = new AtomicBoolean(false); AtomicReference<Throwable> error = new AtomicReference<Throwable>(null); range(0, 1000).mergeMap(Flux::just).forEach(n->{ data.incrementAndGet(); },e->{ error.set(e); },()->{ complete.set(true); }); while(!complete.get()){ LockSupport.parkNanos(10l); } assertThat(data.get(), CoreMatchers.equalTo(1000)); assertTrue(complete.get()); assertThat(error.get(), CoreMatchers.equalTo(null)); }
@Test public void emptyTest() { AtomicBoolean data = new AtomicBoolean(false); AtomicBoolean complete = new AtomicBoolean(false); AtomicReference<Throwable> error = new AtomicReference<Throwable>(null); this.<Integer>empty().mergeMap(v -> Flux.just(v)).forEach(n->{ data.set(true); },e->{ error.set(e); },()->{ complete.set(true); }); while(!complete.get()){ LockSupport.parkNanos(10l); } assertFalse(data.get()); assertTrue(complete.get()); assertThat(error.get(), CoreMatchers.equalTo(null)); }
AtomicBoolean leftComplete = new AtomicBoolean(false); //left & right compelte can be merged into single integer AtomicBoolean rightComplete = new AtomicBoolean(false); AtomicLong leftActive = new AtomicLong(0); AtomicLong rightActive = new AtomicLong(0); AtomicBoolean completing = new AtomicBoolean(false); AtomicInteger status = new AtomicInteger(0); //1st bit for left, 2 bit for right pushing if(status.compareAndSet(0,2) && leftQ.isEmpty()) { status.set(0); }else { return; LockSupport.parkNanos(0); return; LockSupport.parkNanos(0);
private void run() throws IOException { receiveChannel = DatagramChannel.open(); Common.init(receiveChannel); receiveChannel.bind(new InetSocketAddress("localhost", Common.PONG_PORT)); final DatagramChannel sendChannel = DatagramChannel.open(); Common.init(sendChannel); final Selector selector = Selector.open(); receiveChannel.register(selector, OP_READ, this); final NioSelectedKeySet keySet = Common.keySet(selector); final AtomicBoolean running = new AtomicBoolean(true); SigInt.register(() -> running.set(false)); while (running.get()) { measureRoundTrip(HISTOGRAM, SEND_ADDRESS, buffer, sendChannel, selector, keySet, running); HISTOGRAM.reset(); System.gc(); LockSupport.parkNanos(1000 * 1000 * 1000); } }
public void send(Message msg) throws Exception { if(msg == null) throw new IllegalArgumentException("message must not be null"); num_threads.incrementAndGet(); int tmp_index=getWriteIndex(); // decrements write_permits // System.out.printf("[%d] tmp_index=%d\n", Thread.currentThread().getId(), tmp_index); if(tmp_index == -1) { log.warn("buf is full (num_permits: %d, bundler: %s)\n", write_permits.get(), toString()); num_threads.decrementAndGet(); return; } buf[tmp_index]=msg; long acc_bytes=accumulated_bytes.addAndGet(msg.size()); int current_threads=num_threads.decrementAndGet(); boolean no_other_threads=current_threads == 0; boolean unpark=(acc_bytes >= transport.getMaxBundleSize() && accumulated_bytes.compareAndSet(acc_bytes, 0)) || no_other_threads; // only 2 threads at a time should do this (1st cond and 2nd cond), so we have to reduce this to // 1 thread as advanceWriteIndex() is not thread safe if(unpark && unparking.compareAndSet(false, true)) { int num_advanced=advanceWriteIndex(); size.addAndGet(num_advanced); if(num_advanced > 0) { Thread thread=bundler_thread.getThread(); if(thread != null) LockSupport.unpark(thread); } unparking.set(false); } }
@Test public void testNoDeadlockWhenWritingFromAnotherThreadWithSseTransport() throws Exception { socketHandler = () -> { return socket -> { AtomicBoolean closed = new AtomicBoolean(); socket.endHandler(v -> { closed.set(true); testComplete(); }); new Thread(() -> { while (!closed.get()) { LockSupport.parkNanos(50); socket.write(Buffer.buffer(TestUtils.randomAlphaString(256))); } }).start(); }; }; startServers(); client.getNow("/test/400/8ne8e94a/eventsource", onSuccess(resp -> { AtomicInteger count = new AtomicInteger(); resp.handler(msg -> { if (count.incrementAndGet() == 400) { resp.request().connection().close(); } }); })); await(); }
protected void await(boolean throwInterrupt) throws InterruptedException { if(!signaled.get()) { lock.acquired = false; sendAwaitConditionRequest(lock.name, lock.owner); boolean interrupted=false; while(!signaled.get()) { parker.set(Thread.currentThread()); LockSupport.park(this); if (!signaled.get()) { sendDeleteAwaitConditionRequest(lock.name, lock.owner); throw new InterruptedException();
final AtomicInteger coordination = new AtomicInteger( -1 ); final AtomicInteger expected = new AtomicInteger(); final int threads = 30; @SuppressWarnings( "unchecked" ) long end = currentTimeMillis() + SECONDS.toMillis( 100 ); while ( currentTimeMillis() < end && expected.get() < threads ) parkNanos( MILLISECONDS.toNanos( 10 ) ); assertEquals( threads, expected.get() );
/** * Removes and signals threads from queue for phase. */ private void releaseWaiters(int phase) { QNode q; // first element of queue Thread t; // its thread AtomicReference<QNode> head = (phase & 1) == 0 ? evenQ : oddQ; while ((q = head.get()) != null && q.phase != (int)(root.state >>> PHASE_SHIFT)) { if (head.compareAndSet(q, q.next) && (t = q.thread) != null) { q.thread = null; LockSupport.unpark(t); } } }
protected long await(long nanoSeconds) throws InterruptedException { long start=System.nanoTime(); if(!signaled.get()) { while(!signaled.get()) { long wait_nano=nanoSeconds - (System.nanoTime() - start); parker.set(Thread.currentThread()); LockSupport.parkNanos(this, wait_nano); if (!signaled.get()) { sendDeleteAwaitConditionRequest(lock.name, lock.owner); throw new InterruptedException();
}); final AtomicReference<Throwable> readerException = new AtomicReference<>(); final CountDownLatch executeLatch = new CountDownLatch(1); final Thread readerThread = new Thread(() -> { executeLatch.countDown(); } catch (Throwable t) { readerException.set(t); throw t; LockSupport.parkNanos(1L); assertThat(readerException.get(), is(nullValue()));
private static boolean registerDeferral(final JBossThread thread) { if (thread == null) { return false; } final AtomicInteger stateRef = thread.stateRef; int oldVal, newVal; do { oldVal = stateRef.get(); while (oldVal == STATE_INTERRUPT_IN_PROGRESS) { LockSupport.park(); oldVal = stateRef.get(); } if (oldVal == STATE_MAYBE_INTERRUPTED) { newVal = Thread.interrupted() ? STATE_INTERRUPT_DEFERRED : STATE_INTERRUPT_PENDING; } else if (oldVal == STATE_INTERRUPT_DEFERRED || oldVal == STATE_INTERRUPT_PENDING) { // already deferred return false; } else { throw Assert.unreachableCode(); } } while (! stateRef.compareAndSet(oldVal, newVal)); if (newVal == STATE_INTERRUPT_DEFERRED && Thread.interrupted()) { // in case we got interrupted right after we checked interrupt state but before we CAS'd the value. stateRef.set(STATE_INTERRUPT_PENDING); } return true; }
/** * Parks {@link Thread} for nanosToWait. * <p>If the current thread is {@linkplain Thread#interrupted} * while waiting for a permit then it won't throw {@linkplain InterruptedException}, * but its interrupt status will be set. * * @param nanosToWait nanoseconds caller need to wait * @return true if caller was not {@link Thread#interrupted} while waiting */ private boolean waitForPermission(final long nanosToWait) { waitingThreads.incrementAndGet(); long deadline = currentNanoTime() + nanosToWait; boolean wasInterrupted = false; while (currentNanoTime() < deadline && !wasInterrupted) { long sleepBlockDuration = deadline - currentNanoTime(); parkNanos(sleepBlockDuration); wasInterrupted = Thread.interrupted(); } waitingThreads.decrementAndGet(); if (wasInterrupted) { currentThread().interrupt(); } return !wasInterrupted; }