aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorDr Scofield2009-01-28 09:52:09 +0000
committerDr Scofield2009-01-28 09:52:09 +0000
commitce1e1854b129c2e223b399857b2e0c1a842c7186 (patch)
treef751c3dced33f681eacf1cac5d2fd96ee6058680
parentFrom: Christopher Yeoh <yeohc@au1.ibm.com> (diff)
downloadopensim-SC_OLD-ce1e1854b129c2e223b399857b2e0c1a842c7186.zip
opensim-SC_OLD-ce1e1854b129c2e223b399857b2e0c1a842c7186.tar.gz
opensim-SC_OLD-ce1e1854b129c2e223b399857b2e0c1a842c7186.tar.bz2
opensim-SC_OLD-ce1e1854b129c2e223b399857b2e0c1a842c7186.tar.xz
From: Christopher Yeoh <yeohc@au1.ibm.com>
This changeset fixes a race condition where a script (XEngine run) can startup before a reference is added to it in all of the required places in the XEngine class. The effect of this is that a script can sometimes on startup miss script events. For example a script which starts up and initialises itself from a notecard may never receive the dataserver event containing the notecard information. The patch isn't as clean as I'd like - I've split the constructor of ScriptInstance up so it does everything it did before except call Startup and post events like state_entry and on_rez. An Init function has been added which is called after the ScriptInstance object has been added to the necessary data structures in XEngine. Happy to rework it if someone suggests a better way of doing it.
-rw-r--r--OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs1
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs82
-rw-r--r--OpenSim/Region/ScriptEngine/XEngine/XEngine.cs19
3 files changed, 61 insertions, 41 deletions
diff --git a/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs b/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs
index 3367b77..017a6ba 100644
--- a/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs
+++ b/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs
@@ -73,6 +73,7 @@ namespace OpenSim.Region.ScriptEngine.Interfaces
73 73
74 void RemoveState(); 74 void RemoveState();
75 75
76 void Init();
76 void Start(); 77 void Start();
77 bool Stop(int timeout); 78 bool Stop(int timeout);
78 void SetState(string state); 79 void SetState(string state);
diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
index 8d6966f..f808f12 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
@@ -88,6 +88,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
88 private double m_minEventDelay = 0; 88 private double m_minEventDelay = 0;
89 private long m_eventDelayTicks = 0; 89 private long m_eventDelayTicks = 0;
90 private long m_nextEventTimeTicks = 0; 90 private long m_nextEventTimeTicks = 0;
91 private bool m_startOnInit = true;
92 private StateSource m_stateSource;
93 private bool m_postOnRez;
94 private bool m_startedFromSavedState = false;
91 95
92 //private ISponsor m_ScriptSponsor; 96 //private ISponsor m_ScriptSponsor;
93 private Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>> 97 private Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>>
@@ -224,6 +228,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
224 m_Assembly = assembly; 228 m_Assembly = assembly;
225 m_StartParam = startParam; 229 m_StartParam = startParam;
226 m_MaxScriptQueue = maxScriptQueue; 230 m_MaxScriptQueue = maxScriptQueue;
231 m_stateSource = stateSource;
232 m_postOnRez = postOnRez;
227 233
228 if (part != null && part.TaskInventory.ContainsKey(m_ItemID)) 234 if (part != null && part.TaskInventory.ContainsKey(m_ItemID))
229 { 235 {
@@ -313,10 +319,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
313 if (m_RunEvents && (!m_ShuttingDown)) 319 if (m_RunEvents && (!m_ShuttingDown))
314 { 320 {
315 m_RunEvents = false; 321 m_RunEvents = false;
316 Start(); 322 }
317 if (postOnRez) 323 else
318 PostEvent(new EventParams("on_rez", 324 {
319 new Object[] {new LSL_Types.LSLInteger(startParam)}, new DetectParams[0])); 325 m_RunEvents = false;
326 m_startOnInit = false;
320 } 327 }
321 328
322 // we get new rez events on sim restart, too 329 // we get new rez events on sim restart, too
@@ -325,42 +332,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
325 332
326 // We loaded state, don't force a re-save 333 // We loaded state, don't force a re-save
327 m_SaveState = false; 334 m_SaveState = false;
335 m_startedFromSavedState = true;
328 336
329 if (stateSource == StateSource.NewRez)
330 {
331// m_Engine.Log.Debug("[Script] Posted changed(CHANGED_REGION_RESTART) to script");
332 PostEvent(new EventParams("changed",
333 new Object[] {new LSL_Types.LSLInteger(256)}, new DetectParams[0]));
334 }
335 else if (stateSource == StateSource.PrimCrossing)
336 {
337 // CHANGED_REGION
338 PostEvent(new EventParams("changed",
339 new Object[] {new LSL_Types.LSLInteger(512)}, new DetectParams[0]));
340 }
341 } 337 }
342 } 338 }
343 else 339 else
344 { 340 {
345 m_Engine.Log.Error("[Script] Unable to load script state: Memory limit exceeded"); 341 m_Engine.Log.Error("[Script] Unable to load script state: Memory limit exceeded");
346 Start();
347 PostEvent(new EventParams("state_entry",
348 new Object[0], new DetectParams[0]));
349 if (postOnRez)
350 PostEvent(new EventParams("on_rez",
351 new Object[] {new LSL_Types.LSLInteger(startParam)}, new DetectParams[0]));
352
353 } 342 }
354 } 343 }
355 catch (Exception e) 344 catch (Exception e)
356 { 345 {
357 m_Engine.Log.ErrorFormat("[Script] Unable to load script state from xml: {0}\n"+e.ToString(), xml); 346 m_Engine.Log.ErrorFormat("[Script] Unable to load script state from xml: {0}\n"+e.ToString(), xml);
358 Start();
359 PostEvent(new EventParams("state_entry",
360 new Object[0], new DetectParams[0]));
361 if (postOnRez)
362 PostEvent(new EventParams("on_rez",
363 new Object[] {new LSL_Types.LSLInteger(startParam)}, new DetectParams[0]));
364 } 347 }
365 } 348 }
366 else 349 else
@@ -371,13 +354,46 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
371 presence.ControllingClient.SendAgentAlertMessage("Compile successful", false); 354 presence.ControllingClient.SendAgentAlertMessage("Compile successful", false);
372 355
373// m_Engine.Log.ErrorFormat("[Script] Unable to load script state, file not found"); 356// m_Engine.Log.ErrorFormat("[Script] Unable to load script state, file not found");
357 }
358 }
359
360 public void Init()
361 {
362 if (!m_startOnInit) return;
363
364 if (m_startedFromSavedState)
365 {
374 Start(); 366 Start();
375 PostEvent(new EventParams("state_entry", 367 if (m_postOnRez)
376 new Object[0], new DetectParams[0])); 368 {
369 PostEvent(new EventParams("on_rez",
370 new Object[] {new LSL_Types.LSLInteger(m_StartParam)}, new DetectParams[0]));
371 }
377 372
378 if (postOnRez) 373 if (m_stateSource == StateSource.NewRez)
374 {
375// m_Engine.Log.Debug("[Script] Posted changed(CHANGED_REGION_RESTART) to script");
376 PostEvent(new EventParams("changed",
377 new Object[] {new LSL_Types.LSLInteger(256)}, new DetectParams[0]));
378 }
379 else if (m_stateSource == StateSource.PrimCrossing)
380 {
381 // CHANGED_REGION
382 PostEvent(new EventParams("changed",
383 new Object[] {new LSL_Types.LSLInteger(512)}, new DetectParams[0]));
384 }
385 }
386 else
387 {
388 Start();
389 PostEvent(new EventParams("state_entry",
390 new Object[0], new DetectParams[0]));
391 if (m_postOnRez)
392 {
379 PostEvent(new EventParams("on_rez", 393 PostEvent(new EventParams("on_rez",
380 new Object[] {new LSL_Types.LSLInteger(startParam)}, new DetectParams[0])); 394 new Object[] {new LSL_Types.LSLInteger(m_StartParam)}, new DetectParams[0]));
395 }
396
381 } 397 }
382 } 398 }
383 399
diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
index fc76d0b..a0a0037 100644
--- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
+++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
@@ -544,6 +544,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
544 544
545 lock (m_Scripts) 545 lock (m_Scripts)
546 { 546 {
547 ScriptInstance instance = null;
547 // Create the object record 548 // Create the object record
548 549
549 if ((!m_Scripts.ContainsKey(itemID)) || 550 if ((!m_Scripts.ContainsKey(itemID)) ||
@@ -596,14 +597,13 @@ namespace OpenSim.Region.ScriptEngine.XEngine
596 } 597 }
597 m_DomainScripts[appDomain].Add(itemID); 598 m_DomainScripts[appDomain].Add(itemID);
598 599
599 ScriptInstance instance = 600 instance = new ScriptInstance(this, part,
600 new ScriptInstance(this, part, 601 itemID, assetID, assembly,
601 itemID, assetID, assembly, 602 m_AppDomains[appDomain],
602 m_AppDomains[appDomain], 603 part.ParentGroup.RootPart.Name,
603 part.ParentGroup.RootPart.Name, 604 item.Name, startParam, postOnRez,
604 item.Name, startParam, postOnRez, 605 stateSource, m_MaxScriptQueue);
605 stateSource, m_MaxScriptQueue); 606
606
607 m_log.DebugFormat("[XEngine] Loaded script {0}.{1}", 607 m_log.DebugFormat("[XEngine] Loaded script {0}.{1}",
608 part.ParentGroup.RootPart.Name, item.Name); 608 part.ParentGroup.RootPart.Name, item.Name);
609 609
@@ -625,6 +625,9 @@ namespace OpenSim.Region.ScriptEngine.XEngine
625 625
626 if (!m_Assemblies.ContainsKey(assetID)) 626 if (!m_Assemblies.ContainsKey(assetID))
627 m_Assemblies[assetID] = assembly; 627 m_Assemblies[assetID] = assembly;
628
629 if (instance!=null)
630 instance.Init();
628 } 631 }
629 return true; 632 return true;
630 } 633 }