1 /*
2  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
3  *
4  * This code is free software; you can redistribute it and/or modify it
5  * under the terms of the GNU General Public License version 2 only, as
6  * published by the Free Software Foundation.  Oracle designates this
7  * particular file as subject to the "Classpath" exception as provided
8  * by Oracle in the LICENSE file that accompanied this code.
9  *
10  * This code is distributed in the hope that it will be useful, but WITHOUT
11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
13  * version 2 for more details (a copy is included in the LICENSE file that
14  * accompanied this code).
15  *
16  * You should have received a copy of the GNU General Public License version
17  * 2 along with this work; if not, write to the Free Software Foundation,
18  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19  *
20  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
21  * or visit www.oracle.com if you need additional information or have any
22  * questions.
23  */
24 
25 /*
26  * This file is available under and governed by the GNU General Public
27  * License version 2 only, as published by the Free Software Foundation.
28  * However, the following notice accompanied the original version of this
29  * file:
30  *
31  * Written by Doug Lea with assistance from members of JCP JSR-166
32  * Expert Group and released to the public domain, as explained at
33  * http://creativecommons.org/publicdomain/zero/1.0/
34  */
35 
36 package java.util.concurrent.atomic;
37 
38 import dalvik.system.VMStack; // Android-added
39 import java.lang.reflect.Field;
40 import java.lang.reflect.Modifier;
41 import java.security.AccessController;
42 import java.security.PrivilegedActionException;
43 import java.security.PrivilegedExceptionAction;
44 import java.util.function.BinaryOperator;
45 import java.util.function.UnaryOperator;
46 import sun.reflect.CallerSensitive;
47 import sun.reflect.Reflection;
48 
49 /**
50  * A reflection-based utility that enables atomic updates to
51  * designated {@code volatile} reference fields of designated
52  * classes.  This class is designed for use in atomic data structures
53  * in which several reference fields of the same node are
54  * independently subject to atomic updates. For example, a tree node
55  * might be declared as
56  *
57  * <pre> {@code
58  * class Node {
59  *   private volatile Node left, right;
60  *
61  *   private static final AtomicReferenceFieldUpdater<Node, Node> leftUpdater =
62  *     AtomicReferenceFieldUpdater.newUpdater(Node.class, Node.class, "left");
63  *   private static AtomicReferenceFieldUpdater<Node, Node> rightUpdater =
64  *     AtomicReferenceFieldUpdater.newUpdater(Node.class, Node.class, "right");
65  *
66  *   Node getLeft() { return left; }
67  *   boolean compareAndSetLeft(Node expect, Node update) {
68  *     return leftUpdater.compareAndSet(this, expect, update);
69  *   }
70  *   // ... and so on
71  * }}</pre>
72  *
73  * <p>Note that the guarantees of the {@code compareAndSet}
74  * method in this class are weaker than in other atomic classes.
75  * Because this class cannot ensure that all uses of the field
76  * are appropriate for purposes of atomic access, it can
77  * guarantee atomicity only with respect to other invocations of
78  * {@code compareAndSet} and {@code set} on the same updater.
79  *
80  * @since 1.5
81  * @author Doug Lea
82  * @param <T> The type of the object holding the updatable field
83  * @param <V> The type of the field
84  */
85 public abstract class AtomicReferenceFieldUpdater<T,V> {
86 
87     /**
88      * Creates and returns an updater for objects with the given field.
89      * The Class arguments are needed to check that reflective types and
90      * generic types match.
91      *
92      * @param tclass the class of the objects holding the field
93      * @param vclass the class of the field
94      * @param fieldName the name of the field to be updated
95      * @param <U> the type of instances of tclass
96      * @param <W> the type of instances of vclass
97      * @return the updater
98      * @throws ClassCastException if the field is of the wrong type
99      * @throws IllegalArgumentException if the field is not volatile
100      * @throws RuntimeException with a nested reflection-based
101      * exception if the class does not hold field or is the wrong type,
102      * or the field is inaccessible to the caller according to Java language
103      * access control
104      */
105     @CallerSensitive
newUpdater(Class<U> tclass, Class<W> vclass, String fieldName)106     public static <U,W> AtomicReferenceFieldUpdater<U,W> newUpdater(Class<U> tclass,
107                                                                     Class<W> vclass,
108                                                                     String fieldName) {
109         return new AtomicReferenceFieldUpdaterImpl<U,W>
110             (tclass, vclass, fieldName, VMStack.getStackClass1()); // Android-changed
111     }
112 
113     /**
114      * Protected do-nothing constructor for use by subclasses.
115      */
AtomicReferenceFieldUpdater()116     protected AtomicReferenceFieldUpdater() {
117     }
118 
119     /**
120      * Atomically sets the field of the given object managed by this updater
121      * to the given updated value if the current value {@code ==} the
122      * expected value. This method is guaranteed to be atomic with respect to
123      * other calls to {@code compareAndSet} and {@code set}, but not
124      * necessarily with respect to other changes in the field.
125      *
126      * @param obj An object whose field to conditionally set
127      * @param expect the expected value
128      * @param update the new value
129      * @return {@code true} if successful
130      */
compareAndSet(T obj, V expect, V update)131     public abstract boolean compareAndSet(T obj, V expect, V update);
132 
133     /**
134      * Atomically sets the field of the given object managed by this updater
135      * to the given updated value if the current value {@code ==} the
136      * expected value. This method is guaranteed to be atomic with respect to
137      * other calls to {@code compareAndSet} and {@code set}, but not
138      * necessarily with respect to other changes in the field.
139      *
140      * <p><a href="package-summary.html#weakCompareAndSet">May fail
141      * spuriously and does not provide ordering guarantees</a>, so is
142      * only rarely an appropriate alternative to {@code compareAndSet}.
143      *
144      * @param obj An object whose field to conditionally set
145      * @param expect the expected value
146      * @param update the new value
147      * @return {@code true} if successful
148      */
weakCompareAndSet(T obj, V expect, V update)149     public abstract boolean weakCompareAndSet(T obj, V expect, V update);
150 
151     /**
152      * Sets the field of the given object managed by this updater to the
153      * given updated value. This operation is guaranteed to act as a volatile
154      * store with respect to subsequent invocations of {@code compareAndSet}.
155      *
156      * @param obj An object whose field to set
157      * @param newValue the new value
158      */
set(T obj, V newValue)159     public abstract void set(T obj, V newValue);
160 
161     /**
162      * Eventually sets the field of the given object managed by this
163      * updater to the given updated value.
164      *
165      * @param obj An object whose field to set
166      * @param newValue the new value
167      * @since 1.6
168      */
lazySet(T obj, V newValue)169     public abstract void lazySet(T obj, V newValue);
170 
171     /**
172      * Gets the current value held in the field of the given object managed
173      * by this updater.
174      *
175      * @param obj An object whose field to get
176      * @return the current value
177      */
get(T obj)178     public abstract V get(T obj);
179 
180     /**
181      * Atomically sets the field of the given object managed by this updater
182      * to the given value and returns the old value.
183      *
184      * @param obj An object whose field to get and set
185      * @param newValue the new value
186      * @return the previous value
187      */
getAndSet(T obj, V newValue)188     public V getAndSet(T obj, V newValue) {
189         V prev;
190         do {
191             prev = get(obj);
192         } while (!compareAndSet(obj, prev, newValue));
193         return prev;
194     }
195 
196     /**
197      * Atomically updates the field of the given object managed by this updater
198      * with the results of applying the given function, returning the previous
199      * value. The function should be side-effect-free, since it may be
200      * re-applied when attempted updates fail due to contention among threads.
201      *
202      * @param obj An object whose field to get and set
203      * @param updateFunction a side-effect-free function
204      * @return the previous value
205      * @since 1.8
206      */
getAndUpdate(T obj, UnaryOperator<V> updateFunction)207     public final V getAndUpdate(T obj, UnaryOperator<V> updateFunction) {
208         V prev, next;
209         do {
210             prev = get(obj);
211             next = updateFunction.apply(prev);
212         } while (!compareAndSet(obj, prev, next));
213         return prev;
214     }
215 
216     /**
217      * Atomically updates the field of the given object managed by this updater
218      * with the results of applying the given function, returning the updated
219      * value. The function should be side-effect-free, since it may be
220      * re-applied when attempted updates fail due to contention among threads.
221      *
222      * @param obj An object whose field to get and set
223      * @param updateFunction a side-effect-free function
224      * @return the updated value
225      * @since 1.8
226      */
updateAndGet(T obj, UnaryOperator<V> updateFunction)227     public final V updateAndGet(T obj, UnaryOperator<V> updateFunction) {
228         V prev, next;
229         do {
230             prev = get(obj);
231             next = updateFunction.apply(prev);
232         } while (!compareAndSet(obj, prev, next));
233         return next;
234     }
235 
236     /**
237      * Atomically updates the field of the given object managed by this
238      * updater with the results of applying the given function to the
239      * current and given values, returning the previous value. The
240      * function should be side-effect-free, since it may be re-applied
241      * when attempted updates fail due to contention among threads.  The
242      * function is applied with the current value as its first argument,
243      * and the given update as the second argument.
244      *
245      * @param obj An object whose field to get and set
246      * @param x the update value
247      * @param accumulatorFunction a side-effect-free function of two arguments
248      * @return the previous value
249      * @since 1.8
250      */
getAndAccumulate(T obj, V x, BinaryOperator<V> accumulatorFunction)251     public final V getAndAccumulate(T obj, V x,
252                                     BinaryOperator<V> accumulatorFunction) {
253         V prev, next;
254         do {
255             prev = get(obj);
256             next = accumulatorFunction.apply(prev, x);
257         } while (!compareAndSet(obj, prev, next));
258         return prev;
259     }
260 
261     /**
262      * Atomically updates the field of the given object managed by this
263      * updater with the results of applying the given function to the
264      * current and given values, returning the updated value. The
265      * function should be side-effect-free, since it may be re-applied
266      * when attempted updates fail due to contention among threads.  The
267      * function is applied with the current value as its first argument,
268      * and the given update as the second argument.
269      *
270      * @param obj An object whose field to get and set
271      * @param x the update value
272      * @param accumulatorFunction a side-effect-free function of two arguments
273      * @return the updated value
274      * @since 1.8
275      */
accumulateAndGet(T obj, V x, BinaryOperator<V> accumulatorFunction)276     public final V accumulateAndGet(T obj, V x,
277                                     BinaryOperator<V> accumulatorFunction) {
278         V prev, next;
279         do {
280             prev = get(obj);
281             next = accumulatorFunction.apply(prev, x);
282         } while (!compareAndSet(obj, prev, next));
283         return next;
284     }
285 
286     private static final class AtomicReferenceFieldUpdaterImpl<T,V>
287         extends AtomicReferenceFieldUpdater<T,V> {
288         private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
289         private final long offset;
290         /**
291          * if field is protected, the subclass constructing updater, else
292          * the same as tclass
293          */
294         private final Class<?> cclass;
295         /** class holding the field */
296         private final Class<T> tclass;
297         /** field value type */
298         private final Class<V> vclass;
299 
300         /*
301          * Internal type checks within all update methods contain
302          * internal inlined optimizations checking for the common
303          * cases where the class is final (in which case a simple
304          * getClass comparison suffices) or is of type Object (in
305          * which case no check is needed because all objects are
306          * instances of Object). The Object case is handled simply by
307          * setting vclass to null in constructor.  The targetCheck and
308          * updateCheck methods are invoked when these faster
309          * screenings fail.
310          */
311 
AtomicReferenceFieldUpdaterImpl(final Class<T> tclass, final Class<V> vclass, final String fieldName, final Class<?> caller)312         AtomicReferenceFieldUpdaterImpl(final Class<T> tclass,
313                                         final Class<V> vclass,
314                                         final String fieldName,
315                                         final Class<?> caller) {
316             final Field field;
317             final Class<?> fieldClass;
318             final int modifiers;
319             try {
320                 field = tclass.getDeclaredField(fieldName); // Android-changed
321                 modifiers = field.getModifiers();
322                 // BEGIN Android-removed
323                 // sun.reflect.misc.ReflectUtil.ensureMemberAccess(
324                 //     caller, tclass, null, modifiers);
325                 // ClassLoader cl = tclass.getClassLoader();
326                 // ClassLoader ccl = caller.getClassLoader();
327                 // if ((ccl != null) && (ccl != cl) &&
328                 //     ((cl == null) || !isAncestor(cl, ccl))) {
329                 //     sun.reflect.misc.ReflectUtil.checkPackageAccess(tclass);
330                 // }
331                 // END Android-removed
332                 fieldClass = field.getType();
333             // BEGIN Android-removed
334             // } catch (PrivilegedActionException pae) {
335             //     throw new RuntimeException(pae.getException());
336             // END Android-removed
337             } catch (Exception ex) {
338                 throw new RuntimeException(ex);
339             }
340 
341             if (vclass != fieldClass)
342                 throw new ClassCastException();
343             if (vclass.isPrimitive())
344                 throw new IllegalArgumentException("Must be reference type");
345 
346             if (!Modifier.isVolatile(modifiers))
347                 throw new IllegalArgumentException("Must be volatile type");
348 
349             this.cclass = (Modifier.isProtected(modifiers)) ? caller : tclass;
350             this.tclass = tclass;
351             this.vclass = vclass;
352             this.offset = U.objectFieldOffset(field);
353         }
354 
355         // BEGIN Android-removed
356         // /**
357         //  * Returns true if the second classloader can be found in the first
358         //  * classloader's delegation chain.
359         //  * Equivalent to the inaccessible: first.isAncestor(second).
360         //  */
361         // private static boolean isAncestor(ClassLoader first, ClassLoader second) {
362         //     ClassLoader acl = first;
363         //     do {
364         //         acl = acl.getParent();
365         //         if (second == acl) {
366         //             return true;
367         //         }
368         //     } while (acl != null);
369         //     return false;
370         // }
371         // END Android-removed
372 
373         /**
374          * Checks that target argument is instance of cclass.  On
375          * failure, throws cause.
376          */
accessCheck(T obj)377         private final void accessCheck(T obj) {
378             if (!cclass.isInstance(obj))
379                 throwAccessCheckException(obj);
380         }
381 
382         /**
383          * Throws access exception if accessCheck failed due to
384          * protected access, else ClassCastException.
385          */
throwAccessCheckException(T obj)386         private final void throwAccessCheckException(T obj) {
387             if (cclass == tclass)
388                 throw new ClassCastException();
389             else
390                 throw new RuntimeException(
391                     new IllegalAccessException(
392                         "Class " +
393                         cclass.getName() +
394                         " can not access a protected member of class " +
395                         tclass.getName() +
396                         " using an instance of " +
397                         obj.getClass().getName()));
398         }
399 
valueCheck(V v)400         private final void valueCheck(V v) {
401             if (v != null && !(vclass.isInstance(v)))
402                 throwCCE();
403         }
404 
throwCCE()405         static void throwCCE() {
406             throw new ClassCastException();
407         }
408 
compareAndSet(T obj, V expect, V update)409         public final boolean compareAndSet(T obj, V expect, V update) {
410             accessCheck(obj);
411             valueCheck(update);
412             return U.compareAndSwapObject(obj, offset, expect, update);
413         }
414 
weakCompareAndSet(T obj, V expect, V update)415         public final boolean weakCompareAndSet(T obj, V expect, V update) {
416             // same implementation as strong form for now
417             accessCheck(obj);
418             valueCheck(update);
419             return U.compareAndSwapObject(obj, offset, expect, update);
420         }
421 
set(T obj, V newValue)422         public final void set(T obj, V newValue) {
423             accessCheck(obj);
424             valueCheck(newValue);
425             U.putObjectVolatile(obj, offset, newValue);
426         }
427 
lazySet(T obj, V newValue)428         public final void lazySet(T obj, V newValue) {
429             accessCheck(obj);
430             valueCheck(newValue);
431             U.putOrderedObject(obj, offset, newValue);
432         }
433 
434         @SuppressWarnings("unchecked")
get(T obj)435         public final V get(T obj) {
436             accessCheck(obj);
437             return (V)U.getObjectVolatile(obj, offset);
438         }
439 
440         @SuppressWarnings("unchecked")
getAndSet(T obj, V newValue)441         public final V getAndSet(T obj, V newValue) {
442             accessCheck(obj);
443             valueCheck(newValue);
444             return (V)U.getAndSetObject(obj, offset, newValue);
445         }
446     }
447 }
448