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
		Add a link
		
	
		Reference in a new issue