@Override public void onNext(T t) { if (establishedFusionMode == Fuseable.ASYNC) { while (true) { t = qs.poll(); if (t == null) { break; } valueCount++; if (valuesStorage) { List<T> nextValuesSnapshot; while (true) { nextValuesSnapshot = values; nextValuesSnapshot.add(t); if (NEXT_VALUES.compareAndSet(this, nextValuesSnapshot, nextValuesSnapshot)) { break; } } } } } else { valueCount++; if (valuesStorage) { List<T> nextValuesSnapshot; while (true) { nextValuesSnapshot = values; nextValuesSnapshot.add(t); if (NEXT_VALUES.compareAndSet(this, nextValuesSnapshot, nextValuesSnapshot)) { break; } } } } }
/** compareAndSet in one thread enables another waiting for value to succeed */ public void testCompareAndSetInMultipleThreads() throws Exception { x = one; final AtomicReferenceFieldUpdater<AtomicReferenceFieldUpdaterTest, Integer> a; try { a = AtomicReferenceFieldUpdater.newUpdater( AtomicReferenceFieldUpdaterTest.class, Integer.class, "x"); } catch (RuntimeException ok) { return; } Thread t = new Thread( new CheckedRunnable() { public void realRun() { while (!a.compareAndSet(AtomicReferenceFieldUpdaterTest.this, two, three)) Thread.yield(); } }); t.start(); assertTrue(a.compareAndSet(this, one, two)); t.join(LONG_DELAY_MS); assertFalse(t.isAlive()); assertSame(a.get(this), three); }
void scheduleTimeout(long idx) { Disposable d = timer; if (d != null) { d.dispose(); } if (TIMER.compareAndSet(this, d, NEW_TIMER)) { d = worker.schedule( () -> { if (idx == index) { done = true; s.dispose(); dispose(); actual.onError(new TimeoutException()); } }, timeout, unit); if (!TIMER.compareAndSet(this, NEW_TIMER, d)) { d.dispose(); } } }
/** getAndSet returns previous value and sets to given value */ public void testGetAndSet() { AtomicReferenceFieldUpdater<AtomicReferenceFieldUpdaterTest, Integer> a; try { a = AtomicReferenceFieldUpdater.newUpdater( AtomicReferenceFieldUpdaterTest.class, Integer.class, "x"); } catch (RuntimeException ok) { return; } x = one; assertSame(one, a.getAndSet(this, zero)); assertSame(zero, a.getAndSet(this, m10)); assertSame(m10, a.getAndSet(this, 1)); }
/** * Atomically sets the single subscription and requests the missed amount from it. * * @param s the Subscription to set. * @return false if this arbiter is cancelled or there was a subscription already set */ protected final boolean set(Subscription s) { Objects.requireNonNull(s, "s"); Subscription a = this.s; if (a == Operators.cancelledSubscription()) { s.cancel(); return false; } if (a != null) { s.cancel(); Operators.reportSubscriptionSet(); return false; } if (S.compareAndSet(this, null, s)) { long r = REQUESTED.getAndSet(this, 0L); if (r != 0L) { s.request(r); } return true; } a = this.s; if (a != Operators.cancelledSubscription()) { s.cancel(); return false; } Operators.reportSubscriptionSet(); return false; }
public InterruptableSubscriber( Consumer<? super T> consumer, Consumer<? super Throwable> errorConsumer, Consumer<Void> completeConsumer) { super(consumer, errorConsumer, completeConsumer); SUBSCRIPTION.lazySet(this, UNSUBSCRIBED); }
/** * Get the factory to produce the response channel. The resultant channel's {@link * StreamSinkChannel#close()} or {@link StreamSinkChannel#shutdownWrites()} method must be called * at some point after the request is processed to prevent resource leakage and to allow the next * request to proceed. Closing a fixed-length response before the corresponding number of bytes * has been written will cause the connection to be reset and subsequent requests to fail; thus it * is important to ensure that the proper content length is delivered when one is specified. The * response channel may not be writable until after the response headers have been sent. * * <p>If this method is not called then an empty or default response body will be used, depending * on the response code set. * * <p>The returned channel will begin to write out headers when the first write request is * initiated, or when {@link java.nio.channels.Channel#close()} is called on the channel with no * content being written. Once the channel is acquired, however, the response code and headers may * not be modified. * * @return the response channel factory, or {@code null} if another party already acquired the * channel factory */ public ChannelFactory<StreamSinkChannel> getResponseChannelFactory() { final ChannelWrapper[] wrappers = responseWrappersUpdater.getAndSet(this, null); if (wrappers == null) { return null; } return new ResponseChannelFactory(this, underlyingResponseChannel, wrappers); }
/** * Internally undo recorded changes we did so far. * * @return whether the state required undo actions */ boolean undoChanges() { final State state = stateUpdater.getAndSet(this, State.ROLLBACK_ONLY); if (state == State.COMPLETED || state == State.ROLLBACK_ONLY) { // Was actually completed already return false; } PatchingTaskContext.Mode currentMode = this.mode; mode = PatchingTaskContext.Mode.UNDO; final PatchContentLoader loader = PatchContentLoader.create(miscBackup, null, null); // Undo changes for the identity undoChanges(identityEntry, loader); // TODO maybe check if we need to do something for the layers too !? if (state == State.INVALIDATE || currentMode == PatchingTaskContext.Mode.ROLLBACK) { // For apply the state needs to be invalidate // For rollback the files are invalidated as part of the tasks final PatchingTaskContext.Mode mode = currentMode == PatchingTaskContext.Mode.APPLY ? PatchingTaskContext.Mode.ROLLBACK : PatchingTaskContext.Mode.APPLY; for (final File file : moduleInvalidations) { try { PatchModuleInvalidationUtils.processFile(file, mode); } catch (Exception e) { PatchLogger.ROOT_LOGGER.debugf(e, "failed to restore state for %s", file); } } } return true; }
boolean casNext(Node cmp, Node val) { boolean success = nextUpdater.compareAndSet(this, cmp, val); if (!success) { System.err.println("setting next failed"); } return success; }
/** * Fills the buffer with more data, taking into account shuffling and other tricks for dealing * with marks. Assumes that it is being called by a synchronized method. This method also assumes * that all data has already been read in, hence pos > count. */ private void fill() throws IOException { byte[] buffer = getBufIfOpen(); if (markpos < 0) pos = 0; /* no mark: throw away the buffer */ else if (pos >= buffer.length) /* no room left in buffer */ if (markpos > 0) { /* can throw away early part of the buffer */ int sz = pos - markpos; System.arraycopy(buffer, markpos, buffer, 0, sz); pos = sz; markpos = 0; } else if (buffer.length >= marklimit) { markpos = -1; /* buffer got too big, invalidate mark */ pos = 0; /* drop buffer contents */ } else { /* grow buffer */ int nsz = pos * 2; if (nsz > marklimit) nsz = marklimit; byte nbuf[] = new byte[nsz]; System.arraycopy(buffer, 0, nbuf, 0, pos); if (!bufUpdater.compareAndSet(this, buffer, nbuf)) { // Can't replace buf if there was an async close. // Note: This would need to be changed if fill() // is ever made accessible to multiple threads. // But for now, the only way CAS can fail is via close. // assert buf == null; throw new IOException("Stream closed"); } buffer = nbuf; } count = pos; int n = getInIfOpen().read(buffer, pos, buffer.length - pos); if (n > 0) count = n + pos; }
/** The common state. */ static final class State<T> { /** The first observer or the one which buffers until the first arrives. */ volatile Observer<? super T> observerRef = new BufferedObserver<T>(); /** Allow a single subscriber only. */ volatile int first; /** Field updater for observerRef. */ @SuppressWarnings("rawtypes") static final AtomicReferenceFieldUpdater<State, Observer> OBSERVER_UPDATER = AtomicReferenceFieldUpdater.newUpdater(State.class, Observer.class, "observerRef"); /** Field updater for first. */ @SuppressWarnings("rawtypes") static final AtomicIntegerFieldUpdater<State> FIRST_UPDATER = AtomicIntegerFieldUpdater.newUpdater(State.class, "first"); boolean casFirst(int expected, int next) { return FIRST_UPDATER.compareAndSet(this, expected, next); } void setObserverRef(Observer<? super T> o) { observerRef = o; } boolean casObserverRef(Observer<? super T> expected, Observer<? super T> next) { return OBSERVER_UPDATER.compareAndSet(this, expected, next); } }
private boolean transitionState( ExecutionState currentState, ExecutionState targetState, Throwable error) { if (STATE_UPDATER.compareAndSet(this, currentState, targetState)) { markTimestamp(targetState); LOG.info( getVertex().getTaskNameWithSubtaskIndex() + " (" + getAttemptId() + ") switched from " + currentState + " to " + targetState); // make sure that the state transition completes normally. // potential errors (in listeners may not affect the main logic) try { vertex.notifyStateTransition(attemptId, targetState, error); } catch (Throwable t) { LOG.error("Error while notifying execution graph of execution state transition.", t); } return true; } else { return false; } }
@Override protected void requestMore(long n) { Subscription subscription = SUBSCRIPTION.get(this); if (subscription != UNSUBSCRIBED) { subscription.request(n); } }
static final class PublisherTimerRunnable implements Runnable, Subscription { final Subscriber<? super Long> s; final Function<Runnable, ? extends Runnable> asyncExecutor; volatile Runnable cancel; static final AtomicReferenceFieldUpdater<PublisherTimerRunnable, Runnable> CANCEL = AtomicReferenceFieldUpdater.newUpdater( PublisherTimerRunnable.class, Runnable.class, "cancel"); static final Runnable CANCELLED = () -> {}; volatile boolean requested; public PublisherTimerRunnable( Subscriber<? super Long> s, Function<Runnable, ? extends Runnable> asyncExecutor) { this.s = s; this.asyncExecutor = asyncExecutor; } public void setCancel(Runnable cancel) { if (!CANCEL.compareAndSet(this, null, cancel)) { cancel.run(); } } @Override public void run() { if (requested) { if (cancel != CANCELLED) { s.onNext(0L); } asyncExecutor.apply(null); if (cancel != CANCELLED) { s.onComplete(); } } else { s.onError(new IllegalStateException("Could not emit value due to lack of requests")); } } @Override public void cancel() { Runnable c = cancel; if (c != CANCELLED) { c = CANCEL.getAndSet(this, CANCELLED); if (c != null && c != CANCELLED) { c.run(); } } asyncExecutor.apply(null); } @Override public void request(long n) { if (SubscriptionHelper.validate(n)) { requested = true; } } }
@Override public void commit(final DataTreeCandidate candidate) { if (candidate instanceof NoopDataTreeCandidate) { return; } Preconditions.checkArgument( candidate instanceof InMemoryDataTreeCandidate, "Invalid candidate class %s", candidate.getClass()); final InMemoryDataTreeCandidate c = (InMemoryDataTreeCandidate) candidate; if (LOG.isTraceEnabled()) { LOG.trace("Data Tree is {}", NormalizedNodes.toStringTree(c.getTipRoot().getData())); } final TreeNode newRoot = c.getTipRoot(); DataTreeState currentState, newState; do { currentState = state; final TreeNode currentRoot = currentState.getRoot(); LOG.debug("Updating datastore from {} to {}", currentRoot, newRoot); final TreeNode oldRoot = c.getBeforeRoot(); Preconditions.checkState( oldRoot == currentRoot, "Store tree %s and candidate base %s differ.", currentRoot, oldRoot); newState = currentState.withRoot(newRoot); LOG.trace("Updated state from {} to {}", currentState, newState); } while (!STATE_UPDATER.compareAndSet(this, currentState, newState)); }
/* * This method is synchronized to guard against user attempting to install * multiple contexts. Otherwise it runs in a lock-free manner. */ @Override public synchronized void setSchemaContext(final SchemaContext newSchemaContext) { Preconditions.checkNotNull(newSchemaContext); LOG.debug("Following schema contexts will be attempted {}", newSchemaContext); final DataSchemaContextTree contextTree = DataSchemaContextTree.from(newSchemaContext); final DataSchemaContextNode<?> rootContextNode = contextTree.getChild(rootPath); if (rootContextNode == null) { LOG.debug("Could not find root {} in new schema context, not upgrading", rootPath); return; } final DataSchemaNode rootSchemaNode = rootContextNode.getDataSchemaNode(); if (!(rootSchemaNode instanceof DataNodeContainer)) { LOG.warn( "Root {} resolves to non-container type {}, not upgrading", rootPath, rootSchemaNode); return; } final ModificationApplyOperation rootNode; if (rootSchemaNode instanceof ContainerSchemaNode) { // FIXME: real root needs to enfore presence, but that require pre-population rootNode = new ContainerModificationStrategy((ContainerSchemaNode) rootSchemaNode, treeType); } else { rootNode = SchemaAwareApplyOperation.from(rootSchemaNode, treeType); } DataTreeState currentState, newState; do { currentState = state; newState = currentState.withSchemaContext(newSchemaContext, rootNode); } while (!STATE_UPDATER.compareAndSet(this, currentState, newState)); }
abstract class AbstractPromise { private volatile Object _ref; static final long _refoffset; static { try { _refoffset = Unsafe.instance.objectFieldOffset(AbstractPromise.class.getDeclaredField("_ref")); } catch (Throwable t) { throw new ExceptionInInitializerError(t); } } protected final boolean updateState(Object oldState, Object newState) { return Unsafe.instance.compareAndSwapObject(this, _refoffset, oldState, newState); } protected final Object getState() { return _ref; } protected static final AtomicReferenceFieldUpdater<AbstractPromise, Object> updater = AtomicReferenceFieldUpdater.newUpdater(AbstractPromise.class, Object.class, "_ref"); }
@Override protected void doNext(Buffer buffer) { Buffer aggregate = this.aggregate; if (aggregate != null) { aggregate = combine(buffer); } else if (-1L == codec.canDecodeNext(buffer, decoderContext)) { combine(buffer); requestMissing(); return; } if (aggregate == null) { tryEmit(buffer); requestMissing(); } else { if (-1L == codec.canDecodeNext(aggregate, decoderContext)) { requestMissing(); } else if (AGGREGATE.compareAndSet(this, aggregate, null)) { if (!tryEmit(aggregate)) { requestMissing(); } } else { requestMissing(); } } }
/** @param e Error. */ public void onError(Throwable e) { if (ERR_UPD.compareAndSet(this, null, e)) { boolean marked = tx.setRollbackOnly(); if (e instanceof IgniteTxRollbackCheckedException) { if (marked) { try { tx.rollback(); } catch (IgniteCheckedException ex) { U.error(log, "Failed to automatically rollback transaction: " + tx, ex); } } } else if (tx.isSystemInvalidate()) { // Invalidate remote transactions on heuristic error. finish(); try { get(); } catch (IgniteTxHeuristicCheckedException ignore) { // Future should complete with GridCacheTxHeuristicException. } catch (IgniteCheckedException err) { U.error(log, "Failed to invalidate transaction: " + tx, err); } } onComplete(); } }
private V doRemove(final K key, final Table<K, V> table) { final int hashCode = hashOf(key); final AtomicReferenceArray<Item<K, V>[]> array = table.array; final int idx = hashCode & array.length() - 1; // Fetch the table row. Item<K, V>[] oldRow = array.get(idx); if (oldRow == null) { // no match for the key return nonexistent(); } if (oldRow == RESIZED) { V result; if ((result = doRemove(key, table.resizeView)) != NONEXISTENT) { // keep size consistent sizeUpdater.getAndDecrement(table); } return result; } // Find the matching Item in the row. Item<K, V> oldItem = null; int rowIdx = -1; for (int i = 0; i < oldRow.length; i++) { Item<K, V> tryItem = oldRow[i]; if (equals(key, tryItem.key)) { oldItem = tryItem; rowIdx = i; break; } } if (oldItem == null) { // no such entry exists. return nonexistent(); } // Mark the item as "removed". @SuppressWarnings("unchecked") V oldValue = (V) valueUpdater.getAndSet(oldItem, NONEXISTENT); if (oldValue == NONEXISTENT) { // Someone else beat us to it. return nonexistent(); } // Now we are free to remove the item from the row. if (array.compareAndSet(idx, oldRow, remove(oldRow, rowIdx))) { // Adjust the table size, since we are definitely the ones to be removing this item from the // table. sizeUpdater.decrementAndGet(table); // Item is removed from the row; we are done here. return oldValue; } else { boolean result = doRemove(oldItem, table); assert result; return oldValue; } }
@Override public void setCancellation(Cancellation c) { if (!CANCEL.compareAndSet(this, null, c)) { if (cancel != CANCELLED && c != null) { c.dispose(); } } }
void next() { Disposable o = other; U next; try { next = bufferSupplier.get(); } catch (Throwable e) { cancel(); actual.onError(e); return; } if (next == null) { cancel(); actual.onError(new NullPointerException("The buffer supplied is null")); return; } Publisher<B> boundary; try { boundary = boundarySupplier.get(); } catch (Throwable ex) { cancelled = true; s.cancel(); actual.onError(ex); return; } if (boundary == null) { cancelled = true; s.cancel(); actual.onError(new NullPointerException("The boundary publisher supplied is null")); return; } BufferBoundarySubscriber<T, U, B> bs = new BufferBoundarySubscriber<T, U, B>(this); if (!OTHER.compareAndSet(this, o, bs)) { return; } U b; synchronized (this) { b = buffer; if (b == null) { return; } buffer = next; } boundary.subscribe(bs); fastpathEmitMax(b, false, this); }
/** Constructor with non-volatile field throws exception */ public void testConstructor3() { try { AtomicReferenceFieldUpdater<AtomicReferenceFieldUpdaterTest, Integer> a = AtomicReferenceFieldUpdater.newUpdater( AtomicReferenceFieldUpdaterTest.class, Integer.class, "w"); shouldThrow(); } catch (RuntimeException success) { } }
void disposeOther() { Disposable d = other; if (d != DISPOSED) { d = OTHER.getAndSet(this, DISPOSED); if (d != DISPOSED && d != null) { d.dispose(); } } }
public void disposeTimer() { Disposable d = timer; if (d != CANCELLED) { d = TIMER.getAndSet(this, CANCELLED); if (d != CANCELLED && d != null) { d.dispose(); } } }
@Override public void cancel() { Subscription a = s; if (a != Operators.cancelledSubscription()) { a = S.getAndSet(this, Operators.cancelledSubscription()); if (a != null && a != Operators.cancelledSubscription()) { a.cancel(); } } }
void cancelResource() { Cancellation c = cancel; if (c != CANCELLED) { c = CANCEL.getAndSet(this, CANCELLED); if (c != null && c != CANCELLED) { requested = 0L; c.dispose(); } } }
public V setValue(final V value) { V oldValue; do { oldValue = this.value; if (oldValue == NONEXISTENT) { throw new IllegalStateException("Already removed"); } } while (!valueUpdater.compareAndSet(this, oldValue, value)); return oldValue; }
private PausableChannelEventExecutor wrappedEventLoop() { PausableChannelEventExecutor wrapped = wrappedEventLoop; if (wrapped == null) { wrapped = new PausableChannelEventExecutor0(); if (!WRAPPED_EVENTEXECUTOR_UPDATER.compareAndSet(this, null, wrapped)) { // Set in the meantime so we need to issue another volatile read return wrappedEventLoop; } } return wrapped; }
@Override public void cancel() { Runnable c = cancel; if (c != CANCELLED) { c = CANCEL.getAndSet(this, CANCELLED); if (c != null && c != CANCELLED) { c.run(); } } asyncExecutor.apply(null); }