/** 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)); }
/** * 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; }
/** * 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); }
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; } }
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(); } } }
@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); }
void drain() { if (WIP.getAndIncrement(this) != 0) { return; } final Subscriber<? super T> a = actual; int missed = 1; for (; ; ) { if (checkTerminated(done, value == null, a)) { return; } long r = requested; long e = 0L; while (r != e) { boolean d = done; @SuppressWarnings("unchecked") T v = (T) VALUE.getAndSet(this, null); boolean empty = v == null; if (checkTerminated(d, empty, a)) { return; } if (empty) { break; } a.onNext(v); e++; } if (r == e && checkTerminated(done, value == null, a)) { return; } if (e != 0L && r != Long.MAX_VALUE) { REQUESTED.addAndGet(this, -e); } missed = WIP.addAndGet(this, -missed); if (missed == 0) { break; } } }
/** * Get the inbound request. If there is no request body, calling this method may cause the next * request to immediately be processed. The {@link StreamSourceChannel#close()} or {@link * StreamSourceChannel#shutdownReads()} method must be called at some point after the request is * processed to prevent resource leakage and to allow the next request to proceed. Any unread * content will be discarded. * * @return the channel for the inbound request, or {@code null} if another party already acquired * the channel */ public StreamSourceChannel getRequestChannel() { final ChannelWrapper[] wrappers = requestWrappersUpdater.getAndSet(this, null); if (wrappers == null) { return null; } StreamSourceChannel channel = underlyingRequestChannel; for (ChannelWrapper wrapper : wrappers) { final StreamSourceChannel oldChannel = channel; channel = ((ChannelWrapper<StreamSourceChannel>) wrapper).wrap(oldChannel, this); if (channel == null) { channel = oldChannel; } } return channel; }
public StreamSinkChannel create() { final ChannelWrapper[] wrappers = wrappersUpdater.getAndSet(this, null); if (wrappers == null) { return null; } StreamSinkChannel oldChannel = firstChannel; StreamSinkChannel channel = oldChannel; for (ChannelWrapper wrapper : wrappers) { channel = ((ChannelWrapper<StreamSinkChannel>) wrapper).wrap(channel, exchange); if (channel == null) { channel = oldChannel; } } exchange.startResponse(); return channel; }
private V doReplace(final K key, final V value, 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) { return doReplace(key, value, table.resizeView); } // Find the matching Item in the row. Item<K, V> oldItem = null; for (Item<K, V> tryItem : oldRow) { if (equals(key, tryItem.key)) { oldItem = tryItem; break; } } if (oldItem == null) { // no such entry exists. return nonexistent(); } // Now swap the item. @SuppressWarnings("unchecked") V oldRowValue = (V) valueUpdater.getAndSet(oldItem, value); if (oldRowValue == NONEXISTENT) { // Item was removed. return nonexistent(); } // Item is swapped; we are done here. return oldRowValue; }
/** * Clean current global timer references and cancel the respective {@link Timer}. A new global * timer can be assigned later with {@link #get()}. */ public static void unregister() { GlobalTimer timer; while ((timer = GLOBAL_TIMER.getAndSet(context, null)) != null) { timer._cancel(); } }
@Override public void cancel() { if (SUBSCRIPTION.getAndSet(this, CANCELLED) != CANCELLED) { super.cancel(); } }
@Override protected final void doSubscribe(Subscription s) { if (SUBSCRIPTION.getAndSet(this, s) != CANCELLED) { doSafeSubscribe(s); } }
@Override protected final void doError(Throwable t) { if (SUBSCRIPTION.getAndSet(this, CANCELLED) != CANCELLED) { doSafeError(t); } }
/** * Attaches the given object to this key. * * <p>An attached object may later be retrieved via the {@link #attachment() attachment} method. * Only one object may be attached at a time; invoking this method causes any previous attachment * to be discarded. The current attachment may be discarded by attaching <tt>null</tt>. * * @param ob The object to be attached; may be <tt>null</tt> * @return The previously-attached object, if any, otherwise <tt>null</tt> */ public final Object attach(Object ob) { return attachmentUpdater.getAndSet(this, ob); }
@Override protected final void doComplete() { if (SUBSCRIPTION.getAndSet(this, CANCELLED) != CANCELLED) { doSafeComplete(); } }