@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);
    }
  }
Exemple #12
0
  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));
  }
Exemple #17
0
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);
 }