diff options
Diffstat (limited to 'OpenSim/Region/ScriptEngine/XMREngine/XMRInstCapture.cs')
-rw-r--r-- | OpenSim/Region/ScriptEngine/XMREngine/XMRInstCapture.cs | 175 |
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 | ||
28 | using System; | 28 | using System; |
29 | using System.Threading; | 29 | using System.Threading; |
30 | using System.Reflection; | ||
31 | using System.Collections; | ||
32 | using System.Collections.Generic; | ||
33 | using System.Runtime.Remoting.Lifetime; | ||
34 | using System.Security.Policy; | ||
35 | using System.IO; | 30 | using System.IO; |
36 | using System.Xml; | 31 | using System.Xml; |
37 | using System.Text; | ||
38 | using OpenMetaverse; | ||
39 | using OpenSim.Framework; | ||
40 | using OpenSim.Region.ScriptEngine.Interfaces; | ||
41 | using OpenSim.Region.ScriptEngine.Shared; | 32 | using OpenSim.Region.ScriptEngine.Shared; |
42 | using OpenSim.Region.ScriptEngine.Shared.Api; | 33 | using OpenSim.Region.ScriptEngine.Shared.Api; |
43 | using OpenSim.Region.ScriptEngine.Shared.ScriptBase; | ||
44 | using OpenSim.Region.ScriptEngine.XMREngine; | ||
45 | using OpenSim.Region.Framework.Scenes; | ||
46 | using log4net; | 34 | using log4net; |
47 | 35 | ||
48 | using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat; | 36 | using 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 | } |