diff options
Diffstat (limited to '')
-rw-r--r-- | OpenSim/Region/ScriptEngine/XEngine/XEngine.cs | 364 |
1 files changed, 233 insertions, 131 deletions
diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs index 7712076..1e0f01f 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs | |||
@@ -28,6 +28,7 @@ | |||
28 | using System; | 28 | using System; |
29 | using System.Collections; | 29 | using System.Collections; |
30 | using System.Collections.Generic; | 30 | using System.Collections.Generic; |
31 | using System.Diagnostics; //for [DebuggerNonUserCode] | ||
31 | using System.Globalization; | 32 | using System.Globalization; |
32 | using System.IO; | 33 | using System.IO; |
33 | using System.Reflection; | 34 | using System.Reflection; |
@@ -112,6 +113,8 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
112 | private Dictionary<UUID, IScriptInstance> m_Scripts = | 113 | private Dictionary<UUID, IScriptInstance> m_Scripts = |
113 | new Dictionary<UUID, IScriptInstance>(); | 114 | new Dictionary<UUID, IScriptInstance>(); |
114 | 115 | ||
116 | private OpenMetaverse.ReaderWriterLockSlim m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim(); | ||
117 | |||
115 | // Maps the asset ID to the assembly | 118 | // Maps the asset ID to the assembly |
116 | 119 | ||
117 | private Dictionary<UUID, string> m_Assemblies = | 120 | private Dictionary<UUID, string> m_Assemblies = |
@@ -134,6 +137,71 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
134 | IWorkItemResult m_CurrentCompile = null; | 137 | IWorkItemResult m_CurrentCompile = null; |
135 | private Dictionary<UUID, int> m_CompileDict = new Dictionary<UUID, int>(); | 138 | private Dictionary<UUID, int> m_CompileDict = new Dictionary<UUID, int>(); |
136 | 139 | ||
140 | private void lockScriptsForRead(bool locked) | ||
141 | { | ||
142 | if (locked) | ||
143 | { | ||
144 | if (m_scriptsLock.RecursiveReadCount > 0) | ||
145 | { | ||
146 | m_log.Error("[XEngine.m_Scripts] Recursive read lock requested. This should not happen and means something needs to be fixed. For now though, it's safe to continue."); | ||
147 | m_scriptsLock.ExitReadLock(); | ||
148 | } | ||
149 | if (m_scriptsLock.RecursiveWriteCount > 0) | ||
150 | { | ||
151 | m_log.Error("[XEngine.m_Scripts] Recursive write lock requested. This should not happen and means something needs to be fixed."); | ||
152 | m_scriptsLock.ExitWriteLock(); | ||
153 | } | ||
154 | |||
155 | while (!m_scriptsLock.TryEnterReadLock(60000)) | ||
156 | { | ||
157 | m_log.Error("[XEngine.m_Scripts] Thread lock detected while trying to aquire READ lock of m_scripts in XEngine. I'm going to try to solve the thread lock automatically to preserve region stability, but this needs to be fixed."); | ||
158 | if (m_scriptsLock.IsWriteLockHeld) | ||
159 | { | ||
160 | m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim(); | ||
161 | } | ||
162 | } | ||
163 | } | ||
164 | else | ||
165 | { | ||
166 | if (m_scriptsLock.RecursiveReadCount > 0) | ||
167 | { | ||
168 | m_scriptsLock.ExitReadLock(); | ||
169 | } | ||
170 | } | ||
171 | } | ||
172 | private void lockScriptsForWrite(bool locked) | ||
173 | { | ||
174 | if (locked) | ||
175 | { | ||
176 | if (m_scriptsLock.RecursiveReadCount > 0) | ||
177 | { | ||
178 | m_log.Error("[XEngine.m_Scripts] Recursive read lock requested. This should not happen and means something needs to be fixed. For now though, it's safe to continue."); | ||
179 | m_scriptsLock.ExitReadLock(); | ||
180 | } | ||
181 | if (m_scriptsLock.RecursiveWriteCount > 0) | ||
182 | { | ||
183 | m_log.Error("[XEngine.m_Scripts] Recursive write lock requested. This should not happen and means something needs to be fixed."); | ||
184 | m_scriptsLock.ExitWriteLock(); | ||
185 | } | ||
186 | |||
187 | while (!m_scriptsLock.TryEnterWriteLock(60000)) | ||
188 | { | ||
189 | m_log.Error("[XEngine.m_Scripts] Thread lock detected while trying to aquire WRITE lock of m_scripts in XEngine. I'm going to try to solve the thread lock automatically to preserve region stability, but this needs to be fixed."); | ||
190 | if (m_scriptsLock.IsWriteLockHeld) | ||
191 | { | ||
192 | m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim(); | ||
193 | } | ||
194 | } | ||
195 | } | ||
196 | else | ||
197 | { | ||
198 | if (m_scriptsLock.RecursiveWriteCount > 0) | ||
199 | { | ||
200 | m_scriptsLock.ExitWriteLock(); | ||
201 | } | ||
202 | } | ||
203 | } | ||
204 | |||
137 | public string ScriptEngineName | 205 | public string ScriptEngineName |
138 | { | 206 | { |
139 | get { return "XEngine"; } | 207 | get { return "XEngine"; } |
@@ -527,44 +595,37 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
527 | { | 595 | { |
528 | if (!m_Enabled) | 596 | if (!m_Enabled) |
529 | return; | 597 | return; |
530 | 598 | lockScriptsForRead(true); | |
531 | lock (m_Scripts) | 599 | foreach (IScriptInstance instance in m_Scripts.Values) |
532 | { | 600 | { |
533 | m_log.InfoFormat( | 601 | // Force a final state save |
534 | "[XEngine]: Shutting down {0} scripts in {1}", m_Scripts.Count, m_Scene.RegionInfo.RegionName); | 602 | // |
535 | 603 | if (m_Assemblies.ContainsKey(instance.AssetID)) | |
536 | foreach (IScriptInstance instance in m_Scripts.Values) | ||
537 | { | 604 | { |
538 | // Force a final state save | 605 | string assembly = m_Assemblies[instance.AssetID]; |
539 | // | 606 | instance.SaveState(assembly); |
540 | if (m_Assemblies.ContainsKey(instance.AssetID)) | 607 | } |
541 | { | ||
542 | string assembly = m_Assemblies[instance.AssetID]; | ||
543 | instance.SaveState(assembly); | ||
544 | } | ||
545 | 608 | ||
546 | // Clear the event queue and abort the instance thread | 609 | // Clear the event queue and abort the instance thread |
547 | // | 610 | // |
548 | instance.ClearQueue(); | 611 | instance.ClearQueue(); |
549 | instance.Stop(0); | 612 | instance.Stop(0); |
550 | 613 | ||
551 | // Release events, timer, etc | 614 | // Release events, timer, etc |
552 | // | 615 | // |
553 | instance.DestroyScriptInstance(); | 616 | instance.DestroyScriptInstance(); |
554 | 617 | ||
555 | // Unload scripts and app domains. | 618 | // Unload scripts and app domains |
556 | // Must be done explicitly because they have infinite | 619 | // Must be done explicitly because they have infinite |
557 | // lifetime. | 620 | // lifetime |
558 | // However, don't bother to do this if the simulator is shutting | 621 | // |
559 | // down since it takes a long time with many scripts. | 622 | if (!m_SimulatorShuttingDown) |
560 | if (!m_SimulatorShuttingDown) | 623 | { |
624 | m_DomainScripts[instance.AppDomain].Remove(instance.ItemID); | ||
625 | if (m_DomainScripts[instance.AppDomain].Count == 0) | ||
561 | { | 626 | { |
562 | m_DomainScripts[instance.AppDomain].Remove(instance.ItemID); | 627 | m_DomainScripts.Remove(instance.AppDomain); |
563 | if (m_DomainScripts[instance.AppDomain].Count == 0) | 628 | UnloadAppDomain(instance.AppDomain); |
564 | { | ||
565 | m_DomainScripts.Remove(instance.AppDomain); | ||
566 | UnloadAppDomain(instance.AppDomain); | ||
567 | } | ||
568 | } | 629 | } |
569 | } | 630 | } |
570 | 631 | ||
@@ -573,6 +634,14 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
573 | m_Assemblies.Clear(); | 634 | m_Assemblies.Clear(); |
574 | m_DomainScripts.Clear(); | 635 | m_DomainScripts.Clear(); |
575 | } | 636 | } |
637 | lockScriptsForRead(false); | ||
638 | lockScriptsForWrite(true); | ||
639 | m_Scripts.Clear(); | ||
640 | lockScriptsForWrite(false); | ||
641 | m_PrimObjects.Clear(); | ||
642 | m_Assemblies.Clear(); | ||
643 | m_DomainScripts.Clear(); | ||
644 | |||
576 | lock (m_ScriptEngines) | 645 | lock (m_ScriptEngines) |
577 | { | 646 | { |
578 | m_ScriptEngines.Remove(this); | 647 | m_ScriptEngines.Remove(this); |
@@ -637,22 +706,20 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
637 | 706 | ||
638 | List<IScriptInstance> instances = new List<IScriptInstance>(); | 707 | List<IScriptInstance> instances = new List<IScriptInstance>(); |
639 | 708 | ||
640 | lock (m_Scripts) | 709 | lockScriptsForRead(true); |
641 | { | 710 | foreach (IScriptInstance instance in m_Scripts.Values) |
642 | foreach (IScriptInstance instance in m_Scripts.Values) | ||
643 | instances.Add(instance); | 711 | instances.Add(instance); |
644 | } | 712 | lockScriptsForRead(false); |
645 | 713 | ||
646 | foreach (IScriptInstance i in instances) | 714 | foreach (IScriptInstance i in instances) |
647 | { | 715 | { |
648 | string assembly = String.Empty; | 716 | string assembly = String.Empty; |
649 | 717 | ||
650 | lock (m_Scripts) | 718 | |
651 | { | ||
652 | if (!m_Assemblies.ContainsKey(i.AssetID)) | 719 | if (!m_Assemblies.ContainsKey(i.AssetID)) |
653 | continue; | 720 | continue; |
654 | assembly = m_Assemblies[i.AssetID]; | 721 | assembly = m_Assemblies[i.AssetID]; |
655 | } | 722 | |
656 | 723 | ||
657 | i.SaveState(assembly); | 724 | i.SaveState(assembly); |
658 | } | 725 | } |
@@ -996,91 +1063,95 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
996 | } | 1063 | } |
997 | 1064 | ||
998 | ScriptInstance instance = null; | 1065 | ScriptInstance instance = null; |
999 | lock (m_Scripts) | 1066 | // Create the object record |
1067 | lockScriptsForRead(true); | ||
1068 | if ((!m_Scripts.ContainsKey(itemID)) || | ||
1069 | (m_Scripts[itemID].AssetID != assetID)) | ||
1000 | { | 1070 | { |
1001 | // Create the object record | 1071 | lockScriptsForRead(false); |
1002 | if ((!m_Scripts.ContainsKey(itemID)) || | ||
1003 | (m_Scripts[itemID].AssetID != assetID)) | ||
1004 | { | ||
1005 | UUID appDomain = assetID; | ||
1006 | 1072 | ||
1007 | if (part.ParentGroup.IsAttachment) | 1073 | UUID appDomain = assetID; |
1008 | appDomain = part.ParentGroup.RootPart.UUID; | ||
1009 | 1074 | ||
1010 | if (!m_AppDomains.ContainsKey(appDomain)) | 1075 | if (part.ParentGroup.IsAttachment) |
1011 | { | 1076 | appDomain = part.ParentGroup.RootPart.UUID; |
1012 | try | ||
1013 | { | ||
1014 | AppDomainSetup appSetup = new AppDomainSetup(); | ||
1015 | appSetup.PrivateBinPath = Path.Combine( | ||
1016 | m_ScriptEnginesPath, | ||
1017 | m_Scene.RegionInfo.RegionID.ToString()); | ||
1018 | |||
1019 | Evidence baseEvidence = AppDomain.CurrentDomain.Evidence; | ||
1020 | Evidence evidence = new Evidence(baseEvidence); | ||
1021 | |||
1022 | AppDomain sandbox; | ||
1023 | if (m_AppDomainLoading) | ||
1024 | sandbox = AppDomain.CreateDomain( | ||
1025 | m_Scene.RegionInfo.RegionID.ToString(), | ||
1026 | evidence, appSetup); | ||
1027 | else | ||
1028 | sandbox = AppDomain.CurrentDomain; | ||
1029 | |||
1030 | //PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel(); | ||
1031 | //AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition(); | ||
1032 | //PermissionSet sandboxPermissionSet = sandboxPolicy.GetNamedPermissionSet("Internet"); | ||
1033 | //PolicyStatement sandboxPolicyStatement = new PolicyStatement(sandboxPermissionSet); | ||
1034 | //CodeGroup sandboxCodeGroup = new UnionCodeGroup(sandboxMembershipCondition, sandboxPolicyStatement); | ||
1035 | //sandboxPolicy.RootCodeGroup = sandboxCodeGroup; | ||
1036 | //sandbox.SetAppDomainPolicy(sandboxPolicy); | ||
1037 | |||
1038 | m_AppDomains[appDomain] = sandbox; | ||
1039 | 1077 | ||
1040 | m_AppDomains[appDomain].AssemblyResolve += | 1078 | if (!m_AppDomains.ContainsKey(appDomain)) |
1041 | new ResolveEventHandler( | 1079 | { |
1042 | AssemblyResolver.OnAssemblyResolve); | 1080 | try |
1043 | m_DomainScripts[appDomain] = new List<UUID>(); | 1081 | { |
1044 | } | 1082 | AppDomainSetup appSetup = new AppDomainSetup(); |
1045 | catch (Exception e) | 1083 | appSetup.PrivateBinPath = Path.Combine( |
1084 | m_ScriptEnginesPath, | ||
1085 | m_Scene.RegionInfo.RegionID.ToString()); | ||
1086 | |||
1087 | Evidence baseEvidence = AppDomain.CurrentDomain.Evidence; | ||
1088 | Evidence evidence = new Evidence(baseEvidence); | ||
1089 | |||
1090 | AppDomain sandbox; | ||
1091 | if (m_AppDomainLoading) | ||
1092 | sandbox = AppDomain.CreateDomain( | ||
1093 | m_Scene.RegionInfo.RegionID.ToString(), | ||
1094 | evidence, appSetup); | ||
1095 | else | ||
1096 | sandbox = AppDomain.CurrentDomain; | ||
1097 | |||
1098 | //PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel(); | ||
1099 | //AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition(); | ||
1100 | //PermissionSet sandboxPermissionSet = sandboxPolicy.GetNamedPermissionSet("Internet"); | ||
1101 | //PolicyStatement sandboxPolicyStatement = new PolicyStatement(sandboxPermissionSet); | ||
1102 | //CodeGroup sandboxCodeGroup = new UnionCodeGroup(sandboxMembershipCondition, sandboxPolicyStatement); | ||
1103 | //sandboxPolicy.RootCodeGroup = sandboxCodeGroup; | ||
1104 | //sandbox.SetAppDomainPolicy(sandboxPolicy); | ||
1105 | |||
1106 | m_AppDomains[appDomain] = sandbox; | ||
1107 | |||
1108 | m_AppDomains[appDomain].AssemblyResolve += | ||
1109 | new ResolveEventHandler( | ||
1110 | AssemblyResolver.OnAssemblyResolve); | ||
1111 | m_DomainScripts[appDomain] = new List<UUID>(); | ||
1112 | } | ||
1113 | catch (Exception e) | ||
1114 | { | ||
1115 | m_log.ErrorFormat("[XEngine] Exception creating app domain:\n {0}", e.ToString()); | ||
1116 | m_ScriptErrorMessage += "Exception creating app domain:\n"; | ||
1117 | m_ScriptFailCount++; | ||
1118 | lock (m_AddingAssemblies) | ||
1046 | { | 1119 | { |
1047 | m_log.ErrorFormat("[XEngine] Exception creating app domain:\n {0}", e.ToString()); | 1120 | m_AddingAssemblies[assembly]--; |
1048 | m_ScriptErrorMessage += "Exception creating app domain:\n"; | ||
1049 | m_ScriptFailCount++; | ||
1050 | lock (m_AddingAssemblies) | ||
1051 | { | ||
1052 | m_AddingAssemblies[assembly]--; | ||
1053 | } | ||
1054 | return false; | ||
1055 | } | 1121 | } |
1122 | return false; | ||
1056 | } | 1123 | } |
1057 | m_DomainScripts[appDomain].Add(itemID); | 1124 | } |
1058 | 1125 | m_DomainScripts[appDomain].Add(itemID); | |
1059 | instance = new ScriptInstance(this, part, | 1126 | |
1060 | itemID, assetID, assembly, | 1127 | instance = new ScriptInstance(this, part, |
1061 | m_AppDomains[appDomain], | 1128 | itemID, assetID, assembly, |
1062 | part.ParentGroup.RootPart.Name, | 1129 | m_AppDomains[appDomain], |
1063 | item.Name, startParam, postOnRez, | 1130 | part.ParentGroup.RootPart.Name, |
1064 | stateSource, m_MaxScriptQueue); | 1131 | item.Name, startParam, postOnRez, |
1065 | 1132 | stateSource, m_MaxScriptQueue); | |
1066 | m_log.DebugFormat( | 1133 | |
1067 | "[XEngine] Loaded script {0}.{1}, item UUID {2}, prim UUID {3} @ {4}.{5}", | 1134 | m_log.DebugFormat( |
1068 | part.ParentGroup.RootPart.Name, item.Name, itemID, part.UUID, | 1135 | "[XEngine] Loaded script {0}.{1}, script UUID {2}, prim UUID {3} @ {4}.{5}", |
1136 | part.ParentGroup.RootPart.Name, item.Name, assetID, part.UUID, | ||
1069 | part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName); | 1137 | part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName); |
1070 | 1138 | ||
1071 | if (presence != null) | 1139 | if (presence != null) |
1072 | { | 1140 | { |
1073 | ShowScriptSaveResponse(item.OwnerID, | 1141 | ShowScriptSaveResponse(item.OwnerID, |
1074 | assetID, "Compile successful", true); | 1142 | assetID, "Compile successful", true); |
1075 | } | ||
1076 | |||
1077 | instance.AppDomain = appDomain; | ||
1078 | instance.LineMap = linemap; | ||
1079 | |||
1080 | m_Scripts[itemID] = instance; | ||
1081 | } | 1143 | } |
1082 | } | ||
1083 | 1144 | ||
1145 | instance.AppDomain = appDomain; | ||
1146 | instance.LineMap = linemap; | ||
1147 | lockScriptsForWrite(true); | ||
1148 | m_Scripts[itemID] = instance; | ||
1149 | lockScriptsForWrite(false); | ||
1150 | } | ||
1151 | else | ||
1152 | { | ||
1153 | lockScriptsForRead(false); | ||
1154 | } | ||
1084 | lock (m_PrimObjects) | 1155 | lock (m_PrimObjects) |
1085 | { | 1156 | { |
1086 | if (!m_PrimObjects.ContainsKey(localID)) | 1157 | if (!m_PrimObjects.ContainsKey(localID)) |
@@ -1098,9 +1169,9 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1098 | m_AddingAssemblies[assembly]--; | 1169 | m_AddingAssemblies[assembly]--; |
1099 | } | 1170 | } |
1100 | 1171 | ||
1101 | if (instance != null) | 1172 | if (instance!=null) |
1102 | instance.Init(); | 1173 | instance.Init(); |
1103 | 1174 | ||
1104 | return true; | 1175 | return true; |
1105 | } | 1176 | } |
1106 | 1177 | ||
@@ -1113,18 +1184,28 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1113 | m_CompileDict.Remove(itemID); | 1184 | m_CompileDict.Remove(itemID); |
1114 | } | 1185 | } |
1115 | 1186 | ||
1116 | IScriptInstance instance = null; | 1187 | lockScriptsForRead(true); |
1117 | 1188 | // Do we even have it? | |
1118 | lock (m_Scripts) | 1189 | if (!m_Scripts.ContainsKey(itemID)) |
1119 | { | 1190 | { |
1120 | // Do we even have it? | 1191 | // Do we even have it? |
1121 | if (!m_Scripts.ContainsKey(itemID)) | 1192 | if (!m_Scripts.ContainsKey(itemID)) |
1122 | return; | 1193 | return; |
1123 | 1194 | ||
1124 | instance = m_Scripts[itemID]; | 1195 | lockScriptsForRead(false); |
1196 | lockScriptsForWrite(true); | ||
1125 | m_Scripts.Remove(itemID); | 1197 | m_Scripts.Remove(itemID); |
1198 | lockScriptsForWrite(false); | ||
1199 | |||
1200 | return; | ||
1126 | } | 1201 | } |
1202 | |||
1127 | 1203 | ||
1204 | IScriptInstance instance=m_Scripts[itemID]; | ||
1205 | lockScriptsForRead(false); | ||
1206 | lockScriptsForWrite(true); | ||
1207 | m_Scripts.Remove(itemID); | ||
1208 | lockScriptsForWrite(false); | ||
1128 | instance.ClearQueue(); | 1209 | instance.ClearQueue(); |
1129 | 1210 | ||
1130 | // Give the script some time to finish processing its last event. Simply aborting the script thread can | 1211 | // Give the script some time to finish processing its last event. Simply aborting the script thread can |
@@ -1163,8 +1244,13 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1163 | 1244 | ||
1164 | ObjectRemoved handlerObjectRemoved = OnObjectRemoved; | 1245 | ObjectRemoved handlerObjectRemoved = OnObjectRemoved; |
1165 | if (handlerObjectRemoved != null) | 1246 | if (handlerObjectRemoved != null) |
1166 | handlerObjectRemoved(instance.ObjectID); | 1247 | { |
1248 | SceneObjectPart part = m_Scene.GetSceneObjectPart(localID); | ||
1249 | handlerObjectRemoved(part.UUID); | ||
1250 | } | ||
1167 | 1251 | ||
1252 | CleanAssemblies(); | ||
1253 | |||
1168 | ScriptRemoved handlerScriptRemoved = OnScriptRemoved; | 1254 | ScriptRemoved handlerScriptRemoved = OnScriptRemoved; |
1169 | if (handlerScriptRemoved != null) | 1255 | if (handlerScriptRemoved != null) |
1170 | handlerScriptRemoved(itemID); | 1256 | handlerScriptRemoved(itemID); |
@@ -1306,7 +1392,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1306 | return false; | 1392 | return false; |
1307 | 1393 | ||
1308 | uuids = m_PrimObjects[localID]; | 1394 | uuids = m_PrimObjects[localID]; |
1309 | } | 1395 | |
1310 | 1396 | ||
1311 | foreach (UUID itemID in uuids) | 1397 | foreach (UUID itemID in uuids) |
1312 | { | 1398 | { |
@@ -1324,6 +1410,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1324 | result = true; | 1410 | result = true; |
1325 | } | 1411 | } |
1326 | } | 1412 | } |
1413 | } | ||
1327 | 1414 | ||
1328 | return result; | 1415 | return result; |
1329 | } | 1416 | } |
@@ -1425,12 +1512,14 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1425 | private IScriptInstance GetInstance(UUID itemID) | 1512 | private IScriptInstance GetInstance(UUID itemID) |
1426 | { | 1513 | { |
1427 | IScriptInstance instance; | 1514 | IScriptInstance instance; |
1428 | lock (m_Scripts) | 1515 | lockScriptsForRead(true); |
1516 | if (!m_Scripts.ContainsKey(itemID)) | ||
1429 | { | 1517 | { |
1430 | if (!m_Scripts.ContainsKey(itemID)) | 1518 | lockScriptsForRead(false); |
1431 | return null; | 1519 | return null; |
1432 | instance = m_Scripts[itemID]; | ||
1433 | } | 1520 | } |
1521 | instance = m_Scripts[itemID]; | ||
1522 | lockScriptsForRead(false); | ||
1434 | return instance; | 1523 | return instance; |
1435 | } | 1524 | } |
1436 | 1525 | ||
@@ -1454,6 +1543,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1454 | return false; | 1543 | return false; |
1455 | } | 1544 | } |
1456 | 1545 | ||
1546 | [DebuggerNonUserCode] | ||
1457 | public void ApiResetScript(UUID itemID) | 1547 | public void ApiResetScript(UUID itemID) |
1458 | { | 1548 | { |
1459 | IScriptInstance instance = GetInstance(itemID); | 1549 | IScriptInstance instance = GetInstance(itemID); |
@@ -1505,6 +1595,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1505 | return UUID.Zero; | 1595 | return UUID.Zero; |
1506 | } | 1596 | } |
1507 | 1597 | ||
1598 | [DebuggerNonUserCode] | ||
1508 | public void SetState(UUID itemID, string newState) | 1599 | public void SetState(UUID itemID, string newState) |
1509 | { | 1600 | { |
1510 | IScriptInstance instance = GetInstance(itemID); | 1601 | IScriptInstance instance = GetInstance(itemID); |
@@ -1527,11 +1618,10 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1527 | 1618 | ||
1528 | List<IScriptInstance> instances = new List<IScriptInstance>(); | 1619 | List<IScriptInstance> instances = new List<IScriptInstance>(); |
1529 | 1620 | ||
1530 | lock (m_Scripts) | 1621 | lockScriptsForRead(true); |
1531 | { | 1622 | foreach (IScriptInstance instance in m_Scripts.Values) |
1532 | foreach (IScriptInstance instance in m_Scripts.Values) | ||
1533 | instances.Add(instance); | 1623 | instances.Add(instance); |
1534 | } | 1624 | lockScriptsForRead(false); |
1535 | 1625 | ||
1536 | foreach (IScriptInstance i in instances) | 1626 | foreach (IScriptInstance i in instances) |
1537 | { | 1627 | { |
@@ -1969,5 +2059,17 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1969 | // else | 2059 | // else |
1970 | // m_log.DebugFormat("[XEngine]: Could not find script with ID {0} to resume", itemID); | 2060 | // m_log.DebugFormat("[XEngine]: Could not find script with ID {0} to resume", itemID); |
1971 | } | 2061 | } |
2062 | |||
2063 | public bool HasScript(UUID itemID, out bool running) | ||
2064 | { | ||
2065 | running = true; | ||
2066 | |||
2067 | IScriptInstance instance = GetInstance(itemID); | ||
2068 | if (instance == null) | ||
2069 | return false; | ||
2070 | |||
2071 | running = instance.Running; | ||
2072 | return true; | ||
2073 | } | ||
1972 | } | 2074 | } |
1973 | } \ No newline at end of file | 2075 | } |