Skip to content

Commit

Permalink
Protecting the trace with a lock
Browse files Browse the repository at this point in the history
  • Loading branch information
abreslav committed Jan 30, 2013
1 parent c2822fd commit 5eb173e
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 1 deletion.
Expand Up @@ -19,7 +19,13 @@
import com.intellij.openapi.util.Computable;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.diagnostics.Diagnostic;
import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.BindingTrace;
import org.jetbrains.jet.util.slicedmap.ReadOnlySlice;
import org.jetbrains.jet.util.slicedmap.WritableSlice;

import java.util.Collection;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

Expand All @@ -44,6 +50,14 @@ public <T> LazyValue<T> createLazyValue(@NotNull Computable<T> computable) {
return new LockBasedLazyValue<T>(lock, computable);
}

@NotNull
@Override
public BindingTrace createSafeTrace(@NotNull BindingTrace originalTrace) {
// It seems safe to have a separate lock for traces:
// no other locks will be acquired inside the trace operations
return new LockProtectedTrace(lock, originalTrace);
}

private static class LockBasedLazyValue<T> implements LazyValue<T> {
private final Object lock;
private final Computable<T> computable;
Expand Down Expand Up @@ -74,4 +88,58 @@ public T get() {
}
}
}

private static class LockProtectedTrace implements BindingTrace {
private final Object lock;
private final BindingTrace trace;

public LockProtectedTrace(@NotNull Object lock, @NotNull BindingTrace trace) {
this.lock = lock;
this.trace = trace;
}

@Override
public BindingContext getBindingContext() {
synchronized (lock) {
return trace.getBindingContext();
}
}

@Override
public <K, V> void record(WritableSlice<K, V> slice, K key, V value) {
synchronized (lock) {
trace.record(slice, key, value);
}
}

@Override
public <K> void record(WritableSlice<K, Boolean> slice, K key) {
synchronized (lock) {
trace.record(slice, key);
}
}

@Override
@Nullable
public <K, V> V get(ReadOnlySlice<K, V> slice, K key) {
synchronized (lock) {
return trace.get(slice, key);
}
}

@Override
@NotNull
public <K, V> Collection<K> getKeys(WritableSlice<K, V> slice) {
synchronized (lock) {
return trace.getKeys(slice);
}
}

@Override
public void report(@NotNull Diagnostic diagnostic) {
synchronized (lock) {
trace.report(diagnostic);
}
}
}
}
Expand Up @@ -107,7 +107,7 @@ public ResolveSession(
this.storageManager = storageManager;
this.classifierAliases = classifierAliases;
this.specialClasses = specialClasses;
this.trace = new ObservableBindingTrace(delegationTrace);
this.trace = storageManager.createSafeTrace(delegationTrace);
this.injector = new InjectorForLazyResolve(project, this, trace, moduleConfiguration);
this.module = rootDescriptor;
this.moduleConfiguration = moduleConfiguration;
Expand Down
Expand Up @@ -18,6 +18,7 @@

import com.intellij.openapi.util.Computable;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.resolve.BindingTrace;

import java.util.concurrent.ConcurrentMap;

Expand All @@ -27,4 +28,7 @@ public interface StorageManager {

@NotNull
<T> LazyValue<T> createLazyValue(@NotNull Computable<T> computable);

@NotNull
BindingTrace createSafeTrace(@NotNull BindingTrace originalTrace);
}

0 comments on commit 5eb173e

Please sign in to comment.