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:
Alexander Udalov
2016-08-16 20:05:23 +03:00
parent 8fb5858dae
commit dc689ff514
3 changed files with 20 additions and 16 deletions
@@ -122,17 +122,19 @@ public abstract class CallableReference implements KCallable {
}
public KCallable compute() {
if (reflected == null) {
reflected = computeReflected();
KCallable result = reflected;
if (result == null) {
result = computeReflected();
reflected = result;
}
return reflected;
return result;
}
protected KCallable getReflected() {
compute();
if (reflected == this) {
KCallable result = compute();
if (result == this) {
throw new KotlinReflectionNotSupportedError();
}
return reflected;
return result;
}
}
@@ -146,8 +146,7 @@ public class FunctionReference extends FunctionImpl implements KFunction {
getSignature().equals(other.getSignature());
}
if (obj instanceof KFunction) {
compute();
return obj.equals(reflected);
return obj.equals(compute());
}
return false;
}
@@ -159,7 +158,7 @@ public class FunctionReference extends FunctionImpl implements KFunction {
@Override
public String toString() {
compute();
KFunction reflected = compute();
if (reflected != this) {
return reflected.toString();
}
@@ -171,17 +170,19 @@ public class FunctionReference extends FunctionImpl implements KFunction {
}
public KFunction compute() {
if (reflected == null) {
reflected = Reflection.function(this);
KFunction result = reflected;
if (result == null) {
result = Reflection.function(this);
reflected = result;
}
return reflected;
return result;
}
private KFunction getReflected() {
compute();
if (reflected == this) {
KFunction result = compute();
if (result == this) {
throw new KotlinReflectionNotSupportedError();
}
return reflected;
return result;
}
}
@@ -16,6 +16,7 @@
package kotlin.jvm.internal;
import kotlin.reflect.KCallable;
import kotlin.reflect.KProperty;
public abstract class PropertyReference extends CallableReference implements KProperty {
@@ -57,7 +58,7 @@ public abstract class PropertyReference extends CallableReference implements KPr
@Override
public String toString() {
compute();
KCallable reflected = compute();
if (reflected != this) {
return reflected.toString();
}