Use Context.get/putThreadLocal() to register per-thread scopes for DynamicGlobalObject.
This is to fix some very obscure behaviour that was likely caused by the WeakHashMap code.
This commit is contained in:
parent
38b4f265ce
commit
ab5694092e
3 changed files with 15 additions and 25 deletions
|
@ -18,9 +18,8 @@ package helma.scripting.rhino;
|
||||||
|
|
||||||
import helma.framework.core.Application;
|
import helma.framework.core.Application;
|
||||||
import org.mozilla.javascript.Scriptable;
|
import org.mozilla.javascript.Scriptable;
|
||||||
import java.util.Collections;
|
import org.mozilla.javascript.Context;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.WeakHashMap;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class implements a global scope object that is a dynamic proxy
|
* This class implements a global scope object that is a dynamic proxy
|
||||||
|
@ -28,14 +27,13 @@ import java.util.WeakHashMap;
|
||||||
*/
|
*/
|
||||||
public class DynamicGlobalObject extends GlobalObject {
|
public class DynamicGlobalObject extends GlobalObject {
|
||||||
|
|
||||||
Map map = Collections.synchronizedMap(new WeakHashMap());
|
|
||||||
|
|
||||||
public DynamicGlobalObject(RhinoCore core, Application app) {
|
public DynamicGlobalObject(RhinoCore core, Application app) {
|
||||||
super(core, app);
|
super(core, app);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Object get(String s, Scriptable scriptable) {
|
public Object get(String s, Scriptable scriptable) {
|
||||||
Scriptable scope = getScope();
|
Context cx = Context.getCurrentContext();
|
||||||
|
Scriptable scope = (Scriptable) cx.getThreadLocal("threadscope");
|
||||||
if (scope != null) {
|
if (scope != null) {
|
||||||
Object obj = scope.get(s, scope);
|
Object obj = scope.get(s, scope);
|
||||||
if (obj != null && obj != NOT_FOUND) {
|
if (obj != null && obj != NOT_FOUND) {
|
||||||
|
@ -45,16 +43,4 @@ public class DynamicGlobalObject extends GlobalObject {
|
||||||
return super.get(s, scriptable);
|
return super.get(s, scriptable);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void registerScope(Scriptable scope) {
|
|
||||||
map.put(Thread.currentThread(), scope);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Scriptable unregisterScope() {
|
|
||||||
return (Scriptable) map.remove(Thread.currentThread());
|
|
||||||
}
|
|
||||||
|
|
||||||
public final Scriptable getScope() {
|
|
||||||
return (Scriptable) map.get(Thread.currentThread());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -785,14 +785,16 @@ public final class RhinoCore implements ScopeProvider {
|
||||||
////////////////////////////////////////////////
|
////////////////////////////////////////////////
|
||||||
|
|
||||||
private synchronized void evaluate (TypeInfo type, Resource code) {
|
private synchronized void evaluate (TypeInfo type, Resource code) {
|
||||||
Scriptable threadScope = global.unregisterScope();
|
// get the current context
|
||||||
|
Context cx = Context.getCurrentContext();
|
||||||
|
// unregister the per-thread scope while evaluating
|
||||||
|
Object threadScope = cx.getThreadLocal("threadscope");
|
||||||
|
cx.removeThreadLocal("threadscope");
|
||||||
|
|
||||||
String sourceName = code.getName();
|
String sourceName = code.getName();
|
||||||
Reader reader = null;
|
Reader reader = null;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// get the current context
|
|
||||||
Context cx = Context.getCurrentContext();
|
|
||||||
|
|
||||||
Scriptable op = type.objProto;
|
Scriptable op = type.objProto;
|
||||||
|
|
||||||
// do the update, evaluating the file
|
// do the update, evaluating the file
|
||||||
|
@ -832,7 +834,7 @@ public final class RhinoCore implements ScopeProvider {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (threadScope != null) {
|
if (threadScope != null) {
|
||||||
global.registerScope(threadScope);
|
cx.putThreadLocal("threadscope", threadScope);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -174,7 +174,8 @@ public class RhinoEngine implements ScriptingEngine {
|
||||||
|
|
||||||
context.setOptimizationLevel(optLevel);
|
context.setOptimizationLevel(optLevel);
|
||||||
// register the per-thread scope with the dynamic scope
|
// register the per-thread scope with the dynamic scope
|
||||||
core.global.registerScope(global);
|
// core.global.registerScope(global);
|
||||||
|
context.putThreadLocal("threadscope", global);
|
||||||
context.putThreadLocal("reval", reval);
|
context.putThreadLocal("reval", reval);
|
||||||
context.putThreadLocal("engine", this);
|
context.putThreadLocal("engine", this);
|
||||||
// update prototypes
|
// update prototypes
|
||||||
|
@ -225,8 +226,9 @@ public class RhinoEngine implements ScriptingEngine {
|
||||||
public void exitContext() {
|
public void exitContext() {
|
||||||
context.removeThreadLocal("reval");
|
context.removeThreadLocal("reval");
|
||||||
context.removeThreadLocal("engine");
|
context.removeThreadLocal("engine");
|
||||||
|
context.removeThreadLocal("threadscope");
|
||||||
Context.exit();
|
Context.exit();
|
||||||
core.global.unregisterScope();
|
// core.global.unregisterScope();
|
||||||
thread = null;
|
thread = null;
|
||||||
|
|
||||||
// if visual debugger is on let it know we're exiting a context
|
// if visual debugger is on let it know we're exiting a context
|
||||||
|
|
Loading…
Add table
Reference in a new issue