aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ScriptEngine/DotNetEngine/ScriptManager.cs
diff options
context:
space:
mode:
authorTedd Hansen2007-08-25 15:31:47 +0000
committerTedd Hansen2007-08-25 15:31:47 +0000
commit53be4774b32f6736373c1364c3bd659c977fbb4e (patch)
treec81bbc0d41b375bcc403c574da612d18b038c228 /OpenSim/Region/ScriptEngine/DotNetEngine/ScriptManager.cs
parentHopefully fixed the bugs in primitives rotation editing (diff)
downloadopensim-SC-53be4774b32f6736373c1364c3bd659c977fbb4e.zip
opensim-SC-53be4774b32f6736373c1364c3bd659c977fbb4e.tar.gz
opensim-SC-53be4774b32f6736373c1364c3bd659c977fbb4e.tar.bz2
opensim-SC-53be4774b32f6736373c1364c3bd659c977fbb4e.tar.xz
Scripts no longer crash sim after 5 minutes (override InitializeLifetimeService). Loading/Unloading of scripts are now handled in separate thread so server is no delayed because of this. Each script is loaded into a single AppDomain (temporary test for script unload, eats ~15KB more memory for each script). Unload of scripts has been verified to free up memory.
Diffstat (limited to 'OpenSim/Region/ScriptEngine/DotNetEngine/ScriptManager.cs')
-rw-r--r--OpenSim/Region/ScriptEngine/DotNetEngine/ScriptManager.cs123
1 files changed, 104 insertions, 19 deletions
diff --git a/OpenSim/Region/ScriptEngine/DotNetEngine/ScriptManager.cs b/OpenSim/Region/ScriptEngine/DotNetEngine/ScriptManager.cs
index cadae05..9621e56 100644
--- a/OpenSim/Region/ScriptEngine/DotNetEngine/ScriptManager.cs
+++ b/OpenSim/Region/ScriptEngine/DotNetEngine/ScriptManager.cs
@@ -50,11 +50,82 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine
50 public class ScriptManager 50 public class ScriptManager
51 { 51 {
52 52
53 private Thread ScriptLoadUnloadThread;
54 private int ScriptLoadUnloadThread_IdleSleepms = 100;
55 private Queue<LoadStruct> LoadQueue = new Queue<LoadStruct>();
56 private Queue<UnloadStruct> UnloadQueue = new Queue<UnloadStruct>();
57 private struct LoadStruct
58 {
59 public uint localID;
60 public LLUUID itemID;
61 public string Script;
62 }
63 private struct UnloadStruct
64 {
65 public uint localID;
66 public LLUUID itemID;
67 }
68
53 private ScriptEngine m_scriptEngine; 69 private ScriptEngine m_scriptEngine;
54 public ScriptManager(ScriptEngine scriptEngine) 70 public ScriptManager(ScriptEngine scriptEngine)
55 { 71 {
56 m_scriptEngine = scriptEngine; 72 m_scriptEngine = scriptEngine;
57 AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve); 73 AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);
74 ScriptLoadUnloadThread = new Thread(ScriptLoadUnloadThreadLoop);
75 ScriptLoadUnloadThread.Name = "ScriptLoadUnloadThread";
76 ScriptLoadUnloadThread.IsBackground = true;
77 ScriptLoadUnloadThread.Priority = ThreadPriority.BelowNormal;
78 ScriptLoadUnloadThread.Start();
79
80 }
81 ~ScriptManager ()
82 {
83 // Abort load/unload thread
84 try
85 {
86 if (ScriptLoadUnloadThread != null)
87 {
88 if (ScriptLoadUnloadThread.IsAlive == true)
89 {
90 ScriptLoadUnloadThread.Abort();
91 ScriptLoadUnloadThread.Join();
92 }
93 }
94 }
95 catch
96 {
97 }
98 }
99 private void ScriptLoadUnloadThreadLoop()
100 {
101 try
102 {
103 while (true)
104 {
105 if (LoadQueue.Count == 0 && UnloadQueue.Count == 0)
106 Thread.Sleep(ScriptLoadUnloadThread_IdleSleepms);
107
108 if (LoadQueue.Count > 0)
109 {
110 LoadStruct item = LoadQueue.Dequeue();
111 _StartScript(item.localID, item.itemID, item.Script);
112 }
113
114 if (UnloadQueue.Count > 0)
115 {
116 UnloadStruct item = UnloadQueue.Dequeue();
117 _StopScript(item.localID, item.itemID);
118 }
119
120
121
122 }
123 }
124 catch (ThreadAbortException tae)
125 {
126 // Expected
127 }
128
58 } 129 }
59 130
60 private static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args) 131 private static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
@@ -146,8 +217,29 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine
146 /// <param name="localID"></param> 217 /// <param name="localID"></param>
147 public void StartScript(uint localID, LLUUID itemID, string Script) 218 public void StartScript(uint localID, LLUUID itemID, string Script)
148 { 219 {
220 LoadStruct ls = new LoadStruct();
221 ls.localID = localID;
222 ls.itemID = itemID;
223 ls.Script = Script;
224 LoadQueue.Enqueue(ls);
225 }
226 /// <summary>
227 /// Disables and unloads a script
228 /// </summary>
229 /// <param name="localID"></param>
230 /// <param name="itemID"></param>
231 public void StopScript(uint localID, LLUUID itemID)
232 {
233 UnloadStruct ls = new UnloadStruct();
234 ls.localID = localID;
235 ls.itemID = itemID;
236 UnloadQueue.Enqueue(ls);
237 }
238
239 private void _StartScript(uint localID, LLUUID itemID, string Script)
240 {
149 //IScriptHost root = host.GetRoot(); 241 //IScriptHost root = host.GetRoot();
150 m_scriptEngine.Log.Verbose("ScriptEngine", "ScriptManager StartScript: localID: " + localID + ", itemID: " + itemID); 242 Console.WriteLine("ScriptManager StartScript: localID: " + localID + ", itemID: " + itemID);
151 243
152 // We will initialize and start the script. 244 // We will initialize and start the script.
153 // It will be up to the script itself to hook up the correct events. 245 // It will be up to the script itself to hook up the correct events.
@@ -161,32 +253,23 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine
161 OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.LSL.Compiler LSLCompiler = new OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.LSL.Compiler(); 253 OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.LSL.Compiler LSLCompiler = new OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.LSL.Compiler();
162 // Compile (We assume LSL) 254 // Compile (We assume LSL)
163 FileName = LSLCompiler.CompileFromLSLText(Script); 255 FileName = LSLCompiler.CompileFromLSLText(Script);
164 m_scriptEngine.Log.Verbose("ScriptEngine", "Compilation of " + FileName + " done"); 256 Console.WriteLine("Compilation of " + FileName + " done");
165 // * Insert yield into code 257 // * Insert yield into code
166 FileName = ProcessYield(FileName); 258 FileName = ProcessYield(FileName);
167 259
168 260
169 //OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.LSO.LSL_BaseClass Script = LoadAndInitAssembly(FreeAppDomain, FileName); 261#if DEBUG
170
171 //OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.LSL.LSL_BaseClass Script = LoadAndInitAssembly(FreeAppDomain, FileName, localID);
172
173 long before; 262 long before;
174 before = GC.GetTotalMemory(false); 263 before = GC.GetTotalMemory(false);
264#endif
175 LSL_BaseClass CompiledScript = m_scriptEngine.myAppDomainManager.LoadScript(FileName); 265 LSL_BaseClass CompiledScript = m_scriptEngine.myAppDomainManager.LoadScript(FileName);
266#if DEBUG
176 Console.WriteLine("Script " + itemID + " occupies {0} bytes", GC.GetTotalMemory(false) - before); 267 Console.WriteLine("Script " + itemID + " occupies {0} bytes", GC.GetTotalMemory(false) - before);
177 //before = GC.GetTotalMemory(false); 268#endif
178
179 269
180 //Script = m_scriptEngine.myAppDomainManager.LoadScript(FileName); 270 // Add it to our script memstruct
181 //Console.WriteLine("Script occupies {0} bytes", GC.GetTotalMemory(true) - before);
182 //before = GC.GetTotalMemory(true);
183 //Script = m_scriptEngine.myAppDomainManager.LoadScript(FileName);
184 //Console.WriteLine("Script occupies {0} bytes", GC.GetTotalMemory(true) - before);
185
186
187 // Add it to our temporary active script keeper
188 //Scripts.Add(FullitemID, Script);
189 SetScript(localID, itemID, CompiledScript); 271 SetScript(localID, itemID, CompiledScript);
272
190 // We need to give (untrusted) assembly a private instance of BuiltIns 273 // We need to give (untrusted) assembly a private instance of BuiltIns
191 // this private copy will contain Read-Only FullitemID so that it can bring that on to the server whenever needed. 274 // this private copy will contain Read-Only FullitemID so that it can bring that on to the server whenever needed.
192 LSL_BuiltIn_Commands LSLB = new LSL_BuiltIn_Commands(this, World.GetSceneObjectPart(localID)); 275 LSL_BuiltIn_Commands LSLB = new LSL_BuiltIn_Commands(this, World.GetSceneObjectPart(localID));
@@ -202,9 +285,11 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine
202 285
203 286
204 } 287 }
205 public void StopScript(uint localID, LLUUID itemID) 288
289 private void _StopScript(uint localID, LLUUID itemID)
206 { 290 {
207 // Stop script 291 // Stop script
292 Console.WriteLine("Stop script localID: " + localID + " LLUID: " + itemID.ToString());
208 293
209 // Get AppDomain 294 // Get AppDomain
210 AppDomain ad = GetScript(localID, itemID).Exec.GetAppDomain(); 295 AppDomain ad = GetScript(localID, itemID).Exec.GetAppDomain();
@@ -235,7 +320,7 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine
235 { 320 {
236 321
237 // Execute a function in the script 322 // Execute a function in the script
238 m_scriptEngine.Log.Verbose("ScriptEngine", "Executing Function localID: " + localID + ", itemID: " + itemID + ", FunctionName: " + FunctionName); 323 //m_scriptEngine.Log.Verbose("ScriptEngine", "Executing Function localID: " + localID + ", itemID: " + itemID + ", FunctionName: " + FunctionName);
239 LSL_BaseClass Script = m_scriptEngine.myScriptManager.GetScript(localID, itemID); 324 LSL_BaseClass Script = m_scriptEngine.myScriptManager.GetScript(localID, itemID);
240 325
241 // Must be done in correct AppDomain, so leaving it up to the script itself 326 // Must be done in correct AppDomain, so leaving it up to the script itself