private ScriptModule CompileAndPublishModule(string moduleName, SourceUnit su) { Assert.NotNull(moduleName, su); EnsureModules(); string key = su.Id ?? moduleName; // check if we've already published this SourceUnit lock (_modules) { ScriptModule tmp = GetCachedModuleNoLock(key); if (tmp != null) { return(tmp); } } // compile and initialize the module... ScriptModule mod = CompileModule(moduleName, su); lock (_modules) { // check if someone else compiled it first... ScriptModule tmp = GetCachedModuleNoLock(key); if (tmp != null) { return(tmp); } LoadInfo load; if (_loading.TryGetValue(key, out load)) { if (load.Thread == Thread.CurrentThread) { return(load.Module); } Monitor.Exit(_modules); try { lock (load) { if (!load.Done) { if (load.Mre == null) { load.Mre = new ManualResetEvent(false); } Monitor.Exit(load); try { load.Mre.WaitOne(); } finally { Monitor.Enter(load); } } } if (load.Module != null) { return(load.Module); } throw load.Exception; } finally { Monitor.Enter(_modules); } } load = new LoadInfo(); load.Module = mod; load.Thread = Thread.CurrentThread; _loading[key] = load; bool success = false; Monitor.Exit(_modules); try { mod.Execute(); success = true; lock (load) { load.Done = true; if (load.Mre != null) { load.Mre.Set(); } } return(mod); } catch (Exception e) { lock (load) { load.Exception = e; load.Done = true; if (load.Mre != null) { load.Mre.Set(); } } throw; } finally { Monitor.Enter(_modules); _loading.Remove(key); if (success) { _modules[key] = new WeakReference(mod); } } } }
public void Execute() { _module.Execute(); }