guava/src/com/google/common/util/concurrent/AbstractFuture.java
private void removeWaiter(Waiter node) {
    node.thread = null; // mark as 'deleted'
    restart:
    while (true) {
      Waiter pred = null;
      Waiter curr = waiters;
      if (curr == Waiter.TOMBSTONE) {
        return; // give up if someone is calling complete
      }
      Waiter succ;
      while (curr != null) {
        succ = curr.next;
        if (curr.thread != null) { // we aren't unlinking this node, update pred.
          pred = curr;
        } else if (pred != null) { // We are unlinking this node and it has a predecessor.
          pred.next = succ;
          if (pred.thread == null) { // We raced with another node that unlinked pred. Restart.
            continue restart;
          }
        } else if (!ATOMIC_HELPER.casWaiters(this, curr, succ)) { // We are unlinking head
          continue restart; // We raced with an add or complete
        }
        curr = succ;
      }
      break;
    }
  }
private void removeWaiter(Waiter node) {
    node.thread = null; // mark as 'deleted'
    restart:
    while (true) {
      Waiter pred = null;
      Waiter curr = waiters;
      if (curr == Waiter.TOMBSTONE) {
        return; // give up if someone is calling complete
      }
      Waiter succ;
      while (curr != null) {
        succ = curr.next;
        if (curr.thread != null) { // we aren't unlinking this node, update pred.
          pred = curr;
        } else if (pred != null) { // We are unlinking this node and it has a predecessor.
          pred.next = succ;
          if (pred.thread == null) { // We raced with another node that unlinked pred. Restart.
            continue restart;
          }
        } else if (!ATOMIC_HELPER.casWaiters(this, curr, succ)) { // We are unlinking head
          continue restart; // We raced with an add or complete
        }
        curr = succ;
      }
      break;
    }
  }
private void removeWaiter ( Waiter node ) { node . thread = null ; // mark as 'deleted' restart : while ( true ) { Waiter pred = null ; Waiter curr = waiters ; if ( curr == Waiter . TOMBSTONE ) { return ; // give up if someone is calling complete } Waiter succ ; while ( curr != null ) { succ = curr . next ; if ( curr . thread != null ) { // we aren't unlinking this node, update pred. pred = curr ; } else if ( pred != null ) { // We are unlinking this node and it has a predecessor. pred . next = succ ; if ( pred . thread == null ) { // We raced with another node that unlinked pred. Restart. continue restart ; } } else if ( ! ATOMIC_HELPER . casWaiters ( this , curr , succ ) ) { // We are unlinking head continue restart ; // We raced with an add or complete } curr = succ ; } break ; } }
Marks the given node as 'deleted' (null waiter) and then scans the list to unlink all deleted
nodes. This is an O(n) operation in the common case (and O(n^2) in the worst), but we are saved
by two things.

<ul>
<li>This is only called when a waiting thread times out or is interrupted. Both of which
should be rare.
<li>The waiters list should be very short.
</ul>
Marks the given node as deleted ( null waiter ) and then scans the list to unlink all deleted nodes . This is an O ( n ) operation in the common case ( and O ( n^2 ) in the worst ) but we are saved by two things .