<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array"/>
  <modified type="array">
    <modified>
      <diff>@@ -42,7 +42,7 @@ public class ReloadableScript {
     // the script was last compiled
     long checksum = -1;
     // true if module scope is shared
-    boolean shared;
+    Shared shared;
     // the compiled script
     Script script;
     // any exception that may have been thrown during compilation.
@@ -55,6 +55,10 @@ public class ReloadableScript {
     // Set of direct module dependencies
     HashSet&lt;ReloadableScript&gt; dependencies = new HashSet&lt;ReloadableScript&gt;();
 
+    private enum Shared {
+        UNKNOWN, FALSE, TRUE
+    }
+
     private static Logger log = Logger.getLogger(ReloadableScript.class);
 
     /**
@@ -80,6 +84,7 @@ public class ReloadableScript {
     public synchronized Script getScript(Context cx)
             throws JavaScriptException, IOException {
         if (!isUpToDate()) {
+            shared = Shared.UNKNOWN;
             if (!source.exists()) {
                 throw new IOException(source + &quot; not found or not readable&quot;);
             }
@@ -213,41 +218,60 @@ public class ReloadableScript {
         if (modules.containsKey(source)) {
             return modules.get(source);
         }
-        synchronized (this) {
-            Script script = getScript(cx);
-            ModuleScope module = moduleScope;
-            if (module != null) {
-                // Reuse cached scope for shared modules.
-                if (module.getChecksum() == getChecksum()) {
-                    modules.put(source, module);
-                    return module;
-                }
-                module.reset();
-            } else {
-                module = new ModuleScope(moduleName, source, prototype, cx);
-            }
-            if (log.isDebugEnabled()) {
-                log.debug(&quot;Loading module: &quot; + moduleName);
-            }
+        Script script = getScript(cx);
+        ModuleScope module = moduleScope;
+        if (shared == Shared.TRUE
+                &amp;&amp; module != null
+                &amp;&amp; module.getChecksum() == getChecksum()) {
+            // Reuse cached scope for shared modules.
             modules.put(source, module);
-            // warnings are disabled in shell - enable warnings for module loading
-            ToolErrorReporter reporter =
-                    cx.getErrorReporter() instanceof ToolErrorReporter ?
-                            (ToolErrorReporter) cx.getErrorReporter() : null;
-            if (reporter != null &amp;&amp; !reporter.isReportingWarnings()) {
-                try {
-                    reporter.setIsReportingWarnings(true);
-                    script.exec(cx, module);
-                } finally {
-                    reporter.setIsReportingWarnings(false);
-                }
-            } else {
+            return module;
+        }
+
+        if (shared == Shared.UNKNOWN) {
+            module = syncedExecScript(cx, script, module, prototype, modules);
+        } else {
+            module = execScript(cx, script, module, prototype, modules);
+        }
+        return module;
+    }
+
+    private synchronized ModuleScope syncedExecScript(Context cx, Script script,
+                                                      ModuleScope module, Scriptable prototype,
+                                                      Map&lt;Trackable,ModuleScope&gt; modules)
+            throws IOException {
+        return execScript(cx, script, module, prototype, modules);
+    }
+
+    private ModuleScope execScript(Context cx, Script script, ModuleScope module,
+                                   Scriptable prototype, Map&lt;Trackable,ModuleScope&gt; modules)
+            throws IOException {
+        if (module == null) {
+            module = new ModuleScope(moduleName, source, prototype, cx);
+        } else {
+            module.reset();
+        }
+        if (log.isDebugEnabled()) {
+            log.debug(&quot;Loading module: &quot; + moduleName);
+        }
+        modules.put(source, module);
+        // warnings are disabled in shell - enable warnings for module loading
+        ToolErrorReporter reporter =
+                cx.getErrorReporter() instanceof ToolErrorReporter ?
+                        (ToolErrorReporter) cx.getErrorReporter() : null;
+        if (reporter != null &amp;&amp; !reporter.isReportingWarnings()) {
+            try {
+                reporter.setIsReportingWarnings(true);
                 script.exec(cx, module);
+            } finally {
+                reporter.setIsReportingWarnings(false);
             }
-            checkShared(module);
-            module.setChecksum(getChecksum());
-            return module;
+        } else {
+            script.exec(cx, module);
         }
+        checkShared(module);
+        module.setChecksum(getChecksum());
+        return module;
     }
 
     /**
@@ -255,7 +279,7 @@ public class ReloadableScript {
      * @return true of this script represents a shared module
      */
     public boolean isShared() {
-        return shared;
+        return shared == Shared.TRUE;
     }
 
     /**
@@ -265,9 +289,10 @@ public class ReloadableScript {
      */
     protected void checkShared(ModuleScope module) {
         Scriptable meta = module.getMetaObject();
-        shared = meta.get(&quot;shared&quot;, meta) == Boolean.TRUE
+        boolean isShared = meta.get(&quot;shared&quot;, meta) == Boolean.TRUE
                 || module.get(&quot;__shared__&quot;, module) == Boolean.TRUE;
-        if (shared) {
+        shared = isShared ? Shared.TRUE : Shared.FALSE;
+        if (isShared) {
             engine.registerSharedScript(source, this);
             moduleScope = module;
         } else {
@@ -295,7 +320,7 @@ public class ReloadableScript {
      */
     protected long getChecksum() throws IOException {
         long cs = checksum;
-        if (shared) {
+        if (shared == Shared.TRUE) {
             Set&lt;ReloadableScript&gt; set = new HashSet&lt;ReloadableScript&gt;();
             for (ReloadableScript script: dependencies) {
                 cs += script.getNestedChecksum(set);</diff>
      <filename>src/org/helma/engine/ReloadableScript.java</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>fc9eca646dae8e1b28c01ec426abb41a0012ec1e</id>
    </parent>
  </parents>
  <author>
    <name>Hannes Walln&#246;fer</name>
    <email>hannesw@gmail.com</email>
  </author>
  <url>http://github.com/hns/helma-ng/commit/f2b6128067624a52f6c6de9d19d833cef2d4bef3</url>
  <id>f2b6128067624a52f6c6de9d19d833cef2d4bef3</id>
  <committed-date>2009-11-04T01:00:32-08:00</committed-date>
  <authored-date>2009-11-04T01:00:32-08:00</authored-date>
  <message>Improve shared script loading and reloading</message>
  <tree>ca52d1237197896e97ca3d61ffc9f563133aab8e</tree>
  <committer>
    <name>Hannes Walln&#246;fer</name>
    <email>hannesw@gmail.com</email>
  </committer>
</commit>
