jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicReferenceFieldUpdater.java
equal
deleted
inserted
replaced
38 import java.lang.reflect.Field; |
38 import java.lang.reflect.Field; |
39 import java.lang.reflect.Modifier; |
39 import java.lang.reflect.Modifier; |
40 import java.security.AccessController; |
40 import java.security.AccessController; |
41 import java.security.PrivilegedActionException; |
41 import java.security.PrivilegedActionException; |
42 import java.security.PrivilegedExceptionAction; |
42 import java.security.PrivilegedExceptionAction; |
|
43 import java.util.Objects; |
43 import java.util.function.BinaryOperator; |
44 import java.util.function.BinaryOperator; |
44 import java.util.function.UnaryOperator; |
45 import java.util.function.UnaryOperator; |
45 import jdk.internal.misc.Unsafe; |
46 import jdk.internal.misc.Unsafe; |
46 import jdk.internal.reflect.CallerSensitive; |
47 import jdk.internal.reflect.CallerSensitive; |
47 import jdk.internal.reflect.Reflection; |
48 import jdk.internal.reflect.Reflection; |
349 throw new IllegalArgumentException("Must be reference type"); |
350 throw new IllegalArgumentException("Must be reference type"); |
350 |
351 |
351 if (!Modifier.isVolatile(modifiers)) |
352 if (!Modifier.isVolatile(modifiers)) |
352 throw new IllegalArgumentException("Must be volatile type"); |
353 throw new IllegalArgumentException("Must be volatile type"); |
353 |
354 |
354 this.cclass = (Modifier.isProtected(modifiers)) ? caller : tclass; |
355 // Access to protected field members is restricted to receivers only |
|
356 // of the accessing class, or one of its subclasses, and the |
|
357 // accessing class must in turn be a subclass (or package sibling) |
|
358 // of the protected member's defining class. |
|
359 // If the updater refers to a protected field of a declaring class |
|
360 // outside the current package, the receiver argument will be |
|
361 // narrowed to the type of the accessing class. |
|
362 this.cclass = (Modifier.isProtected(modifiers) && |
|
363 tclass.isAssignableFrom(caller) && |
|
364 !isSamePackage(tclass, caller)) |
|
365 ? caller : tclass; |
355 this.tclass = tclass; |
366 this.tclass = tclass; |
356 this.vclass = vclass; |
367 this.vclass = vclass; |
357 this.offset = U.objectFieldOffset(field); |
368 this.offset = U.objectFieldOffset(field); |
358 } |
369 } |
359 |
370 |
369 if (second == acl) { |
380 if (second == acl) { |
370 return true; |
381 return true; |
371 } |
382 } |
372 } while (acl != null); |
383 } while (acl != null); |
373 return false; |
384 return false; |
|
385 } |
|
386 |
|
387 /** |
|
388 * Returns true if the two classes have the same class loader and |
|
389 * package qualifier |
|
390 */ |
|
391 private static boolean isSamePackage(Class<?> class1, Class<?> class2) { |
|
392 return class1.getClassLoader() == class2.getClassLoader() |
|
393 && Objects.equals(class1.getPackageName(), class2.getPackageName()); |
374 } |
394 } |
375 |
395 |
376 /** |
396 /** |
377 * Checks that target argument is instance of cclass. On |
397 * Checks that target argument is instance of cclass. On |
378 * failure, throws cause. |
398 * failure, throws cause. |