diff --git a/android/guava/src/com/google/common/util/concurrent/AbstractFuture.java b/android/guava/src/com/google/common/util/concurrent/AbstractFuture.java index 1982fc7945998..62add5f03374a 100644 --- a/android/guava/src/com/google/common/util/concurrent/AbstractFuture.java +++ b/android/guava/src/com/google/common/util/concurrent/AbstractFuture.java @@ -1485,19 +1485,34 @@ boolean casValue(AbstractFuture future, @Nullable Object expect, Object updat } } - /** Returns an {@link AtomicReferenceFieldUpdater} for {@link #waiters}. */ + /** + * Returns an {@link AtomicReferenceFieldUpdater} for {@link #waiters}. + * + *

The creation of the updater has to happen directly inside {@link AbstractFuture}, as + * discussed in {@link #methodHandlesLookupFromWithinAbstractFuture}. + */ private static AtomicReferenceFieldUpdater, Waiter> waitersUpdaterFromWithinAbstractFuture() { return newUpdater(AbstractFuture.class, Waiter.class, "waiters"); } - /** Returns an {@link AtomicReferenceFieldUpdater} for {@link #listeners}. */ + /** + * Returns an {@link AtomicReferenceFieldUpdater} for {@link #listeners}. + * + *

The creation of the updater has to happen directly inside {@link AbstractFuture}, as + * discussed in {@link #methodHandlesLookupFromWithinAbstractFuture}. + */ private static AtomicReferenceFieldUpdater, Listener> listenersUpdaterFromWithinAbstractFuture() { return newUpdater(AbstractFuture.class, Listener.class, "listeners"); } - /** Returns an {@link AtomicReferenceFieldUpdater} for {@link #value}. */ + /** + * Returns an {@link AtomicReferenceFieldUpdater} for {@link #value}. + * + *

The creation of the updater has to happen directly inside {@link AbstractFuture}, as + * discussed in {@link #methodHandlesLookupFromWithinAbstractFuture}. + */ private static AtomicReferenceFieldUpdater, Object> valueUpdaterFromWithinAbstractFuture() { return newUpdater(AbstractFuture.class, Object.class, "value"); diff --git a/android/guava/src/com/google/common/util/concurrent/AggregateFutureState.java b/android/guava/src/com/google/common/util/concurrent/AggregateFutureState.java index eca2e4f713fcb..67af742248602 100644 --- a/android/guava/src/com/google/common/util/concurrent/AggregateFutureState.java +++ b/android/guava/src/com/google/common/util/concurrent/AggregateFutureState.java @@ -54,10 +54,7 @@ abstract class AggregateFutureState AtomicHelper helper; Throwable thrownReflectionFailure = null; try { - helper = - new SafeAtomicHelper( - newUpdater(AggregateFutureState.class, Set.class, "seenExceptions"), - newUpdater(AggregateFutureState.class, "remaining")); + helper = new SafeAtomicHelper(); } catch (Throwable reflectionFailure) { // sneaky checked exception // Some Android 5.0.x Samsung devices have bugs in JDK reflection APIs that cause // getDeclaredField to throw a NoSuchFieldException when the field is definitely there. @@ -156,20 +153,12 @@ abstract void compareAndSetSeenExceptions( } private static final class SafeAtomicHelper extends AtomicHelper { - final AtomicReferenceFieldUpdater< + private static final AtomicReferenceFieldUpdater< ? super AggregateFutureState, ? super @Nullable Set> - seenExceptionsUpdater; + seenExceptionsUpdater = seenExceptionsUpdaterFromWithinAggregateFutureState(); - final AtomicIntegerFieldUpdater> remainingCountUpdater; - - SafeAtomicHelper( - AtomicReferenceFieldUpdater< - ? super AggregateFutureState, ? super @Nullable Set> - seenExceptionsUpdater, - AtomicIntegerFieldUpdater> remainingCountUpdater) { - this.seenExceptionsUpdater = seenExceptionsUpdater; - this.remainingCountUpdater = remainingCountUpdater; - } + private static final AtomicIntegerFieldUpdater> + remainingCountUpdater = remainingCountUpdaterFromWithinAggregateFutureState(); @Override void compareAndSetSeenExceptions( @@ -201,4 +190,27 @@ int decrementAndGetRemainingCount(AggregateFutureState state) { } } } + + /** + * Returns an {@link AtomicReferenceFieldUpdater} for {@link #seenExceptions}. + * + *

The creation of the updater has to happen directly inside {@link AggregateFutureState}, as + * discussed in {@link AbstractFuture#methodHandlesLookupFromWithinAbstractFuture}. + */ + private static AtomicReferenceFieldUpdater< + ? super AggregateFutureState, ? super @Nullable Set> + seenExceptionsUpdaterFromWithinAggregateFutureState() { + return newUpdater(AggregateFutureState.class, Set.class, "seenExceptions"); + } + + /** + * Returns an {@link AtomicIntegerFieldUpdater} for {@link #remaining}. + * + *

The creation of the updater has to happen directly inside {@link AggregateFutureState}, as + * discussed in {@link AbstractFuture#methodHandlesLookupFromWithinAbstractFuture}. + */ + private static AtomicIntegerFieldUpdater> + remainingCountUpdaterFromWithinAggregateFutureState() { + return newUpdater(AggregateFutureState.class, "remaining"); + } } diff --git a/guava/src/com/google/common/util/concurrent/AbstractFuture.java b/guava/src/com/google/common/util/concurrent/AbstractFuture.java index 8feee33f4bf72..3a6da6562f948 100644 --- a/guava/src/com/google/common/util/concurrent/AbstractFuture.java +++ b/guava/src/com/google/common/util/concurrent/AbstractFuture.java @@ -1597,19 +1597,34 @@ boolean casValue(AbstractFuture future, @Nullable Object expect, Object updat } } - /** Returns an {@link AtomicReferenceFieldUpdater} for {@link #waiters}. */ + /** + * Returns an {@link AtomicReferenceFieldUpdater} for {@link #waiters}. + * + *

The creation of the updater has to happen directly inside {@link AbstractFuture}, as + * discussed in {@link #methodHandlesLookupFromWithinAbstractFuture}. + */ private static AtomicReferenceFieldUpdater, Waiter> waitersUpdaterFromWithinAbstractFuture() { return newUpdater(AbstractFuture.class, Waiter.class, "waiters"); } - /** Returns an {@link AtomicReferenceFieldUpdater} for {@link #listeners}. */ + /** + * Returns an {@link AtomicReferenceFieldUpdater} for {@link #listeners}. + * + *

The creation of the updater has to happen directly inside {@link AbstractFuture}, as + * discussed in {@link #methodHandlesLookupFromWithinAbstractFuture}. + */ private static AtomicReferenceFieldUpdater, Listener> listenersUpdaterFromWithinAbstractFuture() { return newUpdater(AbstractFuture.class, Listener.class, "listeners"); } - /** Returns an {@link AtomicReferenceFieldUpdater} for {@link #value}. */ + /** + * Returns an {@link AtomicReferenceFieldUpdater} for {@link #value}. + * + *

The creation of the updater has to happen directly inside {@link AbstractFuture}, as + * discussed in {@link #methodHandlesLookupFromWithinAbstractFuture}. + */ private static AtomicReferenceFieldUpdater, Object> valueUpdaterFromWithinAbstractFuture() { return newUpdater(AbstractFuture.class, Object.class, "value"); diff --git a/guava/src/com/google/common/util/concurrent/AggregateFutureState.java b/guava/src/com/google/common/util/concurrent/AggregateFutureState.java index eca2e4f713fcb..67af742248602 100644 --- a/guava/src/com/google/common/util/concurrent/AggregateFutureState.java +++ b/guava/src/com/google/common/util/concurrent/AggregateFutureState.java @@ -54,10 +54,7 @@ abstract class AggregateFutureState AtomicHelper helper; Throwable thrownReflectionFailure = null; try { - helper = - new SafeAtomicHelper( - newUpdater(AggregateFutureState.class, Set.class, "seenExceptions"), - newUpdater(AggregateFutureState.class, "remaining")); + helper = new SafeAtomicHelper(); } catch (Throwable reflectionFailure) { // sneaky checked exception // Some Android 5.0.x Samsung devices have bugs in JDK reflection APIs that cause // getDeclaredField to throw a NoSuchFieldException when the field is definitely there. @@ -156,20 +153,12 @@ abstract void compareAndSetSeenExceptions( } private static final class SafeAtomicHelper extends AtomicHelper { - final AtomicReferenceFieldUpdater< + private static final AtomicReferenceFieldUpdater< ? super AggregateFutureState, ? super @Nullable Set> - seenExceptionsUpdater; + seenExceptionsUpdater = seenExceptionsUpdaterFromWithinAggregateFutureState(); - final AtomicIntegerFieldUpdater> remainingCountUpdater; - - SafeAtomicHelper( - AtomicReferenceFieldUpdater< - ? super AggregateFutureState, ? super @Nullable Set> - seenExceptionsUpdater, - AtomicIntegerFieldUpdater> remainingCountUpdater) { - this.seenExceptionsUpdater = seenExceptionsUpdater; - this.remainingCountUpdater = remainingCountUpdater; - } + private static final AtomicIntegerFieldUpdater> + remainingCountUpdater = remainingCountUpdaterFromWithinAggregateFutureState(); @Override void compareAndSetSeenExceptions( @@ -201,4 +190,27 @@ int decrementAndGetRemainingCount(AggregateFutureState state) { } } } + + /** + * Returns an {@link AtomicReferenceFieldUpdater} for {@link #seenExceptions}. + * + *

The creation of the updater has to happen directly inside {@link AggregateFutureState}, as + * discussed in {@link AbstractFuture#methodHandlesLookupFromWithinAbstractFuture}. + */ + private static AtomicReferenceFieldUpdater< + ? super AggregateFutureState, ? super @Nullable Set> + seenExceptionsUpdaterFromWithinAggregateFutureState() { + return newUpdater(AggregateFutureState.class, Set.class, "seenExceptions"); + } + + /** + * Returns an {@link AtomicIntegerFieldUpdater} for {@link #remaining}. + * + *

The creation of the updater has to happen directly inside {@link AggregateFutureState}, as + * discussed in {@link AbstractFuture#methodHandlesLookupFromWithinAbstractFuture}. + */ + private static AtomicIntegerFieldUpdater> + remainingCountUpdaterFromWithinAggregateFutureState() { + return newUpdater(AggregateFutureState.class, "remaining"); + } }