diff options
Diffstat (limited to '')
-rw-r--r-- | OpenSim/Region/ScriptEngine/XEngine/XEngine.cs | 362 |
1 files changed, 232 insertions, 130 deletions
diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs index a9b6e67..eeb125e 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,95 +1063,99 @@ 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 | 1077 | ||
1019 | Evidence baseEvidence = AppDomain.CurrentDomain.Evidence; | 1078 | if (!m_AppDomains.ContainsKey(appDomain)) |
1020 | Evidence evidence = new Evidence(baseEvidence); | 1079 | { |
1080 | try | ||
1081 | { | ||
1082 | AppDomainSetup appSetup = new AppDomainSetup(); | ||
1083 | appSetup.PrivateBinPath = Path.Combine( | ||
1084 | m_ScriptEnginesPath, | ||
1085 | m_Scene.RegionInfo.RegionID.ToString()); | ||
1021 | 1086 | ||
1022 | AppDomain sandbox; | 1087 | Evidence baseEvidence = AppDomain.CurrentDomain.Evidence; |
1023 | if (m_AppDomainLoading) | 1088 | Evidence evidence = new Evidence(baseEvidence); |
1024 | { | ||
1025 | sandbox = AppDomain.CreateDomain( | ||
1026 | m_Scene.RegionInfo.RegionID.ToString(), | ||
1027 | evidence, appSetup); | ||
1028 | sandbox.AssemblyResolve += | ||
1029 | new ResolveEventHandler( | ||
1030 | AssemblyResolver.OnAssemblyResolve); | ||
1031 | } | ||
1032 | else | ||
1033 | { | ||
1034 | sandbox = AppDomain.CurrentDomain; | ||
1035 | } | ||
1036 | |||
1037 | //PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel(); | ||
1038 | //AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition(); | ||
1039 | //PermissionSet sandboxPermissionSet = sandboxPolicy.GetNamedPermissionSet("Internet"); | ||
1040 | //PolicyStatement sandboxPolicyStatement = new PolicyStatement(sandboxPermissionSet); | ||
1041 | //CodeGroup sandboxCodeGroup = new UnionCodeGroup(sandboxMembershipCondition, sandboxPolicyStatement); | ||
1042 | //sandboxPolicy.RootCodeGroup = sandboxCodeGroup; | ||
1043 | //sandbox.SetAppDomainPolicy(sandboxPolicy); | ||
1044 | |||
1045 | m_AppDomains[appDomain] = sandbox; | ||
1046 | 1089 | ||
1047 | m_DomainScripts[appDomain] = new List<UUID>(); | 1090 | AppDomain sandbox; |
1091 | if (m_AppDomainLoading) | ||
1092 | { | ||
1093 | sandbox = AppDomain.CreateDomain( | ||
1094 | m_Scene.RegionInfo.RegionID.ToString(), | ||
1095 | evidence, appSetup); | ||
1096 | m_AppDomains[appDomain].AssemblyResolve += | ||
1097 | new ResolveEventHandler( | ||
1098 | AssemblyResolver.OnAssemblyResolve); | ||
1048 | } | 1099 | } |
1049 | catch (Exception e) | 1100 | else |
1050 | { | 1101 | { |
1051 | m_log.ErrorFormat("[XEngine] Exception creating app domain:\n {0}", e.ToString()); | 1102 | sandbox = AppDomain.CurrentDomain; |
1052 | m_ScriptErrorMessage += "Exception creating app domain:\n"; | ||
1053 | m_ScriptFailCount++; | ||
1054 | lock (m_AddingAssemblies) | ||
1055 | { | ||
1056 | m_AddingAssemblies[assembly]--; | ||
1057 | } | ||
1058 | return false; | ||
1059 | } | 1103 | } |
1060 | } | ||
1061 | m_DomainScripts[appDomain].Add(itemID); | ||
1062 | |||
1063 | instance = new ScriptInstance(this, part, | ||
1064 | itemID, assetID, assembly, | ||
1065 | m_AppDomains[appDomain], | ||
1066 | part.ParentGroup.RootPart.Name, | ||
1067 | item.Name, startParam, postOnRez, | ||
1068 | stateSource, m_MaxScriptQueue); | ||
1069 | |||
1070 | m_log.DebugFormat( | ||
1071 | "[XEngine] Loaded script {0}.{1}, item UUID {2}, prim UUID {3} @ {4}.{5}", | ||
1072 | part.ParentGroup.RootPart.Name, item.Name, itemID, part.UUID, | ||
1073 | part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName); | ||
1074 | 1104 | ||
1075 | if (presence != null) | 1105 | //PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel(); |
1106 | //AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition(); | ||
1107 | //PermissionSet sandboxPermissionSet = sandboxPolicy.GetNamedPermissionSet("Internet"); | ||
1108 | //PolicyStatement sandboxPolicyStatement = new PolicyStatement(sandboxPermissionSet); | ||
1109 | //CodeGroup sandboxCodeGroup = new UnionCodeGroup(sandboxMembershipCondition, sandboxPolicyStatement); | ||
1110 | //sandboxPolicy.RootCodeGroup = sandboxCodeGroup; | ||
1111 | //sandbox.SetAppDomainPolicy(sandboxPolicy); | ||
1112 | |||
1113 | m_AppDomains[appDomain] = sandbox; | ||
1114 | |||
1115 | m_DomainScripts[appDomain] = new List<UUID>(); | ||
1116 | } | ||
1117 | catch (Exception e) | ||
1076 | { | 1118 | { |
1077 | ShowScriptSaveResponse(item.OwnerID, | 1119 | m_log.ErrorFormat("[XEngine] Exception creating app domain:\n {0}", e.ToString()); |
1078 | assetID, "Compile successful", true); | 1120 | m_ScriptErrorMessage += "Exception creating app domain:\n"; |
1121 | m_ScriptFailCount++; | ||
1122 | lock (m_AddingAssemblies) | ||
1123 | { | ||
1124 | m_AddingAssemblies[assembly]--; | ||
1125 | } | ||
1126 | return false; | ||
1079 | } | 1127 | } |
1128 | } | ||
1129 | m_DomainScripts[appDomain].Add(itemID); | ||
1130 | |||
1131 | instance = new ScriptInstance(this, part, | ||
1132 | itemID, assetID, assembly, | ||
1133 | m_AppDomains[appDomain], | ||
1134 | part.ParentGroup.RootPart.Name, | ||
1135 | item.Name, startParam, postOnRez, | ||
1136 | stateSource, m_MaxScriptQueue); | ||
1137 | |||
1138 | m_log.DebugFormat( | ||
1139 | "[XEngine] Loaded script {0}.{1}, script UUID {2}, prim UUID {3} @ {4}.{5}", | ||
1140 | part.ParentGroup.RootPart.Name, item.Name, assetID, part.UUID, | ||
1141 | part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName); | ||
1080 | 1142 | ||
1081 | instance.AppDomain = appDomain; | 1143 | if (presence != null) |
1082 | instance.LineMap = linemap; | 1144 | { |
1083 | 1145 | ShowScriptSaveResponse(item.OwnerID, | |
1084 | m_Scripts[itemID] = instance; | 1146 | assetID, "Compile successful", true); |
1085 | } | 1147 | } |
1086 | } | ||
1087 | 1148 | ||
1149 | instance.AppDomain = appDomain; | ||
1150 | instance.LineMap = linemap; | ||
1151 | lockScriptsForWrite(true); | ||
1152 | m_Scripts[itemID] = instance; | ||
1153 | lockScriptsForWrite(false); | ||
1154 | } | ||
1155 | else | ||
1156 | { | ||
1157 | lockScriptsForRead(false); | ||
1158 | } | ||
1088 | lock (m_PrimObjects) | 1159 | lock (m_PrimObjects) |
1089 | { | 1160 | { |
1090 | if (!m_PrimObjects.ContainsKey(localID)) | 1161 | if (!m_PrimObjects.ContainsKey(localID)) |
@@ -1102,9 +1173,9 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1102 | m_AddingAssemblies[assembly]--; | 1173 | m_AddingAssemblies[assembly]--; |
1103 | } | 1174 | } |
1104 | 1175 | ||
1105 | if (instance != null) | 1176 | if (instance!=null) |
1106 | instance.Init(); | 1177 | instance.Init(); |
1107 | 1178 | ||
1108 | return true; | 1179 | return true; |
1109 | } | 1180 | } |
1110 | 1181 | ||
@@ -1117,18 +1188,28 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1117 | m_CompileDict.Remove(itemID); | 1188 | m_CompileDict.Remove(itemID); |
1118 | } | 1189 | } |
1119 | 1190 | ||
1120 | IScriptInstance instance = null; | 1191 | lockScriptsForRead(true); |
1121 | 1192 | // Do we even have it? | |
1122 | lock (m_Scripts) | 1193 | if (!m_Scripts.ContainsKey(itemID)) |
1123 | { | 1194 | { |
1124 | // Do we even have it? | 1195 | // Do we even have it? |
1125 | if (!m_Scripts.ContainsKey(itemID)) | 1196 | if (!m_Scripts.ContainsKey(itemID)) |
1126 | return; | 1197 | return; |
1127 | 1198 | ||
1128 | instance = m_Scripts[itemID]; | 1199 | lockScriptsForRead(false); |
1200 | lockScriptsForWrite(true); | ||
1129 | m_Scripts.Remove(itemID); | 1201 | m_Scripts.Remove(itemID); |
1202 | lockScriptsForWrite(false); | ||
1203 | |||
1204 | return; | ||
1130 | } | 1205 | } |
1206 | |||
1131 | 1207 | ||
1208 | IScriptInstance instance=m_Scripts[itemID]; | ||
1209 | lockScriptsForRead(false); | ||
1210 | lockScriptsForWrite(true); | ||
1211 | m_Scripts.Remove(itemID); | ||
1212 | lockScriptsForWrite(false); | ||
1132 | instance.ClearQueue(); | 1213 | instance.ClearQueue(); |
1133 | 1214 | ||
1134 | // Give the script some time to finish processing its last event. Simply aborting the script thread can | 1215 | // Give the script some time to finish processing its last event. Simply aborting the script thread can |
@@ -1167,8 +1248,13 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1167 | 1248 | ||
1168 | ObjectRemoved handlerObjectRemoved = OnObjectRemoved; | 1249 | ObjectRemoved handlerObjectRemoved = OnObjectRemoved; |
1169 | if (handlerObjectRemoved != null) | 1250 | if (handlerObjectRemoved != null) |
1170 | handlerObjectRemoved(instance.ObjectID); | 1251 | { |
1252 | SceneObjectPart part = m_Scene.GetSceneObjectPart(localID); | ||
1253 | handlerObjectRemoved(part.UUID); | ||
1254 | } | ||
1171 | 1255 | ||
1256 | CleanAssemblies(); | ||
1257 | |||
1172 | ScriptRemoved handlerScriptRemoved = OnScriptRemoved; | 1258 | ScriptRemoved handlerScriptRemoved = OnScriptRemoved; |
1173 | if (handlerScriptRemoved != null) | 1259 | if (handlerScriptRemoved != null) |
1174 | handlerScriptRemoved(itemID); | 1260 | handlerScriptRemoved(itemID); |
@@ -1310,7 +1396,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1310 | return false; | 1396 | return false; |
1311 | 1397 | ||
1312 | uuids = m_PrimObjects[localID]; | 1398 | uuids = m_PrimObjects[localID]; |
1313 | } | 1399 | |
1314 | 1400 | ||
1315 | foreach (UUID itemID in uuids) | 1401 | foreach (UUID itemID in uuids) |
1316 | { | 1402 | { |
@@ -1328,6 +1414,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1328 | result = true; | 1414 | result = true; |
1329 | } | 1415 | } |
1330 | } | 1416 | } |
1417 | } | ||
1331 | 1418 | ||
1332 | return result; | 1419 | return result; |
1333 | } | 1420 | } |
@@ -1429,12 +1516,14 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1429 | private IScriptInstance GetInstance(UUID itemID) | 1516 | private IScriptInstance GetInstance(UUID itemID) |
1430 | { | 1517 | { |
1431 | IScriptInstance instance; | 1518 | IScriptInstance instance; |
1432 | lock (m_Scripts) | 1519 | lockScriptsForRead(true); |
1520 | if (!m_Scripts.ContainsKey(itemID)) | ||
1433 | { | 1521 | { |
1434 | if (!m_Scripts.ContainsKey(itemID)) | 1522 | lockScriptsForRead(false); |
1435 | return null; | 1523 | return null; |
1436 | instance = m_Scripts[itemID]; | ||
1437 | } | 1524 | } |
1525 | instance = m_Scripts[itemID]; | ||
1526 | lockScriptsForRead(false); | ||
1438 | return instance; | 1527 | return instance; |
1439 | } | 1528 | } |
1440 | 1529 | ||
@@ -1458,6 +1547,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1458 | return false; | 1547 | return false; |
1459 | } | 1548 | } |
1460 | 1549 | ||
1550 | [DebuggerNonUserCode] | ||
1461 | public void ApiResetScript(UUID itemID) | 1551 | public void ApiResetScript(UUID itemID) |
1462 | { | 1552 | { |
1463 | IScriptInstance instance = GetInstance(itemID); | 1553 | IScriptInstance instance = GetInstance(itemID); |
@@ -1509,6 +1599,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1509 | return UUID.Zero; | 1599 | return UUID.Zero; |
1510 | } | 1600 | } |
1511 | 1601 | ||
1602 | [DebuggerNonUserCode] | ||
1512 | public void SetState(UUID itemID, string newState) | 1603 | public void SetState(UUID itemID, string newState) |
1513 | { | 1604 | { |
1514 | IScriptInstance instance = GetInstance(itemID); | 1605 | IScriptInstance instance = GetInstance(itemID); |
@@ -1531,11 +1622,10 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1531 | 1622 | ||
1532 | List<IScriptInstance> instances = new List<IScriptInstance>(); | 1623 | List<IScriptInstance> instances = new List<IScriptInstance>(); |
1533 | 1624 | ||
1534 | lock (m_Scripts) | 1625 | lockScriptsForRead(true); |
1535 | { | 1626 | foreach (IScriptInstance instance in m_Scripts.Values) |
1536 | foreach (IScriptInstance instance in m_Scripts.Values) | ||
1537 | instances.Add(instance); | 1627 | instances.Add(instance); |
1538 | } | 1628 | lockScriptsForRead(false); |
1539 | 1629 | ||
1540 | foreach (IScriptInstance i in instances) | 1630 | foreach (IScriptInstance i in instances) |
1541 | { | 1631 | { |
@@ -1989,5 +2079,17 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1989 | // else | 2079 | // else |
1990 | // m_log.DebugFormat("[XEngine]: Could not find script with ID {0} to resume", itemID); | 2080 | // m_log.DebugFormat("[XEngine]: Could not find script with ID {0} to resume", itemID); |
1991 | } | 2081 | } |
2082 | |||
2083 | public bool HasScript(UUID itemID, out bool running) | ||
2084 | { | ||
2085 | running = true; | ||
2086 | |||
2087 | IScriptInstance instance = GetInstance(itemID); | ||
2088 | if (instance == null) | ||
2089 | return false; | ||
2090 | |||
2091 | running = instance.Running; | ||
2092 | return true; | ||
2093 | } | ||
1992 | } | 2094 | } |
1993 | } | 2095 | } |