Sets the result of this Future to match the supplied input Future once the supplied Future is done, unless this Future has already been cancelled or set (including "set asynchronously," defined below). If the supplied future is plain #isDone done when this
(ListenableFuture<? extends V> future)
| 687 | */ |
| 688 | |
| 689 | @Beta |
| 690 | @CanIgnoreReturnValue |
| 691 | protected boolean setFuture(ListenableFuture<? extends V> future) { |
| 692 | checkNotNull(future); |
| 693 | Object localValue = value; |
| 694 | if (localValue == null) { |
| 695 | if (future.isDone()) { |
| 696 | return completeWithFuture(future, null); |
| 697 | } |
| 698 | SetFuture valueToSet = new SetFuture(future); |
| 699 | if (ATOMIC_HELPER.casValue(this, null, valueToSet)) { |
| 700 | // the listener is responsible for calling completeWithFuture, directExecutor is appropriate |
| 701 | // since all we are doing is unpacking a completed future which should be fast. |
| 702 | try { |
| 703 | future.addListener(valueToSet, directExecutor()); |
| 704 | } catch (Throwable t) { |
| 705 | // addListener has thrown an exception! SetFuture.run can't throw any exceptions so this |
| 706 | // must have been caused by addListener itself. The most likely explanation is a |
| 707 | // misconfigured mock. Try to switch to Failure. |
| 708 | Failure failure; |
| 709 | try { |
| 710 | failure = new Failure(t); |
| 711 | } catch (Throwable oomMostLikely) { |
| 712 | failure = Failure.FALLBACK_INSTANCE; |
| 713 | } |
| 714 | // Note: The only way this CAS could fail is if cancel() has raced with us. That is ok. |
| 715 | boolean unused = ATOMIC_HELPER.casValue(this, valueToSet, failure); |
| 716 | } |
| 717 | return true; |
| 718 | } |
| 719 | localValue = value; // we lost the cas, fall through and maybe cancel |
| 720 | } |
| 721 | // The future has already been set to something. If it is cancellation we should cancel the |
| 722 | // incoming future. |
| 723 | if (localValue instanceof Cancellation) { |
| 724 | // we don't care if it fails, this is best-effort. |
| 725 | future.cancel(((Cancellation) localValue).wasInterrupted); |
| 726 | } |
| 727 | return false; |
| 728 | } |
| 729 | |
| 730 | /** |
| 731 | * Called when a future passed via setFuture has completed. |
no test coverage detected