diff options
author | Dr Scofield | 2009-01-28 09:52:09 +0000 |
---|---|---|
committer | Dr Scofield | 2009-01-28 09:52:09 +0000 |
commit | ce1e1854b129c2e223b399857b2e0c1a842c7186 (patch) | |
tree | f751c3dced33f681eacf1cac5d2fd96ee6058680 /OpenSim/Region | |
parent | From: Christopher Yeoh <yeohc@au1.ibm.com> (diff) | |
download | opensim-SC-ce1e1854b129c2e223b399857b2e0c1a842c7186.zip opensim-SC-ce1e1854b129c2e223b399857b2e0c1a842c7186.tar.gz opensim-SC-ce1e1854b129c2e223b399857b2e0c1a842c7186.tar.bz2 opensim-SC-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.
Diffstat (limited to 'OpenSim/Region')
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 | } |