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; } } }
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; } } }
if (compareAndSetState(oldState, newState)) {
if (compareAndSetState(oldState, newState)) {
/** * Can be called multiple times, but only the first answer will lead to the * future getting triggered. All subsequent complete calls are ignored. * * @param value The type of response to offer. * @return <tt>true</tt> if offered response, either a final response or an * internal response, is set/applied, <tt>false</tt> otherwise. If <tt>false</tt> * is returned, that means offered response is ignored because a final response * is already set to this future. */ @Override public final boolean complete(Object value) { for (; ; ) { final Object oldState = state; if (isDone(oldState)) { warnIfSuspiciousDoubleCompletion(oldState, value); return false; } if (compareAndSetState(oldState, value)) { onComplete(); unblockAll(oldState, defaultExecutor); return true; } } }
/** * Can be called multiple times, but only the first answer will lead to the * future getting triggered. All subsequent complete calls are ignored. * * @param value The type of response to offer. * @return <tt>true</tt> if offered response, either a final response or an * internal response, is set/applied, <tt>false</tt> otherwise. If <tt>false</tt> * is returned, that means offered response is ignored because a final response * is already set to this future. */ @Override public final boolean complete(Object value) { for (; ; ) { final Object oldState = state; if (isDone(oldState)) { warnIfSuspiciousDoubleCompletion(oldState, value); return false; } if (compareAndSetState(oldState, value)) { onComplete(); unblockAll(oldState, defaultExecutor); return true; } } }