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 java.lang.reflect.Field;
  39 import java.lang.reflect.Modifier;
  40 import java.security.AccessController;
  41 import java.security.PrivilegedActionException;
  42 import java.security.PrivilegedExceptionAction;
  43 import java.util.Objects;
  44 import java.util.function.BinaryOperator;
  45 import java.util.function.UnaryOperator;
  46 import jdk.internal.misc.Unsafe;
  47 import jdk.internal.reflect.CallerSensitive;
  48 import jdk.internal.reflect.Reflection;
  49 import java.lang.invoke.VarHandle;
  50 
  51 /**
  52  * A reflection-based utility that enables atomic updates to
  53  * designated {@code volatile} reference fields of designated
  54  * classes.  This class is designed for use in atomic data structures
  55  * in which several reference fields of the same node are
  56  * independently subject to atomic updates. For example, a tree node
  57  * might be declared as
  58  *
  59  * <pre> {@code
  60  * class Node {
  61  *   private volatile Node left, right;
  62  *
  63  *   private static final AtomicReferenceFieldUpdater<Node, Node> leftUpdater =
  64  *     AtomicReferenceFieldUpdater.newUpdater(Node.class, Node.class, "left");
  65  *   private static final AtomicReferenceFieldUpdater<Node, Node> rightUpdater =
  66  *     AtomicReferenceFieldUpdater.newUpdater(Node.class, Node.class, "right");
  67  *
  68  *   Node getLeft() { return left; }
  69  *   boolean compareAndSetLeft(Node expect, Node update) {
  70  *     return leftUpdater.compareAndSet(this, expect, update);
  71  *   }
  72  *   // ... and so on
  73  * }}</pre>
  74  *
  75  * <p>Note that the guarantees of the {@code compareAndSet}
  76  * method in this class are weaker than in other atomic classes.
  77  * Because this class cannot ensure that all uses of the field
  78  * are appropriate for purposes of atomic access, it can
  79  * guarantee atomicity only with respect to other invocations of
  80  * {@code compareAndSet} and {@code set} on the same updater.
  81  *
  82  * <p>Object arguments for parameters of type {@code T} that are not
  83  * instances of the class passed to {@link #newUpdater} will result in
  84  * a {@link ClassCastException} being thrown.
  85  *
  86  * @since 1.5
  87  * @author Doug Lea
  88  * @param <T> The type of the object holding the updatable field
  89  * @param <V> The type of the field
  90  */
  91 public abstract class AtomicReferenceFieldUpdater<T,V> {
  92 
  93     /**
  94      * Creates and returns an updater for objects with the given field.
  95      * The Class arguments are needed to check that reflective types and
  96      * generic types match.
  97      *
  98      * @param tclass the class of the objects holding the field
  99      * @param vclass the class of the field
 100      * @param fieldName the name of the field to be updated
 101      * @param <U> the type of instances of tclass
 102      * @param <W> the type of instances of vclass
 103      * @return the updater
 104      * @throws ClassCastException if the field is of the wrong type
 105      * @throws IllegalArgumentException if the field is not volatile
 106      * @throws RuntimeException with a nested reflection-based
 107      * exception if the class does not hold field or is the wrong type,
 108      * or the field is inaccessible to the caller according to Java language
 109      * access control
 110      */
 111     @CallerSensitive
 112     public static <U,W> AtomicReferenceFieldUpdater<U,W> newUpdater(Class<U> tclass,
 113                                                                     Class<W> vclass,
 114                                                                     String fieldName) {
 115         return new AtomicReferenceFieldUpdaterImpl<U,W>
 116             (tclass, vclass, fieldName, Reflection.getCallerClass());
 117     }
 118 
 119     /**
 120      * Protected do-nothing constructor for use by subclasses.
 121      */
 122     protected AtomicReferenceFieldUpdater() {
 123     }
 124 
 125     /**
 126      * Atomically sets the field of the given object managed by this updater
 127      * to the given updated value if the current value {@code ==} the
 128      * expected value. This method is guaranteed to be atomic with respect to
 129      * other calls to {@code compareAndSet} and {@code set}, but not
 130      * necessarily with respect to other changes in the field.
 131      *
 132      * @param obj An object whose field to conditionally set
 133      * @param expect the expected value
 134      * @param update the new value
 135      * @return {@code true} if successful
 136      */
 137     public abstract boolean compareAndSet(T obj, V expect, V update);
 138 
 139     /**
 140      * Atomically sets the field of the given object managed by this updater
 141      * to the given updated value if the current value {@code ==} the
 142      * expected value. This method is guaranteed to be atomic with respect to
 143      * other calls to {@code compareAndSet} and {@code set}, but not
 144      * necessarily with respect to other changes in the field.
 145      *
 146      * <p>This operation may fail spuriously and does not provide
 147      * ordering guarantees, so is only rarely an appropriate
 148      * alternative to {@code compareAndSet}.
 149      *
 150      * @param obj An object whose field to conditionally set
 151      * @param expect the expected value
 152      * @param update the new value
 153      * @return {@code true} if successful
 154      */
 155     public abstract boolean weakCompareAndSet(T obj, V expect, V update);
 156 
 157     /**
 158      * Sets the field of the given object managed by this updater to the
 159      * given updated value. This operation is guaranteed to act as a volatile
 160      * store with respect to subsequent invocations of {@code compareAndSet}.
 161      *
 162      * @param obj An object whose field to set
 163      * @param newValue the new value
 164      */
 165     public abstract void set(T obj, V newValue);
 166 
 167     /**
 168      * Eventually sets the field of the given object managed by this
 169      * updater to the given updated value.
 170      *
 171      * @param obj An object whose field to set
 172      * @param newValue the new value
 173      * @since 1.6
 174      */
 175     public abstract void lazySet(T obj, V newValue);
 176 
 177     /**
 178      * Returns the current value held in the field of the given object
 179      * managed by this updater.
 180      *
 181      * @param obj An object whose field to get
 182      * @return the current value
 183      */
 184     public abstract V get(T obj);
 185 
 186     /**
 187      * Atomically sets the field of the given object managed by this updater
 188      * to the given value and returns the old value.
 189      *
 190      * @param obj An object whose field to get and set
 191      * @param newValue the new value
 192      * @return the previous value
 193      */
 194     public V getAndSet(T obj, V newValue) {
 195         V prev;
 196         do {
 197             prev = get(obj);
 198         } while (!compareAndSet(obj, prev, newValue));
 199         return prev;
 200     }
 201 
 202     /**
 203      * Atomically updates (with memory effects as specified by {@link
 204      * VarHandle#compareAndSet}) the field of the given object managed
 205      * by this updater with the results of applying the given
 206      * function, returning the previous value. The function should be
 207      * side-effect-free, since it may be re-applied when attempted
 208      * updates fail due to contention among threads.
 209      *
 210      * @param obj An object whose field to get and set
 211      * @param updateFunction a side-effect-free function
 212      * @return the previous value
 213      * @since 1.8
 214      */
 215     public final V getAndUpdate(T obj, UnaryOperator<V> updateFunction) {
 216         V prev, next;
 217         do {
 218             prev = get(obj);
 219             next = updateFunction.apply(prev);
 220         } while (!compareAndSet(obj, prev, next));
 221         return prev;
 222     }
 223 
 224     /**
 225      * Atomically updates (with memory effects as specified by {@link
 226      * VarHandle#compareAndSet}) the field of the given object managed
 227      * by this updater with the results of applying the given
 228      * function, returning the updated value. The function should be
 229      * side-effect-free, since it may be re-applied when attempted
 230      * updates fail due to contention among threads.
 231      *
 232      * @param obj An object whose field to get and set
 233      * @param updateFunction a side-effect-free function
 234      * @return the updated value
 235      * @since 1.8
 236      */
 237     public final V updateAndGet(T obj, UnaryOperator<V> updateFunction) {
 238         V prev, next;
 239         do {
 240             prev = get(obj);
 241             next = updateFunction.apply(prev);
 242         } while (!compareAndSet(obj, prev, next));
 243         return next;
 244     }
 245 
 246     /**
 247      * Atomically updates (with memory effects as specified by {@link
 248      * VarHandle#compareAndSet}) the field of the given object managed
 249      * by this updater with the results of applying the given function
 250      * to the current and given values, returning the previous value.
 251      * The function should be side-effect-free, since it may be
 252      * re-applied when attempted updates fail due to contention among
 253      * threads.  The function is applied with the current value as its
 254      * first argument, and the given update as the second argument.
 255      *
 256      * @param obj An object whose field to get and set
 257      * @param x the update value
 258      * @param accumulatorFunction a side-effect-free function of two arguments
 259      * @return the previous value
 260      * @since 1.8
 261      */
 262     public final V getAndAccumulate(T obj, V x,
 263                                     BinaryOperator<V> accumulatorFunction) {
 264         V prev, next;
 265         do {
 266             prev = get(obj);
 267             next = accumulatorFunction.apply(prev, x);
 268         } while (!compareAndSet(obj, prev, next));
 269         return prev;
 270     }
 271 
 272     /**
 273      * Atomically updates (with memory effects as specified by {@link
 274      * VarHandle#compareAndSet}) the field of the given object managed
 275      * by this updater with the results of applying the given function
 276      * to the current and given values, returning the updated value.
 277      * The function should be side-effect-free, since it may be
 278      * re-applied when attempted updates fail due to contention among
 279      * threads.  The function is applied with the current value as its
 280      * first argument, and the given update as the second argument.
 281      *
 282      * @param obj An object whose field to get and set
 283      * @param x the update value
 284      * @param accumulatorFunction a side-effect-free function of two arguments
 285      * @return the updated value
 286      * @since 1.8
 287      */
 288     public final V accumulateAndGet(T obj, V x,
 289                                     BinaryOperator<V> accumulatorFunction) {
 290         V prev, next;
 291         do {
 292             prev = get(obj);
 293             next = accumulatorFunction.apply(prev, x);
 294         } while (!compareAndSet(obj, prev, next));
 295         return next;
 296     }
 297 
 298     private static final class AtomicReferenceFieldUpdaterImpl<T,V>
 299         extends AtomicReferenceFieldUpdater<T,V> {
 300         private static final Unsafe U = Unsafe.getUnsafe();
 301         private final long offset;
 302         /**
 303          * if field is protected, the subclass constructing updater, else
 304          * the same as tclass
 305          */
 306         private final Class<?> cclass;
 307         /** class holding the field */
 308         private final Class<T> tclass;
 309         /** field value type */
 310         private final Class<V> vclass;
 311 
 312         /*
 313          * Internal type checks within all update methods contain
 314          * internal inlined optimizations checking for the common
 315          * cases where the class is final (in which case a simple
 316          * getClass comparison suffices) or is of type Object (in
 317          * which case no check is needed because all objects are
 318          * instances of Object). The Object case is handled simply by
 319          * setting vclass to null in constructor.  The targetCheck and
 320          * updateCheck methods are invoked when these faster
 321          * screenings fail.
 322          */
 323 
 324         AtomicReferenceFieldUpdaterImpl(final Class<T> tclass,
 325                                         final Class<V> vclass,
 326                                         final String fieldName,
 327                                         final Class<?> caller) {
 328             final Field field;
 329             final Class<?> fieldClass;
 330             final int modifiers;
 331             try {
 332                 field = AccessController.doPrivileged(
 333                     new PrivilegedExceptionAction<Field>() {
 334                         public Field run() throws NoSuchFieldException {
 335                             return tclass.getDeclaredField(fieldName);
 336                         }
 337                     });
 338                 modifiers = field.getModifiers();
 339                 sun.reflect.misc.ReflectUtil.ensureMemberAccess(
 340                     caller, tclass, null, modifiers);
 341                 ClassLoader cl = tclass.getClassLoader();
 342                 ClassLoader ccl = caller.getClassLoader();
 343                 if ((ccl != null) && (ccl != cl) &&
 344                     ((cl == null) || !isAncestor(cl, ccl))) {
 345                     sun.reflect.misc.ReflectUtil.checkPackageAccess(tclass);
 346                 }
 347                 fieldClass = field.getType();
 348             } catch (PrivilegedActionException pae) {
 349                 throw new RuntimeException(pae.getException());
 350             } catch (Exception ex) {
 351                 throw new RuntimeException(ex);
 352             }
 353 
 354             if (vclass != fieldClass)
 355                 throw new ClassCastException();
 356             if (vclass.isPrimitive())
 357                 throw new IllegalArgumentException("Must be reference type");
 358 
 359             if (!Modifier.isVolatile(modifiers))
 360                 throw new IllegalArgumentException("Must be volatile type");
 361 
 362             // Access to protected field members is restricted to receivers only
 363             // of the accessing class, or one of its subclasses, and the
 364             // accessing class must in turn be a subclass (or package sibling)
 365             // of the protected member's defining class.
 366             // If the updater refers to a protected field of a declaring class
 367             // outside the current package, the receiver argument will be
 368             // narrowed to the type of the accessing class.
 369             this.cclass = (Modifier.isProtected(modifiers) &&
 370                            tclass.isAssignableFrom(caller) &&
 371                            !isSamePackage(tclass, caller))
 372                           ? caller : tclass;
 373             this.tclass = tclass;
 374             this.vclass = vclass;
 375             this.offset = U.objectFieldOffset(field);
 376         }
 377 
 378         /**
 379          * Returns true if the second classloader can be found in the first
 380          * classloader's delegation chain.
 381          * Equivalent to the inaccessible: first.isAncestor(second).
 382          */
 383         private static boolean isAncestor(ClassLoader first, ClassLoader second) {
 384             ClassLoader acl = first;
 385             do {
 386                 acl = acl.getParent();
 387                 if (second == acl) {
 388                     return true;
 389                 }
 390             } while (acl != null);
 391             return false;
 392         }
 393 
 394         /**
 395          * Returns true if the two classes have the same class loader and
 396          * package qualifier
 397          */
 398         private static boolean isSamePackage(Class<?> class1, Class<?> class2) {
 399             return class1.getClassLoader() == class2.getClassLoader()
 400                    && Objects.equals(class1.getPackageName(), class2.getPackageName());
 401         }
 402 
 403         /**
 404          * Checks that target argument is instance of cclass.  On
 405          * failure, throws cause.
 406          */
 407         private final void accessCheck(T obj) {
 408             if (!cclass.isInstance(obj))
 409                 throwAccessCheckException(obj);
 410         }
 411 
 412         /**
 413          * Throws access exception if accessCheck failed due to
 414          * protected access, else ClassCastException.
 415          */
 416         private final void throwAccessCheckException(T obj) {
 417             if (cclass == tclass)
 418                 throw new ClassCastException();
 419             else
 420                 throw new RuntimeException(
 421                     new IllegalAccessException(
 422                         "Class " +
 423                         cclass.getName() +
 424                         " can not access a protected member of class " +
 425                         tclass.getName() +
 426                         " using an instance of " +
 427                         obj.getClass().getName()));
 428         }
 429 
 430         private final void valueCheck(V v) {
 431             if (v != null && !(vclass.isInstance(v)))
 432                 throwCCE();
 433         }
 434 
 435         static void throwCCE() {
 436             throw new ClassCastException();
 437         }
 438 
 439         public final boolean compareAndSet(T obj, V expect, V update) {
 440             accessCheck(obj);
 441             valueCheck(update);
 442             return U.compareAndSetReference(obj, offset, expect, update);
 443         }
 444 
 445         public final boolean weakCompareAndSet(T obj, V expect, V update) {
 446             // same implementation as strong form for now
 447             accessCheck(obj);
 448             valueCheck(update);
 449             return U.compareAndSetReference(obj, offset, expect, update);
 450         }
 451 
 452         public final void set(T obj, V newValue) {
 453             accessCheck(obj);
 454             valueCheck(newValue);
 455             U.putReferenceVolatile(obj, offset, newValue);
 456         }
 457 
 458         public final void lazySet(T obj, V newValue) {
 459             accessCheck(obj);
 460             valueCheck(newValue);
 461             U.putReferenceRelease(obj, offset, newValue);
 462         }
 463 
 464         @SuppressWarnings("unchecked")
 465         public final V get(T obj) {
 466             accessCheck(obj);
 467             return (V)U.getReferenceVolatile(obj, offset);
 468         }
 469 
 470         @SuppressWarnings("unchecked")
 471         public final V getAndSet(T obj, V newValue) {
 472             accessCheck(obj);
 473             valueCheck(newValue);
 474             return (V)U.getAndSetReference(obj, offset, newValue);
 475         }
 476     }
 477 }