diff options
Diffstat (limited to '')
-rw-r--r-- | OpenSim/Region/ScriptEngine/YEngine/XMRInstCapture.cs (renamed from OpenSim/Region/ScriptEngine/XMREngine/XMRInstCapture.cs) | 202 |
1 files changed, 54 insertions, 148 deletions
diff --git a/OpenSim/Region/ScriptEngine/XMREngine/XMRInstCapture.cs b/OpenSim/Region/ScriptEngine/YEngine/XMRInstCapture.cs index ed33108..e90d83b 100644 --- a/OpenSim/Region/ScriptEngine/XMREngine/XMRInstCapture.cs +++ b/OpenSim/Region/ScriptEngine/YEngine/XMRInstCapture.cs | |||
@@ -26,7 +26,6 @@ | |||
26 | */ | 26 | */ |
27 | 27 | ||
28 | using System; | 28 | using System; |
29 | using System.Threading; | ||
30 | using System.IO; | 29 | using System.IO; |
31 | using System.Xml; | 30 | using System.Xml; |
32 | using OpenSim.Region.ScriptEngine.Shared; | 31 | using OpenSim.Region.ScriptEngine.Shared; |
@@ -41,7 +40,7 @@ using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion; | |||
41 | using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; | 40 | using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; |
42 | using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3; | 41 | using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3; |
43 | 42 | ||
44 | namespace OpenSim.Region.ScriptEngine.XMREngine | 43 | namespace OpenSim.Region.ScriptEngine.Yengine |
45 | { | 44 | { |
46 | public partial class XMRInstance | 45 | public partial class XMRInstance |
47 | { | 46 | { |
@@ -54,7 +53,7 @@ namespace OpenSim.Region.ScriptEngine.XMREngine | |||
54 | 53 | ||
55 | /** | 54 | /** |
56 | * @brief Create an XML element that gives the current state of the script. | 55 | * @brief Create an XML element that gives the current state of the script. |
57 | * <ScriptState Engine="XMREngine" SourceHash=m_ObjCode.sourceHash Asset=m_Item.AssetID> | 56 | * <ScriptState Engine="YEngine" SourceHash=m_ObjCode.sourceHash Asset=m_Item.AssetID> |
58 | * <Snapshot>globalsandstackdump</Snapshot> | 57 | * <Snapshot>globalsandstackdump</Snapshot> |
59 | * <Running>m_Running</Running> | 58 | * <Running>m_Running</Running> |
60 | * <DetectArray ... | 59 | * <DetectArray ... |
@@ -71,23 +70,23 @@ namespace OpenSim.Region.ScriptEngine.XMREngine | |||
71 | // Change this to a 5 second timeout. If things do mess up, | 70 | // Change this to a 5 second timeout. If things do mess up, |
72 | // we don't want to be stuck forever. | 71 | // we don't want to be stuck forever. |
73 | // | 72 | // |
74 | m_DetachReady.WaitOne (5000, false); | 73 | m_DetachReady.WaitOne(5000, false); |
75 | 74 | ||
76 | XmlElement scriptStateN = doc.CreateElement("", "ScriptState", ""); | 75 | XmlElement scriptStateN = doc.CreateElement("", "ScriptState", ""); |
77 | scriptStateN.SetAttribute("Engine", m_Engine.ScriptEngineName); | 76 | scriptStateN.SetAttribute("Engine", m_Engine.ScriptEngineName); |
78 | scriptStateN.SetAttribute("Asset", m_Item.AssetID.ToString()); | 77 | scriptStateN.SetAttribute("Asset", m_Item.AssetID.ToString()); |
79 | scriptStateN.SetAttribute ("SourceHash", m_ObjCode.sourceHash); | 78 | scriptStateN.SetAttribute("SourceHash", m_ObjCode.sourceHash); |
80 | 79 | ||
81 | // Make sure we aren't executing part of the script so it stays | 80 | // Make sure we aren't executing part of the script so it stays |
82 | // stable. Setting suspendOnCheckRun tells CheckRun() to suspend | 81 | // stable. Setting suspendOnCheckRun tells CheckRun() to suspend |
83 | // and return out so RunOne() will release the lock asap. | 82 | // and return out so RunOne() will release the lock asap. |
84 | suspendOnCheckRunHold = true; | 83 | suspendOnCheckRunHold = true; |
85 | lock (m_RunLock) | 84 | lock(m_RunLock) |
86 | { | 85 | { |
87 | m_RunOnePhase = "GetExecutionState enter"; | 86 | m_RunOnePhase = "GetExecutionState enter"; |
88 | CheckRunLockInvariants(true); | 87 | CheckRunLockInvariants(true); |
89 | 88 | ||
90 | // Get copy of script globals and stack in relocateable form. | 89 | // Get copy of script globals and stack in relocateable form. |
91 | MemoryStream snapshotStream = new MemoryStream(); | 90 | MemoryStream snapshotStream = new MemoryStream(); |
92 | MigrateOutEventHandler(snapshotStream); | 91 | MigrateOutEventHandler(snapshotStream); |
93 | Byte[] snapshotBytes = snapshotStream.ToArray(); | 92 | Byte[] snapshotBytes = snapshotStream.ToArray(); |
@@ -96,21 +95,24 @@ namespace OpenSim.Region.ScriptEngine.XMREngine | |||
96 | XmlElement snapshotN = doc.CreateElement("", "Snapshot", ""); | 95 | XmlElement snapshotN = doc.CreateElement("", "Snapshot", ""); |
97 | snapshotN.AppendChild(doc.CreateTextNode(snapshotString)); | 96 | snapshotN.AppendChild(doc.CreateTextNode(snapshotString)); |
98 | scriptStateN.AppendChild(snapshotN); | 97 | scriptStateN.AppendChild(snapshotN); |
99 | m_RunOnePhase = "GetExecutionState B"; CheckRunLockInvariants(true); | 98 | m_RunOnePhase = "GetExecutionState B"; |
99 | CheckRunLockInvariants(true); | ||
100 | 100 | ||
101 | // "Running" says whether or not we are accepting new events. | 101 | // "Running" says whether or not we are accepting new events. |
102 | XmlElement runningN = doc.CreateElement("", "Running", ""); | 102 | XmlElement runningN = doc.CreateElement("", "Running", ""); |
103 | runningN.AppendChild(doc.CreateTextNode(m_Running.ToString())); | 103 | runningN.AppendChild(doc.CreateTextNode(m_Running.ToString())); |
104 | scriptStateN.AppendChild(runningN); | 104 | scriptStateN.AppendChild(runningN); |
105 | m_RunOnePhase = "GetExecutionState C"; CheckRunLockInvariants(true); | 105 | m_RunOnePhase = "GetExecutionState C"; |
106 | CheckRunLockInvariants(true); | ||
106 | 107 | ||
107 | // "DoGblInit" says whether or not default:state_entry() will init global vars. | 108 | // "DoGblInit" says whether or not default:state_entry() will init global vars. |
108 | XmlElement doGblInitN = doc.CreateElement("", "DoGblInit", ""); | 109 | XmlElement doGblInitN = doc.CreateElement("", "DoGblInit", ""); |
109 | doGblInitN.AppendChild(doc.CreateTextNode(doGblInit.ToString())); | 110 | doGblInitN.AppendChild(doc.CreateTextNode(doGblInit.ToString())); |
110 | scriptStateN.AppendChild(doGblInitN); | 111 | scriptStateN.AppendChild(doGblInitN); |
111 | m_RunOnePhase = "GetExecutionState D"; CheckRunLockInvariants(true); | 112 | m_RunOnePhase = "GetExecutionState D"; |
113 | CheckRunLockInvariants(true); | ||
112 | 114 | ||
113 | // More misc data. | 115 | // More misc data. |
114 | XmlNode permissionsN = doc.CreateElement("", "Permissions", ""); | 116 | XmlNode permissionsN = doc.CreateElement("", "Permissions", ""); |
115 | scriptStateN.AppendChild(permissionsN); | 117 | scriptStateN.AppendChild(permissionsN); |
116 | 118 | ||
@@ -121,30 +123,32 @@ namespace OpenSim.Region.ScriptEngine.XMREngine | |||
121 | XmlAttribute maskA = doc.CreateAttribute("", "mask", ""); | 123 | XmlAttribute maskA = doc.CreateAttribute("", "mask", ""); |
122 | maskA.Value = m_Item.PermsMask.ToString(); | 124 | maskA.Value = m_Item.PermsMask.ToString(); |
123 | permissionsN.Attributes.Append(maskA); | 125 | permissionsN.Attributes.Append(maskA); |
124 | m_RunOnePhase = "GetExecutionState E"; CheckRunLockInvariants(true); | 126 | m_RunOnePhase = "GetExecutionState E"; |
127 | CheckRunLockInvariants(true); | ||
125 | 128 | ||
126 | // "DetectParams" are returned by llDetected...() script functions | 129 | // "DetectParams" are returned by llDetected...() script functions |
127 | // for the currently active event, if any. | 130 | // for the currently active event, if any. |
128 | if (m_DetectParams != null) | 131 | if(m_DetectParams != null) |
129 | { | 132 | { |
130 | XmlElement detParArrayN = doc.CreateElement("", "DetectArray", ""); | 133 | XmlElement detParArrayN = doc.CreateElement("", "DetectArray", ""); |
131 | AppendXMLDetectArray(doc, detParArrayN, m_DetectParams); | 134 | AppendXMLDetectArray(doc, detParArrayN, m_DetectParams); |
132 | scriptStateN.AppendChild(detParArrayN); | 135 | scriptStateN.AppendChild(detParArrayN); |
133 | } | 136 | } |
134 | m_RunOnePhase = "GetExecutionState F"; CheckRunLockInvariants(true); | 137 | m_RunOnePhase = "GetExecutionState F"; |
135 | 138 | CheckRunLockInvariants(true); | |
136 | // Save any events we have in the queue. | 139 | |
137 | // <EventQueue> | 140 | // Save any events we have in the queue. |
138 | // <Event Name="..."> | 141 | // <EventQueue> |
139 | // <param>...</param> ... | 142 | // <Event Name="..."> |
140 | // <DetectParams>...</DetectParams> ... | 143 | // <param>...</param> ... |
141 | // </Event> | 144 | // <DetectParams>...</DetectParams> ... |
142 | // ... | 145 | // </Event> |
143 | // </EventQueue> | 146 | // ... |
147 | // </EventQueue> | ||
144 | XmlElement queuedEventsN = doc.CreateElement("", "EventQueue", ""); | 148 | XmlElement queuedEventsN = doc.CreateElement("", "EventQueue", ""); |
145 | lock (m_QueueLock) | 149 | lock(m_QueueLock) |
146 | { | 150 | { |
147 | foreach (EventParams evt in m_EventQueue) | 151 | foreach(EventParams evt in m_EventQueue) |
148 | { | 152 | { |
149 | XmlElement singleEventN = doc.CreateElement("", "Event", ""); | 153 | XmlElement singleEventN = doc.CreateElement("", "Event", ""); |
150 | singleEventN.SetAttribute("Name", evt.EventName); | 154 | singleEventN.SetAttribute("Name", evt.EventName); |
@@ -154,26 +158,28 @@ namespace OpenSim.Region.ScriptEngine.XMREngine | |||
154 | } | 158 | } |
155 | } | 159 | } |
156 | scriptStateN.AppendChild(queuedEventsN); | 160 | scriptStateN.AppendChild(queuedEventsN); |
157 | m_RunOnePhase = "GetExecutionState G"; CheckRunLockInvariants(true); | 161 | m_RunOnePhase = "GetExecutionState G"; |
162 | CheckRunLockInvariants(true); | ||
158 | 163 | ||
159 | // "Plugins" indicate enabled timers and listens, etc. | 164 | // "Plugins" indicate enabled timers and listens, etc. |
160 | Object[] pluginData = | 165 | Object[] pluginData = |
161 | AsyncCommandManager.GetSerializationData(m_Engine, m_ItemID); | 166 | AsyncCommandManager.GetSerializationData(m_Engine, m_ItemID); |
162 | 167 | ||
163 | XmlNode plugins = doc.CreateElement("", "Plugins", ""); | 168 | XmlNode plugins = doc.CreateElement("", "Plugins", ""); |
164 | AppendXMLObjectArray(doc, plugins, pluginData, "plugin"); | 169 | AppendXMLObjectArray(doc, plugins, pluginData, "plugin"); |
165 | scriptStateN.AppendChild(plugins); | 170 | scriptStateN.AppendChild(plugins); |
166 | m_RunOnePhase = "GetExecutionState H"; CheckRunLockInvariants(true); | 171 | m_RunOnePhase = "GetExecutionState H"; |
172 | CheckRunLockInvariants(true); | ||
167 | 173 | ||
168 | // Let script run again. | 174 | // Let script run again. |
169 | suspendOnCheckRunHold = false; | 175 | suspendOnCheckRunHold = false; |
170 | 176 | ||
171 | m_RunOnePhase = "GetExecutionState leave"; | 177 | m_RunOnePhase = "GetExecutionState leave"; |
172 | CheckRunLockInvariants(true); | 178 | CheckRunLockInvariants(true); |
173 | } | 179 | } |
174 | 180 | ||
175 | // scriptStateN represents the contents of the .state file so | 181 | // scriptStateN represents the contents of the .state file so |
176 | // write the .state file while we are here. | 182 | // write the .state file while we are here. |
177 | FileStream fs = File.Create(m_StateFileName); | 183 | FileStream fs = File.Create(m_StateFileName); |
178 | StreamWriter sw = new StreamWriter(fs); | 184 | StreamWriter sw = new StreamWriter(fs); |
179 | sw.Write(scriptStateN.OuterXml); | 185 | sw.Write(scriptStateN.OuterXml); |
@@ -185,116 +191,16 @@ namespace OpenSim.Region.ScriptEngine.XMREngine | |||
185 | 191 | ||
186 | /** | 192 | /** |
187 | * @brief Write script state to output stream. | 193 | * @brief Write script state to output stream. |
188 | * The script microthread is at same state on return, | ||
189 | * ie, either inactive or suspended inside CheckRun(). | ||
190 | * | ||
191 | * Input: | 194 | * Input: |
192 | * stream = stream to write event handler state information to | 195 | * stream = stream to write event handler state information to |
193 | */ | 196 | */ |
194 | private void MigrateOutEventHandler (Stream stream) | 197 | private void MigrateOutEventHandler(Stream stream) |
195 | { | 198 | { |
196 | moehexcep = null; | 199 | // Write script state out, frames and all, to the stream. |
197 | 200 | // Does not change script state. | |
198 | // do all the work in the MigrateOutEventHandlerThread() method below | 201 | stream.WriteByte(migrationVersion); |
199 | moehstream = stream; | 202 | stream.WriteByte((byte)16); |
200 | 203 | this.MigrateOut(new BinaryWriter(stream)); | |
201 | XMRScriptThread cst = m_Engine.CurrentScriptThread (); | ||
202 | if (cst != null) | ||
203 | { | ||
204 | |||
205 | // we might be getting called inside some LSL Api function | ||
206 | // so we are already in script thread and thus must do | ||
207 | // migration directly | ||
208 | MigrateOutEventHandlerThread (); | ||
209 | } | ||
210 | else | ||
211 | { | ||
212 | // some other thread, do migration via a script thread | ||
213 | m_Engine.QueueToTrunk(this.MigrateOutEventHandlerThread); | ||
214 | |||
215 | // wait for it to complete | ||
216 | lock (moehdone) | ||
217 | { | ||
218 | while (moehstream != null) | ||
219 | Monitor.Wait (moehdone); | ||
220 | } | ||
221 | } | ||
222 | |||
223 | // maybe it threw up | ||
224 | if (moehexcep != null) | ||
225 | throw moehexcep; | ||
226 | } | ||
227 | |||
228 | private Exception moehexcep; | ||
229 | private object moehdone = new object (); | ||
230 | private Stream moehstream; | ||
231 | private void MigrateOutEventHandlerThread () | ||
232 | { | ||
233 | Exception except; | ||
234 | |||
235 | try | ||
236 | { | ||
237 | // Resume the microthread and it will throw a StackCaptureException() | ||
238 | // with the stack frames saved to this.stackFrames. | ||
239 | // Then write the saved stack frames to the output stream. | ||
240 | // | ||
241 | // There is a stack only if the event code is not None. | ||
242 | if (this.eventCode != ScriptEventCode.None) | ||
243 | { | ||
244 | // tell microthread to continue | ||
245 | // it should see captureStackFrames and throw StackCaptureException() | ||
246 | // ...generating XMRStackFrames as it unwinds | ||
247 | this.captureStackFrames = true; | ||
248 | // this.suspendOnCheckRunTemp = true; | ||
249 | except = this.microthread.ResumeEx (); | ||
250 | this.captureStackFrames = false; | ||
251 | |||
252 | if (except == null) | ||
253 | throw new Exception ("stack save did not complete"); | ||
254 | |||
255 | if (!(except is StackCaptureException)) | ||
256 | throw except; | ||
257 | } | ||
258 | |||
259 | // Write script state out, frames and all, to the stream. | ||
260 | // Does not change script state. | ||
261 | |||
262 | moehstream.WriteByte (migrationVersion); | ||
263 | moehstream.WriteByte ((byte)16); | ||
264 | this.MigrateOut (new BinaryWriter (moehstream)); | ||
265 | |||
266 | // Now restore script stack. | ||
267 | // Microthread will suspend inside CheckRun() when restore is complete. | ||
268 | if (this.eventCode != ScriptEventCode.None) | ||
269 | { | ||
270 | this.stackFramesRestored = false; | ||
271 | except = this.microthread.StartEx (); | ||
272 | |||
273 | if (except != null) | ||
274 | throw except; | ||
275 | |||
276 | if (!this.stackFramesRestored) | ||
277 | throw new Exception ("restore after save did not complete"); | ||
278 | |||
279 | } | ||
280 | } | ||
281 | catch (Exception e) | ||
282 | { | ||
283 | moehexcep = e; | ||
284 | } | ||
285 | finally | ||
286 | { | ||
287 | // make sure CheckRunLockInvariants() won't puque | ||
288 | if (this.microthread.Active () == 0) | ||
289 | this.eventCode = ScriptEventCode.None; | ||
290 | |||
291 | // wake the MigrateOutEventHandler() method above | ||
292 | lock (moehdone) | ||
293 | { | ||
294 | moehstream = null; | ||
295 | Monitor.Pulse (moehdone); | ||
296 | } | ||
297 | } | ||
298 | } | 204 | } |
299 | 205 | ||
300 | /** | 206 | /** |
@@ -304,7 +210,7 @@ namespace OpenSim.Region.ScriptEngine.XMREngine | |||
304 | */ | 210 | */ |
305 | private static void AppendXMLDetectArray(XmlDocument doc, XmlElement parent, DetectParams[] detect) | 211 | private static void AppendXMLDetectArray(XmlDocument doc, XmlElement parent, DetectParams[] detect) |
306 | { | 212 | { |
307 | foreach (DetectParams d in detect) | 213 | foreach(DetectParams d in detect) |
308 | { | 214 | { |
309 | XmlElement detectParamsN = GetXMLDetect(doc, d); | 215 | XmlElement detectParamsN = GetXMLDetect(doc, d); |
310 | parent.AppendChild(detectParamsN); | 216 | parent.AppendChild(detectParamsN); |
@@ -367,7 +273,7 @@ namespace OpenSim.Region.ScriptEngine.XMREngine | |||
367 | */ | 273 | */ |
368 | private static void AppendXMLObjectArray(XmlDocument doc, XmlNode parent, object[] array, string tag) | 274 | private static void AppendXMLObjectArray(XmlDocument doc, XmlNode parent, object[] array, string tag) |
369 | { | 275 | { |
370 | foreach (object o in array) | 276 | foreach(object o in array) |
371 | { | 277 | { |
372 | XmlElement element = GetXMLObject(doc, o, tag); | 278 | XmlElement element = GetXMLObject(doc, o, tag); |
373 | parent.AppendChild(element); | 279 | parent.AppendChild(element); |
@@ -385,7 +291,7 @@ namespace OpenSim.Region.ScriptEngine.XMREngine | |||
385 | XmlAttribute typ = doc.CreateAttribute("", "type", ""); | 291 | XmlAttribute typ = doc.CreateAttribute("", "type", ""); |
386 | XmlElement n = doc.CreateElement("", tag, ""); | 292 | XmlElement n = doc.CreateElement("", tag, ""); |
387 | 293 | ||
388 | if (o is LSL_List) | 294 | if(o is LSL_List) |
389 | { | 295 | { |
390 | typ.Value = "list"; | 296 | typ.Value = "list"; |
391 | n.Attributes.Append(typ); | 297 | n.Attributes.Append(typ); |