MCPcopy Index your code
hub / github.com/OpenTSDB/async / addCallbacks

Method addCallbacks

src/Deferred.java:637–705  ·  view source on GitHub ↗

Registers a callback and an "errback". If the deferred result is already available, the callback or the errback (depending on the nature of the result) is executed immediately from this thread. @param cb The callback to register. @param eb Th errback to register. @return this with an "up

(final Callback<R, T> cb,
                                             final Callback<R2, E> eb)

Source from the content-addressed store, hash-verified

635 * you hit it, you probably did something wrong.
636 */
637 @SuppressWarnings("unchecked")
638 public <R, R2, E> Deferred<R> addCallbacks(final Callback<R, T> cb,
639 final Callback<R2, E> eb) {
640 if (cb == null) {
641 throw new NullPointerException("null callback");
642 } else if (eb == null) {
643 throw new NullPointerException("null errback");
644 }
645 // We need to synchronize on `this' first before the CAS, to prevent
646 // runCallbacks from switching our state from RUNNING to DONE right
647 // before we add another callback.
648 synchronized (this) {
649 // If we're DONE, switch to RUNNING atomically.
650 if (state == DONE) {
651 // This "check-then-act" sequence is safe as this is the only code
652 // path that transitions from DONE to RUNNING and it's synchronized.
653 state = RUNNING;
654 } else {
655 // We get here if weren't DONE (most common code path)
656 // -or-
657 // if we were DONE and another thread raced with us to change the
658 // state and we lost the race (uncommon).
659 if (callbacks == null) {
660 callbacks = new Callback[INIT_CALLBACK_CHAIN_SIZE];
661 }
662 // Do we need to grow the array?
663 else if (last_callback == callbacks.length) {
664 final int oldlen = callbacks.length;
665 if (oldlen == MAX_CALLBACK_CHAIN_LENGTH * 2) {
666 throw new CallbackOverflowError("Too many callbacks in " + this
667 + " (size=" + (oldlen / 2) + ") when attempting to add cb="
668 + cb + '@' + cb.hashCode() + ", eb=" + eb + '@' + eb.hashCode());
669 }
670 final int len = Math.min(oldlen * 2, MAX_CALLBACK_CHAIN_LENGTH * 2);
671 final Callback[] newcbs = new Callback[len];
672 System.arraycopy(callbacks, next_callback, // Outstanding callbacks.
673 newcbs, 0, // Move them to the beginning.
674 last_callback - next_callback); // Number of items.
675 last_callback -= next_callback;
676 next_callback = 0;
677 callbacks = newcbs;
678 }
679 callbacks[last_callback++] = cb;
680 callbacks[last_callback++] = eb;
681 return (Deferred<R>) ((Deferred) this);
682 }
683 } // end of synchronized block
684
685 if (!doCall(result instanceof Exception ? eb : cb)) {
686 // While we were executing the callback, another thread could have
687 // added more callbacks. If doCall returned true, it means we're
688 // PAUSED, so we won't reach this point, because the Deferred we're
689 // waiting on will call us back later. But if we're still in state
690 // RUNNING, we'll get to here, and we must check to see if any new
691 // callbacks were added while we were executing doCall, because if
692 // there are, we must execute them immediately, because no one else
693 // is going to execute them for us otherwise.
694 boolean more;

Callers 6

addCallbackMethod · 0.95
addCallbackDeferringMethod · 0.95
addErrbackMethod · 0.95
addBothMethod · 0.95
addBothDeferringMethod · 0.95
chainMethod · 0.95

Calls 2

doCallMethod · 0.95
runCallbacksMethod · 0.95

Tested by

no test coverage detected