提交 ff5fc86c 编写于 作者: R robm

8165344: Update concurrency support

Reviewed-by: psandoz
上级 dd8c83f2
...@@ -40,6 +40,7 @@ import java.lang.reflect.Modifier; ...@@ -40,6 +40,7 @@ import java.lang.reflect.Modifier;
import java.security.AccessController; import java.security.AccessController;
import java.security.PrivilegedActionException; import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction; import java.security.PrivilegedExceptionAction;
import java.util.Objects;
import java.util.function.IntBinaryOperator; import java.util.function.IntBinaryOperator;
import java.util.function.IntUnaryOperator; import java.util.function.IntUnaryOperator;
import sun.reflect.CallerSensitive; import sun.reflect.CallerSensitive;
...@@ -410,7 +411,17 @@ public abstract class AtomicIntegerFieldUpdater<T> { ...@@ -410,7 +411,17 @@ public abstract class AtomicIntegerFieldUpdater<T> {
if (!Modifier.isVolatile(modifiers)) if (!Modifier.isVolatile(modifiers))
throw new IllegalArgumentException("Must be volatile type"); throw new IllegalArgumentException("Must be volatile type");
this.cclass = (Modifier.isProtected(modifiers)) ? caller : tclass; // Access to protected field members is restricted to receivers only
// of the accessing class, or one of its subclasses, and the
// accessing class must in turn be a subclass (or package sibling)
// of the protected member's defining class.
// If the updater refers to a protected field of a declaring class
// outside the current package, the receiver argument will be
// narrowed to the type of the accessing class.
this.cclass = (Modifier.isProtected(modifiers) &&
tclass.isAssignableFrom(caller) &&
!isSamePackage(tclass, caller))
? caller : tclass;
this.tclass = tclass; this.tclass = tclass;
this.offset = U.objectFieldOffset(field); this.offset = U.objectFieldOffset(field);
} }
...@@ -431,6 +442,21 @@ public abstract class AtomicIntegerFieldUpdater<T> { ...@@ -431,6 +442,21 @@ public abstract class AtomicIntegerFieldUpdater<T> {
return false; return false;
} }
/**
* Returns true if the two classes have the same class loader and
* package qualifier
*/
private static boolean isSamePackage(Class<?> class1, Class<?> class2) {
return class1.getClassLoader() == class2.getClassLoader()
&& Objects.equals(getPackageName(class1), getPackageName(class2));
}
private static String getPackageName(Class<?> cls) {
String cn = cls.getName();
int dot = cn.lastIndexOf('.');
return (dot != -1) ? cn.substring(0, dot) : "";
}
/** /**
* Checks that target argument is instance of cclass. On * Checks that target argument is instance of cclass. On
* failure, throws cause. * failure, throws cause.
......
...@@ -40,6 +40,7 @@ import java.lang.reflect.Modifier; ...@@ -40,6 +40,7 @@ import java.lang.reflect.Modifier;
import java.security.AccessController; import java.security.AccessController;
import java.security.PrivilegedActionException; import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction; import java.security.PrivilegedExceptionAction;
import java.util.Objects;
import java.util.function.LongBinaryOperator; import java.util.function.LongBinaryOperator;
import java.util.function.LongUnaryOperator; import java.util.function.LongUnaryOperator;
import sun.reflect.CallerSensitive; import sun.reflect.CallerSensitive;
...@@ -408,7 +409,17 @@ public abstract class AtomicLongFieldUpdater<T> { ...@@ -408,7 +409,17 @@ public abstract class AtomicLongFieldUpdater<T> {
if (!Modifier.isVolatile(modifiers)) if (!Modifier.isVolatile(modifiers))
throw new IllegalArgumentException("Must be volatile type"); throw new IllegalArgumentException("Must be volatile type");
this.cclass = (Modifier.isProtected(modifiers)) ? caller : tclass; // Access to protected field members is restricted to receivers only
// of the accessing class, or one of its subclasses, and the
// accessing class must in turn be a subclass (or package sibling)
// of the protected member's defining class.
// If the updater refers to a protected field of a declaring class
// outside the current package, the receiver argument will be
// narrowed to the type of the accessing class.
this.cclass = (Modifier.isProtected(modifiers) &&
tclass.isAssignableFrom(caller) &&
!isSamePackage(tclass, caller))
? caller : tclass;
this.tclass = tclass; this.tclass = tclass;
this.offset = U.objectFieldOffset(field); this.offset = U.objectFieldOffset(field);
} }
...@@ -539,7 +550,17 @@ public abstract class AtomicLongFieldUpdater<T> { ...@@ -539,7 +550,17 @@ public abstract class AtomicLongFieldUpdater<T> {
if (!Modifier.isVolatile(modifiers)) if (!Modifier.isVolatile(modifiers))
throw new IllegalArgumentException("Must be volatile type"); throw new IllegalArgumentException("Must be volatile type");
this.cclass = (Modifier.isProtected(modifiers)) ? caller : tclass; // Access to protected field members is restricted to receivers only
// of the accessing class, or one of its subclasses, and the
// accessing class must in turn be a subclass (or package sibling)
// of the protected member's defining class.
// If the updater refers to a protected field of a declaring class
// outside the current package, the receiver argument will be
// narrowed to the type of the accessing class.
this.cclass = (Modifier.isProtected(modifiers) &&
tclass.isAssignableFrom(caller) &&
!isSamePackage(tclass, caller))
? caller : tclass;
this.tclass = tclass; this.tclass = tclass;
this.offset = U.objectFieldOffset(field); this.offset = U.objectFieldOffset(field);
} }
...@@ -620,4 +641,19 @@ public abstract class AtomicLongFieldUpdater<T> { ...@@ -620,4 +641,19 @@ public abstract class AtomicLongFieldUpdater<T> {
} while (acl != null); } while (acl != null);
return false; return false;
} }
/**
* Returns true if the two classes have the same class loader and
* package qualifier
*/
private static boolean isSamePackage(Class<?> class1, Class<?> class2) {
return class1.getClassLoader() == class2.getClassLoader()
&& Objects.equals(getPackageName(class1), getPackageName(class2));
}
private static String getPackageName(Class<?> cls) {
String cn = cls.getName();
int dot = cn.lastIndexOf('.');
return (dot != -1) ? cn.substring(0, dot) : "";
}
} }
...@@ -40,6 +40,7 @@ import java.lang.reflect.Modifier; ...@@ -40,6 +40,7 @@ import java.lang.reflect.Modifier;
import java.security.AccessController; import java.security.AccessController;
import java.security.PrivilegedActionException; import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction; import java.security.PrivilegedExceptionAction;
import java.util.Objects;
import java.util.function.BinaryOperator; import java.util.function.BinaryOperator;
import java.util.function.UnaryOperator; import java.util.function.UnaryOperator;
import sun.reflect.CallerSensitive; import sun.reflect.CallerSensitive;
...@@ -346,7 +347,17 @@ public abstract class AtomicReferenceFieldUpdater<T,V> { ...@@ -346,7 +347,17 @@ public abstract class AtomicReferenceFieldUpdater<T,V> {
if (!Modifier.isVolatile(modifiers)) if (!Modifier.isVolatile(modifiers))
throw new IllegalArgumentException("Must be volatile type"); throw new IllegalArgumentException("Must be volatile type");
this.cclass = (Modifier.isProtected(modifiers)) ? caller : tclass; // Access to protected field members is restricted to receivers only
// of the accessing class, or one of its subclasses, and the
// accessing class must in turn be a subclass (or package sibling)
// of the protected member's defining class.
// If the updater refers to a protected field of a declaring class
// outside the current package, the receiver argument will be
// narrowed to the type of the accessing class.
this.cclass = (Modifier.isProtected(modifiers) &&
tclass.isAssignableFrom(caller) &&
!isSamePackage(tclass, caller))
? caller : tclass;
this.tclass = tclass; this.tclass = tclass;
this.vclass = vclass; this.vclass = vclass;
this.offset = U.objectFieldOffset(field); this.offset = U.objectFieldOffset(field);
...@@ -368,6 +379,21 @@ public abstract class AtomicReferenceFieldUpdater<T,V> { ...@@ -368,6 +379,21 @@ public abstract class AtomicReferenceFieldUpdater<T,V> {
return false; return false;
} }
/**
* Returns true if the two classes have the same class loader and
* package qualifier
*/
private static boolean isSamePackage(Class<?> class1, Class<?> class2) {
return class1.getClassLoader() == class2.getClassLoader()
&& Objects.equals(getPackageName(class1), getPackageName(class2));
}
private static String getPackageName(Class<?> cls) {
String cn = cls.getName();
int dot = cn.lastIndexOf('.');
return (dot != -1) ? cn.substring(0, dot) : "";
}
/** /**
* Checks that target argument is instance of cclass. On * Checks that target argument is instance of cclass. On
* failure, throws cause. * failure, throws cause.
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册