Skip to content
Permalink
Browse files
Use a single global lock for proxy creation to avoid deadlocks.
This is a temporary measure to avoid deadlocks when multiple
threads load mutually-dependent Java classes. We should replace
this with some sort of atomic update of the proxy classes.

Temporary fix for #1621.
  • Loading branch information
headius committed Feb 26, 2015
1 parent 0ca486c commit 1ad3c6790cc122820f86c8ba01616e5280284030
Showing with 9 additions and 1 deletion.
  1. +2 −1 core/src/main/java/org/jruby/javasupport/JavaClass.java
  2. +7 −0 core/src/main/java/org/jruby/javasupport/JavaSupport.java
@@ -518,7 +518,7 @@ static boolean isConstant(final Field field) {
private RubyModule unfinishedProxyModule;
private RubyClass unfinishedProxyClass;

private final ReentrantLock proxyLock = new ReentrantLock();
private final ReentrantLock proxyLock;

private final Initializer initializer;

@@ -576,6 +576,7 @@ public JavaClass(Ruby runtime, Class<?> javaClass) {
} else {
initializer = DUMMY_INITIALIZER;
}
this.proxyLock = runtime.getJavaSupport().getProxyLock();
}

@Override
@@ -40,6 +40,7 @@
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.locks.ReentrantLock;

import org.jruby.Ruby;
import org.jruby.RubyClass;
@@ -135,6 +136,8 @@ public IRubyObject allocateProxy(Object javaObject, RubyClass clazz) {

private final Map<Object, Object[]> javaObjectVariables = new WeakIdentityHashMap();

private final ReentrantLock proxyLock = new ReentrantLock();

// A cache of all JavaProxyClass objects created for this runtime
private Map<Set<?>, JavaProxyClass> javaProxyClassCache = Collections.synchronizedMap(new HashMap<Set<?>, JavaProxyClass>());

@@ -374,4 +377,8 @@ public Map<Set<?>, JavaProxyClass> getJavaProxyClassCache() {
return this.javaProxyClassCache;
}

public ReentrantLock getProxyLock() {
return proxyLock;
}

}

0 comments on commit 1ad3c67

Please sign in to comment.