aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ScriptEngine/XMREngine/XMRInstCapture.cs
diff options
context:
space:
mode:
authorUbitUmarov2018-02-02 12:49:40 +0000
committerUbitUmarov2018-02-02 12:49:40 +0000
commit83e2fee71be695b78438e0c9dc50b649a539d0e3 (patch)
treeaf213fea5ebfa4e773af6942c753e7f3bba0d83f /OpenSim/Region/ScriptEngine/XMREngine/XMRInstCapture.cs
parentMerge branch 'master' into httptests (diff)
downloadopensim-SC-83e2fee71be695b78438e0c9dc50b649a539d0e3.zip
opensim-SC-83e2fee71be695b78438e0c9dc50b649a539d0e3.tar.gz
opensim-SC-83e2fee71be695b78438e0c9dc50b649a539d0e3.tar.bz2
opensim-SC-83e2fee71be695b78438e0c9dc50b649a539d0e3.tar.xz
add experimental script engine XMRengine donated by mrieker (DreamNation) And our Melanie. ***DANGER*** ***TESTONLY*** ***disable HG*** dont leave running when not looking... tp/crossing to Xengine will reset scripts. i do see a few issues but should be testable, so we can decide if we should invest more on it.
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/ScriptEngine/XMREngine/XMRInstCapture.cs436
1 files changed, 436 insertions, 0 deletions
diff --git a/OpenSim/Region/ScriptEngine/XMREngine/XMRInstCapture.cs b/OpenSim/Region/ScriptEngine/XMREngine/XMRInstCapture.cs
new file mode 100644
index 0000000..8950d63
--- /dev/null
+++ b/OpenSim/Region/ScriptEngine/XMREngine/XMRInstCapture.cs
@@ -0,0 +1,436 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
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;
36using System.Xml;
37using System.Text;
38using OpenMetaverse;
39using OpenSim.Framework;
40using OpenSim.Region.ScriptEngine.Interfaces;
41using OpenSim.Region.ScriptEngine.Shared;
42using OpenSim.Region.ScriptEngine.Shared.Api;
43using OpenSim.Region.ScriptEngine.Shared.ScriptBase;
44using OpenSim.Region.ScriptEngine.XMREngine;
45using OpenSim.Region.Framework.Scenes;
46using log4net;
47
48using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat;
49using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
50using LSL_Key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
51using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list;
52using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
53using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
54using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
55
56namespace OpenSim.Region.ScriptEngine.XMREngine
57{
58 public partial class XMRInstance
59 {
60 /********************************************************************************\
61 * The only method of interest to outside this module is GetExecutionState() *
62 * which captures the current state of the script into an XML document. *
63 * *
64 * The rest of this module contains support routines for GetExecutionState(). *
65 \********************************************************************************/
66
67 /**
68 * @brief Create an XML element that gives the current state of the script.
69 * <ScriptState Engine="XMREngine" SourceHash=m_ObjCode.sourceHash Asset=m_Item.AssetID>
70 * <Snapshot>globalsandstackdump</Snapshot>
71 * <Running>m_Running</Running>
72 * <DetectArray ...
73 * <EventQueue ...
74 * <Permissions ...
75 * <Plugins />
76 * </ScriptState>
77 * Updates the .state file while we're at it.
78 */
79 public XmlElement GetExecutionState(XmlDocument doc)
80 {
81 /*
82 * When we're detaching an attachment, we need to wait here.
83 */
84
85 // Change this to a 5 second timeout. If things do mess up,
86 // we don't want to be stuck forever.
87 //
88 m_DetachReady.WaitOne (5000, false);
89
90 XmlElement scriptStateN = doc.CreateElement("", "ScriptState", "");
91 scriptStateN.SetAttribute("Engine", m_Engine.ScriptEngineName);
92 scriptStateN.SetAttribute("Asset", m_Item.AssetID.ToString());
93 scriptStateN.SetAttribute ("SourceHash", m_ObjCode.sourceHash);
94
95 /*
96 * Make sure we aren't executing part of the script so it stays
97 * stable. Setting suspendOnCheckRun tells CheckRun() to suspend
98 * and return out so RunOne() will release the lock asap.
99 */
100 suspendOnCheckRunHold = true;
101 lock (m_RunLock)
102 {
103 m_RunOnePhase = "GetExecutionState enter";
104 CheckRunLockInvariants(true);
105
106 /*
107 * Get copy of script globals and stack in relocateable form.
108 */
109 MemoryStream snapshotStream = new MemoryStream();
110 MigrateOutEventHandler(snapshotStream);
111 Byte[] snapshotBytes = snapshotStream.ToArray();
112 snapshotStream.Close();
113 string snapshotString = Convert.ToBase64String(snapshotBytes);
114 XmlElement snapshotN = doc.CreateElement("", "Snapshot", "");
115 snapshotN.AppendChild(doc.CreateTextNode(snapshotString));
116 scriptStateN.AppendChild(snapshotN);
117 m_RunOnePhase = "GetExecutionState B"; CheckRunLockInvariants(true);
118
119 /*
120 * "Running" says whether or not we are accepting new events.
121 */
122 XmlElement runningN = doc.CreateElement("", "Running", "");
123 runningN.AppendChild(doc.CreateTextNode(m_Running.ToString()));
124 scriptStateN.AppendChild(runningN);
125 m_RunOnePhase = "GetExecutionState C"; CheckRunLockInvariants(true);
126
127 /*
128 * "DoGblInit" says whether or not default:state_entry() will init global vars.
129 */
130 XmlElement doGblInitN = doc.CreateElement("", "DoGblInit", "");
131 doGblInitN.AppendChild(doc.CreateTextNode(doGblInit.ToString()));
132 scriptStateN.AppendChild(doGblInitN);
133 m_RunOnePhase = "GetExecutionState D"; CheckRunLockInvariants(true);
134
135 /*
136 * More misc data.
137 */
138 XmlNode permissionsN = doc.CreateElement("", "Permissions", "");
139 scriptStateN.AppendChild(permissionsN);
140
141 XmlAttribute granterA = doc.CreateAttribute("", "granter", "");
142 granterA.Value = m_Item.PermsGranter.ToString();
143 permissionsN.Attributes.Append(granterA);
144
145 XmlAttribute maskA = doc.CreateAttribute("", "mask", "");
146 maskA.Value = m_Item.PermsMask.ToString();
147 permissionsN.Attributes.Append(maskA);
148 m_RunOnePhase = "GetExecutionState E"; CheckRunLockInvariants(true);
149
150 /*
151 * "DetectParams" are returned by llDetected...() script functions
152 * for the currently active event, if any.
153 */
154 if (m_DetectParams != null)
155 {
156 XmlElement detParArrayN = doc.CreateElement("", "DetectArray", "");
157 AppendXMLDetectArray(doc, detParArrayN, m_DetectParams);
158 scriptStateN.AppendChild(detParArrayN);
159 }
160 m_RunOnePhase = "GetExecutionState F"; CheckRunLockInvariants(true);
161
162 /*
163 * Save any events we have in the queue.
164 * <EventQueue>
165 * <Event Name="...">
166 * <param>...</param> ...
167 * <DetectParams>...</DetectParams> ...
168 * </Event>
169 * ...
170 * </EventQueue>
171 */
172 XmlElement queuedEventsN = doc.CreateElement("", "EventQueue", "");
173 lock (m_QueueLock)
174 {
175 foreach (EventParams evt in m_EventQueue)
176 {
177 XmlElement singleEventN = doc.CreateElement("", "Event", "");
178 singleEventN.SetAttribute("Name", evt.EventName);
179 AppendXMLObjectArray(doc, singleEventN, evt.Params, "param");
180 AppendXMLDetectArray(doc, singleEventN, evt.DetectParams);
181 queuedEventsN.AppendChild(singleEventN);
182 }
183 }
184 scriptStateN.AppendChild(queuedEventsN);
185 m_RunOnePhase = "GetExecutionState G"; CheckRunLockInvariants(true);
186
187 /*
188 * "Plugins" indicate enabled timers and listens, etc.
189 */
190 Object[] pluginData =
191 AsyncCommandManager.GetSerializationData(m_Engine,
192 m_ItemID);
193
194 XmlNode plugins = doc.CreateElement("", "Plugins", "");
195 AppendXMLObjectArray(doc, plugins, pluginData, "plugin");
196 scriptStateN.AppendChild(plugins);
197 m_RunOnePhase = "GetExecutionState H"; CheckRunLockInvariants(true);
198
199 /*
200 * Let script run again.
201 */
202 suspendOnCheckRunHold = false;
203
204 m_RunOnePhase = "GetExecutionState leave";
205 CheckRunLockInvariants(true);
206 }
207
208 /*
209 * scriptStateN represents the contents of the .state file so
210 * write the .state file while we are here.
211 */
212 FileStream fs = File.Create(m_StateFileName);
213 StreamWriter sw = new StreamWriter(fs);
214 sw.Write(scriptStateN.OuterXml);
215 sw.Close();
216 fs.Close();
217
218 return scriptStateN;
219 }
220
221 /**
222 * @brief Write script state to output stream.
223 * The script microthread is at same state on return,
224 * ie, either inactive or suspended inside CheckRun().
225 *
226 * Input:
227 * stream = stream to write event handler state information to
228 */
229 private void MigrateOutEventHandler (Stream stream)
230 {
231 moehexcep = null;
232
233 // do all the work in the MigrateOutEventHandlerThread() method below
234 moehstream = stream;
235
236 XMRScriptThread cst = XMRScriptThread.CurrentScriptThread ();
237 if (cst != null) {
238
239 // we might be getting called inside some LSL Api function
240 // so we are already in script thread and thus must do
241 // migration directly
242 MigrateOutEventHandlerThread ();
243 } else {
244
245 // some other thread, do migration via a script thread
246 lock (XMRScriptThread.m_WakeUpLock) {
247 m_Engine.m_ThunkQueue.Enqueue (this.MigrateOutEventHandlerThread);
248 }
249 XMRScriptThread.WakeUpOne ();
250
251 // wait for it to complete
252 lock (moehdone) {
253 while (moehstream != null) {
254 Monitor.Wait (moehdone);
255 }
256 }
257 }
258
259 // maybe it threw up
260 if (moehexcep != null) throw moehexcep;
261 }
262 private Exception moehexcep;
263 private object moehdone = new object ();
264 private Stream moehstream;
265 private void MigrateOutEventHandlerThread ()
266 {
267 Exception except;
268
269 try {
270
271 /*
272 * Resume the microthread and it will throw a StackCaptureException()
273 * with the stack frames saved to this.stackFrames.
274 * Then write the saved stack frames to the output stream.
275 *
276 * There is a stack only if the event code is not None.
277 */
278 if (this.eventCode != ScriptEventCode.None) {
279
280 // tell microthread to continue
281 // it should see captureStackFrames and throw StackCaptureException()
282 // ...generating XMRStackFrames as it unwinds
283 this.captureStackFrames = true;
284 except = this.microthread.ResumeEx ();
285 this.captureStackFrames = false;
286 if (except == null) {
287 throw new Exception ("stack save did not complete");
288 }
289 if (!(except is StackCaptureException)) {
290 throw except;
291 }
292 }
293
294 /*
295 * Write script state out, frames and all, to the stream.
296 * Does not change script state.
297 */
298 moehstream.WriteByte (migrationVersion);
299 moehstream.WriteByte ((byte)16);
300 this.MigrateOut (new BinaryWriter (moehstream));
301
302 /*
303 * Now restore script stack.
304 * Microthread will suspend inside CheckRun() when restore is complete.
305 */
306 if (this.eventCode != ScriptEventCode.None) {
307 this.stackFramesRestored = false;
308 except = this.microthread.StartEx ();
309 if (except != null) {
310 throw except;
311 }
312 if (!this.stackFramesRestored) {
313 throw new Exception ("restore after save did not complete");
314 }
315 }
316 } catch (Exception e) {
317 moehexcep = e;
318 } finally {
319
320 // make sure CheckRunLockInvariants() won't puque
321 if (this.microthread.Active () == 0) {
322 this.eventCode = ScriptEventCode.None;
323 }
324
325 // wake the MigrateOutEventHandler() method above
326 lock (moehdone) {
327 moehstream = null;
328 Monitor.Pulse (moehdone);
329 }
330 }
331 }
332
333 /**
334 * @brief Convert an DetectParams[] to corresponding XML.
335 * DetectParams[] holds the values retrievable by llDetected...() for
336 * a given event.
337 */
338 private static void AppendXMLDetectArray(XmlDocument doc, XmlElement parent, DetectParams[] detect)
339 {
340 foreach (DetectParams d in detect)
341 {
342 XmlElement detectParamsN = GetXMLDetect(doc, d);
343 parent.AppendChild(detectParamsN);
344 }
345 }
346
347 private static XmlElement GetXMLDetect(XmlDocument doc, DetectParams d)
348 {
349 XmlElement detectParamsN = doc.CreateElement("", "DetectParams", "");
350
351 XmlAttribute d_key = doc.CreateAttribute("", "key", "");
352 d_key.Value = d.Key.ToString();
353 detectParamsN.Attributes.Append(d_key);
354
355 XmlAttribute pos = doc.CreateAttribute("", "pos", "");
356 pos.Value = d.OffsetPos.ToString();
357 detectParamsN.Attributes.Append(pos);
358
359 XmlAttribute d_linkNum = doc.CreateAttribute("", "linkNum", "");
360 d_linkNum.Value = d.LinkNum.ToString();
361 detectParamsN.Attributes.Append(d_linkNum);
362
363 XmlAttribute d_group = doc.CreateAttribute("", "group", "");
364 d_group.Value = d.Group.ToString();
365 detectParamsN.Attributes.Append(d_group);
366
367 XmlAttribute d_name = doc.CreateAttribute("", "name", "");
368 d_name.Value = d.Name.ToString();
369 detectParamsN.Attributes.Append(d_name);
370
371 XmlAttribute d_owner = doc.CreateAttribute("", "owner", "");
372 d_owner.Value = d.Owner.ToString();
373 detectParamsN.Attributes.Append(d_owner);
374
375 XmlAttribute d_position = doc.CreateAttribute("", "position", "");
376 d_position.Value = d.Position.ToString();
377 detectParamsN.Attributes.Append(d_position);
378
379 XmlAttribute d_rotation = doc.CreateAttribute("", "rotation", "");
380 d_rotation.Value = d.Rotation.ToString();
381 detectParamsN.Attributes.Append(d_rotation);
382
383 XmlAttribute d_type = doc.CreateAttribute("", "type", "");
384 d_type.Value = d.Type.ToString();
385 detectParamsN.Attributes.Append(d_type);
386
387 XmlAttribute d_velocity = doc.CreateAttribute("", "velocity", "");
388 d_velocity.Value = d.Velocity.ToString();
389 detectParamsN.Attributes.Append(d_velocity);
390
391 return detectParamsN;
392 }
393
394 /**
395 * @brief Append elements of an array of objects to an XML parent.
396 * @param doc = document the parent is part of
397 * @param parent = parent to append the items to
398 * @param array = array of objects
399 * @param tag = <tag ..>...</tag> for each element
400 */
401 private static void AppendXMLObjectArray(XmlDocument doc, XmlNode parent, object[] array, string tag)
402 {
403 foreach (object o in array)
404 {
405 XmlElement element = GetXMLObject(doc, o, tag);
406 parent.AppendChild(element);
407 }
408 }
409
410 /**
411 * @brief Get and XML representation of an object.
412 * @param doc = document the tag will be put in
413 * @param o = object to be represented
414 * @param tag = <tag ...>...</tag>
415 */
416 private static XmlElement GetXMLObject(XmlDocument doc, object o, string tag)
417 {
418 XmlAttribute typ = doc.CreateAttribute("", "type", "");
419 XmlElement n = doc.CreateElement("", tag, "");
420
421 if (o is LSL_List)
422 {
423 typ.Value = "list";
424 n.Attributes.Append(typ);
425 AppendXMLObjectArray(doc, n, ((LSL_List)o).Data, "item");
426 }
427 else
428 {
429 typ.Value = o.GetType().ToString();
430 n.Attributes.Append(typ);
431 n.AppendChild(doc.CreateTextNode(o.ToString()));
432 }
433 return n;
434 }
435 }
436}