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 36package java.util.concurrent.atomic; 37 38import dalvik.system.VMStack; // Android-added 39import java.lang.reflect.Field; 40import java.lang.reflect.Modifier; 41import java.security.AccessController; 42import java.security.PrivilegedActionException; 43import java.security.PrivilegedExceptionAction; 44import java.util.function.BinaryOperator; 45import java.util.function.UnaryOperator; 46import sun.reflect.CallerSensitive; 47import 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 */ 85public 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 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 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 */ 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 */ 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 400 private final void valueCheck(V v) { 401 if (v != null && !(vclass.isInstance(v))) 402 throwCCE(); 403 } 404 405 static void throwCCE() { 406 throw new ClassCastException(); 407 } 408 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 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 422 public final void set(T obj, V newValue) { 423 accessCheck(obj); 424 valueCheck(newValue); 425 U.putObjectVolatile(obj, offset, newValue); 426 } 427 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") 435 public final V get(T obj) { 436 accessCheck(obj); 437 return (V)U.getObjectVolatile(obj, offset); 438 } 439 440 @SuppressWarnings("unchecked") 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