Fix concurrent access issues in CallableReference implementations
Because of multiple reads from the same non-volatile variable, NPE was possible to achieve in a multi-threaded application
This commit is contained in:
@@ -122,17 +122,19 @@ public abstract class CallableReference implements KCallable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public KCallable compute() {
|
public KCallable compute() {
|
||||||
if (reflected == null) {
|
KCallable result = reflected;
|
||||||
reflected = computeReflected();
|
if (result == null) {
|
||||||
|
result = computeReflected();
|
||||||
|
reflected = result;
|
||||||
}
|
}
|
||||||
return reflected;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected KCallable getReflected() {
|
protected KCallable getReflected() {
|
||||||
compute();
|
KCallable result = compute();
|
||||||
if (reflected == this) {
|
if (result == this) {
|
||||||
throw new KotlinReflectionNotSupportedError();
|
throw new KotlinReflectionNotSupportedError();
|
||||||
}
|
}
|
||||||
return reflected;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -146,8 +146,7 @@ public class FunctionReference extends FunctionImpl implements KFunction {
|
|||||||
getSignature().equals(other.getSignature());
|
getSignature().equals(other.getSignature());
|
||||||
}
|
}
|
||||||
if (obj instanceof KFunction) {
|
if (obj instanceof KFunction) {
|
||||||
compute();
|
return obj.equals(compute());
|
||||||
return obj.equals(reflected);
|
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -159,7 +158,7 @@ public class FunctionReference extends FunctionImpl implements KFunction {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
compute();
|
KFunction reflected = compute();
|
||||||
if (reflected != this) {
|
if (reflected != this) {
|
||||||
return reflected.toString();
|
return reflected.toString();
|
||||||
}
|
}
|
||||||
@@ -171,17 +170,19 @@ public class FunctionReference extends FunctionImpl implements KFunction {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public KFunction compute() {
|
public KFunction compute() {
|
||||||
if (reflected == null) {
|
KFunction result = reflected;
|
||||||
reflected = Reflection.function(this);
|
if (result == null) {
|
||||||
|
result = Reflection.function(this);
|
||||||
|
reflected = result;
|
||||||
}
|
}
|
||||||
return reflected;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private KFunction getReflected() {
|
private KFunction getReflected() {
|
||||||
compute();
|
KFunction result = compute();
|
||||||
if (reflected == this) {
|
if (result == this) {
|
||||||
throw new KotlinReflectionNotSupportedError();
|
throw new KotlinReflectionNotSupportedError();
|
||||||
}
|
}
|
||||||
return reflected;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
package kotlin.jvm.internal;
|
package kotlin.jvm.internal;
|
||||||
|
|
||||||
|
import kotlin.reflect.KCallable;
|
||||||
import kotlin.reflect.KProperty;
|
import kotlin.reflect.KProperty;
|
||||||
|
|
||||||
public abstract class PropertyReference extends CallableReference implements KProperty {
|
public abstract class PropertyReference extends CallableReference implements KProperty {
|
||||||
@@ -57,7 +58,7 @@ public abstract class PropertyReference extends CallableReference implements KPr
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
compute();
|
KCallable reflected = compute();
|
||||||
if (reflected != this) {
|
if (reflected != this) {
|
||||||
return reflected.toString();
|
return reflected.toString();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user