aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ScriptEngine/Shared/Instance
diff options
context:
space:
mode:
authorJustin Clark-Casey (justincc)2015-01-16 23:55:00 +0000
committerJustin Clark-Casey (justincc)2015-01-16 23:55:11 +0000
commitfaaf47a86f34f24dec0d7d51eda638d0df3db305 (patch)
tree999a9351ae53e4ecc0b465e8e1bea744cb335837 /OpenSim/Region/ScriptEngine/Shared/Instance
parentFor scripts in attachments, don't save .state files apart from the initial on... (diff)
downloadopensim-SC-faaf47a86f34f24dec0d7d51eda638d0df3db305.zip
opensim-SC-faaf47a86f34f24dec0d7d51eda638d0df3db305.tar.gz
opensim-SC-faaf47a86f34f24dec0d7d51eda638d0df3db305.tar.bz2
opensim-SC-faaf47a86f34f24dec0d7d51eda638d0df3db305.tar.xz
Prevent a race condition between the script engine backup thread and script removal by locking on the script's EventQueue and only proceeding if it's flagged as still running.
Relates to http://opensimulator.org/mantis/view.php?id=7407
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs70
1 files changed, 40 insertions, 30 deletions
diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
index 9498aa8..e202a24 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
@@ -564,7 +564,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
564 } 564 }
565 } 565 }
566 566
567 public bool Stop(int timeout) 567 public bool Stop(int timeout, bool clearEventQueue = false)
568 { 568 {
569 if (DebugLevel >= 1) 569 if (DebugLevel >= 1)
570 m_log.DebugFormat( 570 m_log.DebugFormat(
@@ -575,6 +575,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
575 575
576 lock (EventQueue) 576 lock (EventQueue)
577 { 577 {
578 if (clearEventQueue)
579 ClearQueue();
580
578 if (!Running) 581 if (!Running)
579 return true; 582 return true;
580 583
@@ -1065,45 +1068,52 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
1065 1068
1066 public void SaveState() 1069 public void SaveState()
1067 { 1070 {
1068 // If we're currently in an event, just tell it to save upon return 1071 // We need to lock here to avoid any race with a thread that is removing this script.
1069 // 1072 lock (EventQueue)
1070 if (m_InEvent)
1071 { 1073 {
1072 m_SaveState = true; 1074 if (!Running)
1073 return; 1075 return;
1074 }
1075 1076
1076// m_log.DebugFormat( 1077 // If we're currently in an event, just tell it to save upon return
1077// "[SCRIPT INSTANCE]: Saving state for script {0} (id {1}) in part {2} (id {3}) in object {4} in {5}", 1078 //
1078// ScriptTask.Name, ScriptTask.ItemID, Part.Name, Part.UUID, Part.ParentGroup.Name, Engine.World.Name); 1079 if (m_InEvent)
1080 {
1081 m_SaveState = true;
1082 return;
1083 }
1079 1084
1080 PluginData = AsyncCommandManager.GetSerializationData(Engine, ItemID); 1085 // m_log.DebugFormat(
1086 // "[SCRIPT INSTANCE]: Saving state for script {0} (id {1}) in part {2} (id {3}) in object {4} in {5}",
1087 // ScriptTask.Name, ScriptTask.ItemID, Part.Name, Part.UUID, Part.ParentGroup.Name, Engine.World.Name);
1081 1088
1082 string xml = ScriptSerializer.Serialize(this); 1089 PluginData = AsyncCommandManager.GetSerializationData(Engine, ItemID);
1083 1090
1084 // Compare hash of the state we just just created with the state last written to disk 1091 string xml = ScriptSerializer.Serialize(this);
1085 // If the state is different, update the disk file.
1086 UUID hash = UUID.Parse(Utils.MD5String(xml));
1087 1092
1088 if (hash != m_CurrentStateHash) 1093 // Compare hash of the state we just just created with the state last written to disk
1089 { 1094 // If the state is different, update the disk file.
1090 try 1095 UUID hash = UUID.Parse(Utils.MD5String(xml));
1096
1097 if (hash != m_CurrentStateHash)
1091 { 1098 {
1092 using (FileStream fs = File.Create(Path.Combine(m_dataPath, ItemID.ToString() + ".state"))) 1099 try
1100 {
1101 using (FileStream fs = File.Create(Path.Combine(m_dataPath, ItemID.ToString() + ".state")))
1102 {
1103 Byte[] buf = Util.UTF8NoBomEncoding.GetBytes(xml);
1104 fs.Write(buf, 0, buf.Length);
1105 }
1106 }
1107 catch(Exception)
1093 { 1108 {
1094 Byte[] buf = Util.UTF8NoBomEncoding.GetBytes(xml); 1109 // m_log.Error("Unable to save xml\n"+e.ToString());
1095 fs.Write(buf, 0, buf.Length);
1096 } 1110 }
1111 //if (!File.Exists(Path.Combine(Path.GetDirectoryName(assembly), ItemID.ToString() + ".state")))
1112 //{
1113 // throw new Exception("Completed persistence save, but no file was created");
1114 //}
1115 m_CurrentStateHash = hash;
1097 } 1116 }
1098 catch(Exception)
1099 {
1100 // m_log.Error("Unable to save xml\n"+e.ToString());
1101 }
1102 //if (!File.Exists(Path.Combine(Path.GetDirectoryName(assembly), ItemID.ToString() + ".state")))
1103 //{
1104 // throw new Exception("Completed persistence save, but no file was created");
1105 //}
1106 m_CurrentStateHash = hash;
1107 } 1117 }
1108 } 1118 }
1109 1119