|
23 | 23 | import com.google.common.annotations.Beta;
|
24 | 24 | import com.google.common.annotations.GwtCompatible;
|
25 | 25 | import com.google.common.base.Throwables;
|
26 |
| -import com.google.errorprone.annotations.ForOverride; |
27 | 26 |
|
28 | 27 | import java.security.AccessController;
|
29 | 28 | import java.security.PrivilegedActionException;
|
@@ -110,7 +109,7 @@ abstract static class TrustedFuture<V> extends AbstractFuture<V> {
|
110 | 109 | static {
|
111 | 110 | AtomicHelper helper = null;
|
112 | 111 | try {
|
113 |
| - helper = new UnsafeAtomicHelper(); |
| 112 | + helper = UnsafeAtomicHelperFactory.values()[0].tryCreateUnsafeAtomicHelper(); |
114 | 113 | } catch (Throwable e) {
|
115 | 114 | // catch absolutely everything and fall through
|
116 | 115 | }
|
@@ -764,7 +763,6 @@ private void complete() {
|
764 | 763 | *
|
765 | 764 | * <p>This is called exactly once, after all listeners have executed. By default it does nothing.
|
766 | 765 | */
|
767 |
| - // TODO(cpovirk): @ForOverride if https://github.com/google/error-prone/issues/342 permits |
768 | 766 | void done() {}
|
769 | 767 |
|
770 | 768 | /**
|
@@ -848,12 +846,40 @@ private abstract static class AtomicHelper {
|
848 | 846 | abstract boolean casValue(AbstractFuture future, Object expected, Object v);
|
849 | 847 | }
|
850 | 848 |
|
| 849 | + /** |
| 850 | + * Temporary hack to hide the reference to {@link UnsafeAtomicHelper} from Android. The caller of |
| 851 | + * this code will execute {@link #tryCreateUnsafeAtomicHelper} on the <b>first</b> enum value |
| 852 | + * present. On the server, this will try to create {@link UnsafeAtomicHelper}. On Android, it will |
| 853 | + * just return {@code null}. |
| 854 | + */ |
| 855 | + private enum UnsafeAtomicHelperFactory { |
| 856 | + @SuppressUnderAndroid // temporarily while we make Proguard tolerate Unsafe |
| 857 | + REALLY_TRY_TO_CREATE { |
| 858 | + @Override |
| 859 | + AtomicHelper tryCreateUnsafeAtomicHelper() { |
| 860 | + return new UnsafeAtomicHelper(); |
| 861 | + } |
| 862 | + }, |
| 863 | + |
| 864 | + DONT_EVEN_TRY_TO_CREATE { |
| 865 | + @Override |
| 866 | + AtomicHelper tryCreateUnsafeAtomicHelper() { |
| 867 | + return null; |
| 868 | + } |
| 869 | + }, |
| 870 | + |
| 871 | + ; |
| 872 | + |
| 873 | + abstract AtomicHelper tryCreateUnsafeAtomicHelper(); |
| 874 | + } |
| 875 | + |
851 | 876 | /**
|
852 | 877 | * {@link AtomicHelper} based on {@link sun.misc.Unsafe}.
|
853 | 878 | *
|
854 | 879 | * <p>Static initialization of this class will fail if the {@link sun.misc.Unsafe} object cannot
|
855 | 880 | * be accessed.
|
856 | 881 | */
|
| 882 | + @SuppressUnderAndroid // temporarily while we make Proguard tolerate Unsafe |
857 | 883 | private static final class UnsafeAtomicHelper extends AtomicHelper {
|
858 | 884 | static final sun.misc.Unsafe UNSAFE;
|
859 | 885 | static final long LISTENERS_OFFSET;
|
@@ -899,26 +925,31 @@ private static final class UnsafeAtomicHelper extends AtomicHelper {
|
899 | 925 | }
|
900 | 926 | }
|
901 | 927 |
|
902 |
| - @Override void putThread(Waiter waiter, Thread thread) { |
| 928 | + @Override |
| 929 | + void putThread(Waiter waiter, Thread thread) { |
903 | 930 | UNSAFE.putObject(waiter, WAITER_THREAD_OFFSET, thread);
|
904 | 931 | }
|
905 | 932 |
|
906 |
| - @Override void putNext(Waiter waiter, Waiter next) { |
| 933 | + @Override |
| 934 | + void putNext(Waiter waiter, Waiter next) { |
907 | 935 | UNSAFE.putObject(waiter, WAITER_NEXT_OFFSET, next);
|
908 | 936 | }
|
909 | 937 |
|
910 | 938 | /** Performs a CAS operation on the {@link #waiters} field. */
|
911 |
| - @Override boolean casWaiters(AbstractFuture future, Waiter curr, Waiter next) { |
| 939 | + @Override |
| 940 | + boolean casWaiters(AbstractFuture future, Waiter curr, Waiter next) { |
912 | 941 | return UNSAFE.compareAndSwapObject(future, WAITERS_OFFSET, curr, next);
|
913 | 942 | }
|
914 | 943 |
|
915 | 944 | /** Performs a CAS operation on the {@link #listeners} field. */
|
916 |
| - @Override boolean casListeners(AbstractFuture future, Listener curr, Listener next) { |
| 945 | + @Override |
| 946 | + boolean casListeners(AbstractFuture future, Listener curr, Listener next) { |
917 | 947 | return UNSAFE.compareAndSwapObject(future, LISTENERS_OFFSET, curr, next);
|
918 | 948 | }
|
919 | 949 |
|
920 | 950 | /** Performs a CAS operation on the {@link #value} field. */
|
921 |
| - @Override boolean casValue(AbstractFuture future, Object expected, Object v) { |
| 951 | + @Override |
| 952 | + boolean casValue(AbstractFuture future, Object expected, Object v) { |
922 | 953 | return UNSAFE.compareAndSwapObject(future, VALUE_OFFSET, expected, v);
|
923 | 954 | }
|
924 | 955 | }
|
|
0 commit comments