void unregisterWaiter(Thread waiter) {
    WaitNode prev = null;
    Object current = state;

    while (current != null) {
      Object currentWaiter =
          current.getClass() == WaitNode.class ? ((WaitNode) current).waiter : current;
      Object next = current.getClass() == WaitNode.class ? ((WaitNode) current).next : null;

      if (currentWaiter == waiter) {
        // it is the item we are looking for, so lets try to remove it
        if (prev == null) {
          // it's the first item of the stack, so we need to change the head to the next
          Object n = next == null ? VOID : next;
          // if we manage to CAS we are done, else we need to restart
          current = compareAndSetState(current, n) ? null : state;
        } else {
          // remove the current item (this is done by letting the prev.next point to the next
          // instead of current)
          prev.next = next;
          // end the loop
          current = null;
        }
      } else {
        // it isn't the item we are looking for, so lets move on to the next
        prev = current.getClass() == WaitNode.class ? (WaitNode) current : null;
        current = next;
      }
    }
  }
  /**
   * Registers a waiter (thread/ExecutionCallback) that gets notified when the future completes.
   *
   * @param waiter the waiter
   * @param executor the {@link Executor} to use in case of an {@link ExecutionCallback}.
   * @return VOID if the registration was a success, anything else but void is the response.
   */
  private Object registerWaiter(Object waiter, Executor executor) {
    WaitNode waitNode = null;
    for (; ; ) {
      final Object oldState = state;
      if (isDone(oldState)) {
        return oldState;
      }

      Object newState;
      if (oldState == VOID && (executor == null || executor == defaultExecutor)) {
        // nothing is syncing on this future, so instead of creating a WaitNode, we just try to cas
        // the waiter
        newState = waiter;
      } else {
        // something already has been registered for syncing, so we need to create a WaitNode
        if (waitNode == null) {
          waitNode = new WaitNode(waiter, executor);
        }
        waitNode.next = oldState;
        newState = waitNode;
      }

      if (compareAndSetState(oldState, newState)) {
        // we have successfully registered
        return VOID;
      }
    }
  }
Example #3
0
 protected WaitNode extract() {
   if (head_ == null) return null;
   else {
     WaitNode w = head_;
     head_ = w.next;
     if (head_ == null) tail_ = null;
     w.next = null;
     return w;
   }
 }
Example #4
0
 protected void insert(WaitNode w) {
   if (tail_ == null) head_ = tail_ = w;
   else {
     tail_.next = w;
     tail_ = w;
   }
 }