aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ScriptEngine/Shared/Instance
diff options
context:
space:
mode:
authorJustin Clark-Casey (justincc)2015-01-29 17:55:08 +0000
committerJustin Clark-Casey (justincc)2015-01-29 17:55:08 +0000
commitb4e955d1c107784ccf17a739cd83b2603f665d0c (patch)
treeb3a60117c47a975625883ee714dd0b4fc317dda6 /OpenSim/Region/ScriptEngine/Shared/Instance
parentCorrect typo in raw default script stop strategy (diff)
downloadopensim-SC-b4e955d1c107784ccf17a739cd83b2603f665d0c.zip
opensim-SC-b4e955d1c107784ccf17a739cd83b2603f665d0c.tar.gz
opensim-SC-b4e955d1c107784ccf17a739cd83b2603f665d0c.tar.bz2
opensim-SC-b4e955d1c107784ccf17a739cd83b2603f665d0c.tar.xz
Avoid a possible race condition by serializing plugin data outside the EventQueue lock in ScriptInstance.SaveState()
This takes the AsyncCommandHandler.staticLock. However, AsyncCommandHandler.DoOneCmdHandlerPass() already holds staticLock and may attempt to take the EventQueue lock via ScriptInstance.PostEvent() in XEngine.CheckListeners() This is a regression from faaf47a (Fri Jan 16 2015) but not simply reverting that commit since it will reintroduce a race between script removal, backup and event queue manipulating code.
Diffstat (limited to 'OpenSim/Region/ScriptEngine/Shared/Instance')
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs11
1 files changed, 9 insertions, 2 deletions
diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
index 5ff56a1..d28b151 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
@@ -1022,9 +1022,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
1022 1022
1023 public void SaveState() 1023 public void SaveState()
1024 { 1024 {
1025 if (!Running)
1026 return;
1027
1028 // We cannot call this inside the EventQueue lock since it will currently take AsyncCommandManager.staticLock.
1029 // This may already be held by AsyncCommandManager.DoOneCmdHandlerPass() which in turn can take EventQueue
1030 // lock via ScriptInstance.PostEvent().
1031 PluginData = AsyncCommandManager.GetSerializationData(Engine, ItemID);
1032
1025 // We need to lock here to avoid any race with a thread that is removing this script. 1033 // We need to lock here to avoid any race with a thread that is removing this script.
1026 lock (EventQueue) 1034 lock (EventQueue)
1027 { 1035 {
1036 // Check again to avoid a race with a thread in Stop()
1028 if (!Running) 1037 if (!Running)
1029 return; 1038 return;
1030 1039
@@ -1040,8 +1049,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
1040 // "[SCRIPT INSTANCE]: Saving state for script {0} (id {1}) in part {2} (id {3}) in object {4} in {5}", 1049 // "[SCRIPT INSTANCE]: Saving state for script {0} (id {1}) in part {2} (id {3}) in object {4} in {5}",
1041 // ScriptTask.Name, ScriptTask.ItemID, Part.Name, Part.UUID, Part.ParentGroup.Name, Engine.World.Name); 1050 // ScriptTask.Name, ScriptTask.ItemID, Part.Name, Part.UUID, Part.ParentGroup.Name, Engine.World.Name);
1042 1051
1043 PluginData = AsyncCommandManager.GetSerializationData(Engine, ItemID);
1044
1045 string xml = ScriptSerializer.Serialize(this); 1052 string xml = ScriptSerializer.Serialize(this);
1046 1053
1047 // Compare hash of the state we just just created with the state last written to disk 1054 // Compare hash of the state we just just created with the state last written to disk