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; } } }
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; } }
protected void insert(WaitNode w) { if (tail_ == null) head_ = tail_ = w; else { tail_.next = w; tail_ = w; } }