aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ScriptEngine/XMREngine/XMRInstCapture.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ScriptEngine/XMREngine/XMRInstCapture.cs')
-rw-r--r--OpenSim/Region/ScriptEngine/XMREngine/XMRInstCapture.cs175
1 files changed, 71 insertions, 104 deletions
diff --git a/OpenSim/Region/ScriptEngine/XMREngine/XMRInstCapture.cs b/OpenSim/Region/ScriptEngine/XMREngine/XMRInstCapture.cs
index 8950d63..ed33108 100644
--- a/OpenSim/Region/ScriptEngine/XMREngine/XMRInstCapture.cs
+++ b/OpenSim/Region/ScriptEngine/XMREngine/XMRInstCapture.cs
@@ -27,22 +27,10 @@
27 27
28using System; 28using System;
29using System.Threading; 29using System.Threading;
30using System.Reflection;
31using System.Collections;
32using System.Collections.Generic;
33using System.Runtime.Remoting.Lifetime;
34using System.Security.Policy;
35using System.IO; 30using System.IO;
36using System.Xml; 31using System.Xml;
37using System.Text;
38using OpenMetaverse;
39using OpenSim.Framework;
40using OpenSim.Region.ScriptEngine.Interfaces;
41using OpenSim.Region.ScriptEngine.Shared; 32using OpenSim.Region.ScriptEngine.Shared;
42using OpenSim.Region.ScriptEngine.Shared.Api; 33using OpenSim.Region.ScriptEngine.Shared.Api;
43using OpenSim.Region.ScriptEngine.Shared.ScriptBase;
44using OpenSim.Region.ScriptEngine.XMREngine;
45using OpenSim.Region.Framework.Scenes;
46using log4net; 34using log4net;
47 35
48using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat; 36using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat;
@@ -78,9 +66,7 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
78 */ 66 */
79 public XmlElement GetExecutionState(XmlDocument doc) 67 public XmlElement GetExecutionState(XmlDocument doc)
80 { 68 {
81 /* 69 // When we're detaching an attachment, we need to wait here.
82 * When we're detaching an attachment, we need to wait here.
83 */
84 70
85 // Change this to a 5 second timeout. If things do mess up, 71 // Change this to a 5 second timeout. If things do mess up,
86 // we don't want to be stuck forever. 72 // we don't want to be stuck forever.
@@ -92,20 +78,16 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
92 scriptStateN.SetAttribute("Asset", m_Item.AssetID.ToString()); 78 scriptStateN.SetAttribute("Asset", m_Item.AssetID.ToString());
93 scriptStateN.SetAttribute ("SourceHash", m_ObjCode.sourceHash); 79 scriptStateN.SetAttribute ("SourceHash", m_ObjCode.sourceHash);
94 80
95 /* 81 // Make sure we aren't executing part of the script so it stays
96 * Make sure we aren't executing part of the script so it stays 82 // stable. Setting suspendOnCheckRun tells CheckRun() to suspend
97 * stable. Setting suspendOnCheckRun tells CheckRun() to suspend 83 // and return out so RunOne() will release the lock asap.
98 * and return out so RunOne() will release the lock asap.
99 */
100 suspendOnCheckRunHold = true; 84 suspendOnCheckRunHold = true;
101 lock (m_RunLock) 85 lock (m_RunLock)
102 { 86 {
103 m_RunOnePhase = "GetExecutionState enter"; 87 m_RunOnePhase = "GetExecutionState enter";
104 CheckRunLockInvariants(true); 88 CheckRunLockInvariants(true);
105 89
106 /* 90 // Get copy of script globals and stack in relocateable form.
107 * Get copy of script globals and stack in relocateable form.
108 */
109 MemoryStream snapshotStream = new MemoryStream(); 91 MemoryStream snapshotStream = new MemoryStream();
110 MigrateOutEventHandler(snapshotStream); 92 MigrateOutEventHandler(snapshotStream);
111 Byte[] snapshotBytes = snapshotStream.ToArray(); 93 Byte[] snapshotBytes = snapshotStream.ToArray();
@@ -116,25 +98,19 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
116 scriptStateN.AppendChild(snapshotN); 98 scriptStateN.AppendChild(snapshotN);
117 m_RunOnePhase = "GetExecutionState B"; CheckRunLockInvariants(true); 99 m_RunOnePhase = "GetExecutionState B"; CheckRunLockInvariants(true);
118 100
119 /* 101 // "Running" says whether or not we are accepting new events.
120 * "Running" says whether or not we are accepting new events.
121 */
122 XmlElement runningN = doc.CreateElement("", "Running", ""); 102 XmlElement runningN = doc.CreateElement("", "Running", "");
123 runningN.AppendChild(doc.CreateTextNode(m_Running.ToString())); 103 runningN.AppendChild(doc.CreateTextNode(m_Running.ToString()));
124 scriptStateN.AppendChild(runningN); 104 scriptStateN.AppendChild(runningN);
125 m_RunOnePhase = "GetExecutionState C"; CheckRunLockInvariants(true); 105 m_RunOnePhase = "GetExecutionState C"; CheckRunLockInvariants(true);
126 106
127 /* 107 // "DoGblInit" says whether or not default:state_entry() will init global vars.
128 * "DoGblInit" says whether or not default:state_entry() will init global vars.
129 */
130 XmlElement doGblInitN = doc.CreateElement("", "DoGblInit", ""); 108 XmlElement doGblInitN = doc.CreateElement("", "DoGblInit", "");
131 doGblInitN.AppendChild(doc.CreateTextNode(doGblInit.ToString())); 109 doGblInitN.AppendChild(doc.CreateTextNode(doGblInit.ToString()));
132 scriptStateN.AppendChild(doGblInitN); 110 scriptStateN.AppendChild(doGblInitN);
133 m_RunOnePhase = "GetExecutionState D"; CheckRunLockInvariants(true); 111 m_RunOnePhase = "GetExecutionState D"; CheckRunLockInvariants(true);
134 112
135 /* 113 // More misc data.
136 * More misc data.
137 */
138 XmlNode permissionsN = doc.CreateElement("", "Permissions", ""); 114 XmlNode permissionsN = doc.CreateElement("", "Permissions", "");
139 scriptStateN.AppendChild(permissionsN); 115 scriptStateN.AppendChild(permissionsN);
140 116
@@ -147,10 +123,8 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
147 permissionsN.Attributes.Append(maskA); 123 permissionsN.Attributes.Append(maskA);
148 m_RunOnePhase = "GetExecutionState E"; CheckRunLockInvariants(true); 124 m_RunOnePhase = "GetExecutionState E"; CheckRunLockInvariants(true);
149 125
150 /* 126 // "DetectParams" are returned by llDetected...() script functions
151 * "DetectParams" are returned by llDetected...() script functions 127 // for the currently active event, if any.
152 * for the currently active event, if any.
153 */
154 if (m_DetectParams != null) 128 if (m_DetectParams != null)
155 { 129 {
156 XmlElement detParArrayN = doc.CreateElement("", "DetectArray", ""); 130 XmlElement detParArrayN = doc.CreateElement("", "DetectArray", "");
@@ -159,16 +133,14 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
159 } 133 }
160 m_RunOnePhase = "GetExecutionState F"; CheckRunLockInvariants(true); 134 m_RunOnePhase = "GetExecutionState F"; CheckRunLockInvariants(true);
161 135
162 /* 136 // Save any events we have in the queue.
163 * Save any events we have in the queue. 137 // <EventQueue>
164 * <EventQueue> 138 // <Event Name="...">
165 * <Event Name="..."> 139 // <param>...</param> ...
166 * <param>...</param> ... 140 // <DetectParams>...</DetectParams> ...
167 * <DetectParams>...</DetectParams> ... 141 // </Event>
168 * </Event> 142 // ...
169 * ... 143 // </EventQueue>
170 * </EventQueue>
171 */
172 XmlElement queuedEventsN = doc.CreateElement("", "EventQueue", ""); 144 XmlElement queuedEventsN = doc.CreateElement("", "EventQueue", "");
173 lock (m_QueueLock) 145 lock (m_QueueLock)
174 { 146 {
@@ -184,31 +156,24 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
184 scriptStateN.AppendChild(queuedEventsN); 156 scriptStateN.AppendChild(queuedEventsN);
185 m_RunOnePhase = "GetExecutionState G"; CheckRunLockInvariants(true); 157 m_RunOnePhase = "GetExecutionState G"; CheckRunLockInvariants(true);
186 158
187 /* 159 // "Plugins" indicate enabled timers and listens, etc.
188 * "Plugins" indicate enabled timers and listens, etc.
189 */
190 Object[] pluginData = 160 Object[] pluginData =
191 AsyncCommandManager.GetSerializationData(m_Engine, 161 AsyncCommandManager.GetSerializationData(m_Engine, m_ItemID);
192 m_ItemID);
193 162
194 XmlNode plugins = doc.CreateElement("", "Plugins", ""); 163 XmlNode plugins = doc.CreateElement("", "Plugins", "");
195 AppendXMLObjectArray(doc, plugins, pluginData, "plugin"); 164 AppendXMLObjectArray(doc, plugins, pluginData, "plugin");
196 scriptStateN.AppendChild(plugins); 165 scriptStateN.AppendChild(plugins);
197 m_RunOnePhase = "GetExecutionState H"; CheckRunLockInvariants(true); 166 m_RunOnePhase = "GetExecutionState H"; CheckRunLockInvariants(true);
198 167
199 /* 168 // Let script run again.
200 * Let script run again.
201 */
202 suspendOnCheckRunHold = false; 169 suspendOnCheckRunHold = false;
203 170
204 m_RunOnePhase = "GetExecutionState leave"; 171 m_RunOnePhase = "GetExecutionState leave";
205 CheckRunLockInvariants(true); 172 CheckRunLockInvariants(true);
206 } 173 }
207 174
208 /* 175 // scriptStateN represents the contents of the .state file so
209 * scriptStateN represents the contents of the .state file so 176 // write the .state file while we are here.
210 * write the .state file while we are here.
211 */
212 FileStream fs = File.Create(m_StateFileName); 177 FileStream fs = File.Create(m_StateFileName);
213 StreamWriter sw = new StreamWriter(fs); 178 StreamWriter sw = new StreamWriter(fs);
214 sw.Write(scriptStateN.OuterXml); 179 sw.Write(scriptStateN.OuterXml);
@@ -233,32 +198,33 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
233 // do all the work in the MigrateOutEventHandlerThread() method below 198 // do all the work in the MigrateOutEventHandlerThread() method below
234 moehstream = stream; 199 moehstream = stream;
235 200
236 XMRScriptThread cst = XMRScriptThread.CurrentScriptThread (); 201 XMRScriptThread cst = m_Engine.CurrentScriptThread ();
237 if (cst != null) { 202 if (cst != null)
203 {
238 204
239 // we might be getting called inside some LSL Api function 205 // we might be getting called inside some LSL Api function
240 // so we are already in script thread and thus must do 206 // so we are already in script thread and thus must do
241 // migration directly 207 // migration directly
242 MigrateOutEventHandlerThread (); 208 MigrateOutEventHandlerThread ();
243 } else { 209 }
244 210 else
211 {
245 // some other thread, do migration via a script thread 212 // some other thread, do migration via a script thread
246 lock (XMRScriptThread.m_WakeUpLock) { 213 m_Engine.QueueToTrunk(this.MigrateOutEventHandlerThread);
247 m_Engine.m_ThunkQueue.Enqueue (this.MigrateOutEventHandlerThread);
248 }
249 XMRScriptThread.WakeUpOne ();
250 214
251 // wait for it to complete 215 // wait for it to complete
252 lock (moehdone) { 216 lock (moehdone)
253 while (moehstream != null) { 217 {
218 while (moehstream != null)
254 Monitor.Wait (moehdone); 219 Monitor.Wait (moehdone);
255 }
256 } 220 }
257 } 221 }
258 222
259 // maybe it threw up 223 // maybe it threw up
260 if (moehexcep != null) throw moehexcep; 224 if (moehexcep != null)
225 throw moehexcep;
261 } 226 }
227
262 private Exception moehexcep; 228 private Exception moehexcep;
263 private object moehdone = new object (); 229 private object moehdone = new object ();
264 private Stream moehstream; 230 private Stream moehstream;
@@ -266,64 +232,65 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
266 { 232 {
267 Exception except; 233 Exception except;
268 234
269 try { 235 try
270 236 {
271 /* 237 // Resume the microthread and it will throw a StackCaptureException()
272 * Resume the microthread and it will throw a StackCaptureException() 238 // with the stack frames saved to this.stackFrames.
273 * with the stack frames saved to this.stackFrames. 239 // Then write the saved stack frames to the output stream.
274 * Then write the saved stack frames to the output stream. 240 //
275 * 241 // There is a stack only if the event code is not None.
276 * There is a stack only if the event code is not None. 242 if (this.eventCode != ScriptEventCode.None)
277 */ 243 {
278 if (this.eventCode != ScriptEventCode.None) {
279
280 // tell microthread to continue 244 // tell microthread to continue
281 // it should see captureStackFrames and throw StackCaptureException() 245 // it should see captureStackFrames and throw StackCaptureException()
282 // ...generating XMRStackFrames as it unwinds 246 // ...generating XMRStackFrames as it unwinds
283 this.captureStackFrames = true; 247 this.captureStackFrames = true;
248// this.suspendOnCheckRunTemp = true;
284 except = this.microthread.ResumeEx (); 249 except = this.microthread.ResumeEx ();
285 this.captureStackFrames = false; 250 this.captureStackFrames = false;
286 if (except == null) { 251
252 if (except == null)
287 throw new Exception ("stack save did not complete"); 253 throw new Exception ("stack save did not complete");
288 } 254
289 if (!(except is StackCaptureException)) { 255 if (!(except is StackCaptureException))
290 throw except; 256 throw except;
291 }
292 } 257 }
293 258
294 /* 259 // Write script state out, frames and all, to the stream.
295 * Write script state out, frames and all, to the stream. 260 // Does not change script state.
296 * Does not change script state. 261
297 */
298 moehstream.WriteByte (migrationVersion); 262 moehstream.WriteByte (migrationVersion);
299 moehstream.WriteByte ((byte)16); 263 moehstream.WriteByte ((byte)16);
300 this.MigrateOut (new BinaryWriter (moehstream)); 264 this.MigrateOut (new BinaryWriter (moehstream));
301 265
302 /* 266 // Now restore script stack.
303 * Now restore script stack. 267 // Microthread will suspend inside CheckRun() when restore is complete.
304 * Microthread will suspend inside CheckRun() when restore is complete. 268 if (this.eventCode != ScriptEventCode.None)
305 */ 269 {
306 if (this.eventCode != ScriptEventCode.None) {
307 this.stackFramesRestored = false; 270 this.stackFramesRestored = false;
308 except = this.microthread.StartEx (); 271 except = this.microthread.StartEx ();
309 if (except != null) { 272
273 if (except != null)
310 throw except; 274 throw except;
311 } 275
312 if (!this.stackFramesRestored) { 276 if (!this.stackFramesRestored)
313 throw new Exception ("restore after save did not complete"); 277 throw new Exception ("restore after save did not complete");
314 } 278
315 } 279 }
316 } catch (Exception e) { 280 }
281 catch (Exception e)
282 {
317 moehexcep = e; 283 moehexcep = e;
318 } finally { 284 }
319 285 finally
286 {
320 // make sure CheckRunLockInvariants() won't puque 287 // make sure CheckRunLockInvariants() won't puque
321 if (this.microthread.Active () == 0) { 288 if (this.microthread.Active () == 0)
322 this.eventCode = ScriptEventCode.None; 289 this.eventCode = ScriptEventCode.None;
323 }
324 290
325 // wake the MigrateOutEventHandler() method above 291 // wake the MigrateOutEventHandler() method above
326 lock (moehdone) { 292 lock (moehdone)
293 {
327 moehstream = null; 294 moehstream = null;
328 Monitor.Pulse (moehdone); 295 Monitor.Pulse (moehdone);
329 } 296 }