jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicReferenceFieldUpdater.java
changeset 43207 569e0c1d851d
parent 42322 c3474fef4fe4
child 45518 4a116dd82fb5
equal deleted inserted replaced
43206:4c18d1166944 43207:569e0c1d851d
    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.