diff options
Diffstat (limited to 'OpenSim/Region/ScriptEngine/XEngine')
-rw-r--r-- | OpenSim/Region/ScriptEngine/XEngine/XEngine.cs | 362 |
1 files changed, 231 insertions, 131 deletions
diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs index ab41873..1d3ba6c 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"; } |
@@ -518,44 +586,37 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
518 | { | 586 | { |
519 | if (!m_Enabled) | 587 | if (!m_Enabled) |
520 | return; | 588 | return; |
521 | 589 | lockScriptsForRead(true); | |
522 | lock (m_Scripts) | 590 | foreach (IScriptInstance instance in m_Scripts.Values) |
523 | { | 591 | { |
524 | m_log.InfoFormat( | 592 | // Force a final state save |
525 | "[XEngine]: Shutting down {0} scripts in {1}", m_Scripts.Count, m_Scene.RegionInfo.RegionName); | 593 | // |
526 | 594 | if (m_Assemblies.ContainsKey(instance.AssetID)) | |
527 | foreach (IScriptInstance instance in m_Scripts.Values) | ||
528 | { | 595 | { |
529 | // Force a final state save | 596 | string assembly = m_Assemblies[instance.AssetID]; |
530 | // | 597 | instance.SaveState(assembly); |
531 | if (m_Assemblies.ContainsKey(instance.AssetID)) | 598 | } |
532 | { | ||
533 | string assembly = m_Assemblies[instance.AssetID]; | ||
534 | instance.SaveState(assembly); | ||
535 | } | ||
536 | 599 | ||
537 | // Clear the event queue and abort the instance thread | 600 | // Clear the event queue and abort the instance thread |
538 | // | 601 | // |
539 | instance.ClearQueue(); | 602 | instance.ClearQueue(); |
540 | instance.Stop(0); | 603 | instance.Stop(0); |
541 | 604 | ||
542 | // Release events, timer, etc | 605 | // Release events, timer, etc |
543 | // | 606 | // |
544 | instance.DestroyScriptInstance(); | 607 | instance.DestroyScriptInstance(); |
545 | 608 | ||
546 | // Unload scripts and app domains. | 609 | // Unload scripts and app domains |
547 | // Must be done explicitly because they have infinite | 610 | // Must be done explicitly because they have infinite |
548 | // lifetime. | 611 | // lifetime |
549 | // However, don't bother to do this if the simulator is shutting | 612 | // |
550 | // down since it takes a long time with many scripts. | 613 | if (!m_SimulatorShuttingDown) |
551 | if (!m_SimulatorShuttingDown) | 614 | { |
615 | m_DomainScripts[instance.AppDomain].Remove(instance.ItemID); | ||
616 | if (m_DomainScripts[instance.AppDomain].Count == 0) | ||
552 | { | 617 | { |
553 | m_DomainScripts[instance.AppDomain].Remove(instance.ItemID); | 618 | m_DomainScripts.Remove(instance.AppDomain); |
554 | if (m_DomainScripts[instance.AppDomain].Count == 0) | 619 | UnloadAppDomain(instance.AppDomain); |
555 | { | ||
556 | m_DomainScripts.Remove(instance.AppDomain); | ||
557 | UnloadAppDomain(instance.AppDomain); | ||
558 | } | ||
559 | } | 620 | } |
560 | } | 621 | } |
561 | 622 | ||
@@ -564,6 +625,14 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
564 | m_Assemblies.Clear(); | 625 | m_Assemblies.Clear(); |
565 | m_DomainScripts.Clear(); | 626 | m_DomainScripts.Clear(); |
566 | } | 627 | } |
628 | lockScriptsForRead(false); | ||
629 | lockScriptsForWrite(true); | ||
630 | m_Scripts.Clear(); | ||
631 | lockScriptsForWrite(false); | ||
632 | m_PrimObjects.Clear(); | ||
633 | m_Assemblies.Clear(); | ||
634 | m_DomainScripts.Clear(); | ||
635 | |||
567 | lock (m_ScriptEngines) | 636 | lock (m_ScriptEngines) |
568 | { | 637 | { |
569 | m_ScriptEngines.Remove(this); | 638 | m_ScriptEngines.Remove(this); |
@@ -628,22 +697,20 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
628 | 697 | ||
629 | List<IScriptInstance> instances = new List<IScriptInstance>(); | 698 | List<IScriptInstance> instances = new List<IScriptInstance>(); |
630 | 699 | ||
631 | lock (m_Scripts) | 700 | lockScriptsForRead(true); |
632 | { | 701 | foreach (IScriptInstance instance in m_Scripts.Values) |
633 | foreach (IScriptInstance instance in m_Scripts.Values) | ||
634 | instances.Add(instance); | 702 | instances.Add(instance); |
635 | } | 703 | lockScriptsForRead(false); |
636 | 704 | ||
637 | foreach (IScriptInstance i in instances) | 705 | foreach (IScriptInstance i in instances) |
638 | { | 706 | { |
639 | string assembly = String.Empty; | 707 | string assembly = String.Empty; |
640 | 708 | ||
641 | lock (m_Scripts) | 709 | |
642 | { | ||
643 | if (!m_Assemblies.ContainsKey(i.AssetID)) | 710 | if (!m_Assemblies.ContainsKey(i.AssetID)) |
644 | continue; | 711 | continue; |
645 | assembly = m_Assemblies[i.AssetID]; | 712 | assembly = m_Assemblies[i.AssetID]; |
646 | } | 713 | |
647 | 714 | ||
648 | i.SaveState(assembly); | 715 | i.SaveState(assembly); |
649 | } | 716 | } |
@@ -987,91 +1054,95 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
987 | } | 1054 | } |
988 | 1055 | ||
989 | ScriptInstance instance = null; | 1056 | ScriptInstance instance = null; |
990 | lock (m_Scripts) | 1057 | // Create the object record |
1058 | lockScriptsForRead(true); | ||
1059 | if ((!m_Scripts.ContainsKey(itemID)) || | ||
1060 | (m_Scripts[itemID].AssetID != assetID)) | ||
991 | { | 1061 | { |
992 | // Create the object record | 1062 | lockScriptsForRead(false); |
993 | if ((!m_Scripts.ContainsKey(itemID)) || | ||
994 | (m_Scripts[itemID].AssetID != assetID)) | ||
995 | { | ||
996 | UUID appDomain = assetID; | ||
997 | 1063 | ||
998 | if (part.ParentGroup.IsAttachment) | 1064 | UUID appDomain = assetID; |
999 | appDomain = part.ParentGroup.RootPart.UUID; | ||
1000 | 1065 | ||
1001 | if (!m_AppDomains.ContainsKey(appDomain)) | 1066 | if (part.ParentGroup.IsAttachment) |
1002 | { | 1067 | appDomain = part.ParentGroup.RootPart.UUID; |
1003 | try | ||
1004 | { | ||
1005 | AppDomainSetup appSetup = new AppDomainSetup(); | ||
1006 | appSetup.PrivateBinPath = Path.Combine( | ||
1007 | m_ScriptEnginesPath, | ||
1008 | m_Scene.RegionInfo.RegionID.ToString()); | ||
1009 | |||
1010 | Evidence baseEvidence = AppDomain.CurrentDomain.Evidence; | ||
1011 | Evidence evidence = new Evidence(baseEvidence); | ||
1012 | |||
1013 | AppDomain sandbox; | ||
1014 | if (m_AppDomainLoading) | ||
1015 | sandbox = AppDomain.CreateDomain( | ||
1016 | m_Scene.RegionInfo.RegionID.ToString(), | ||
1017 | evidence, appSetup); | ||
1018 | else | ||
1019 | sandbox = AppDomain.CurrentDomain; | ||
1020 | |||
1021 | //PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel(); | ||
1022 | //AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition(); | ||
1023 | //PermissionSet sandboxPermissionSet = sandboxPolicy.GetNamedPermissionSet("Internet"); | ||
1024 | //PolicyStatement sandboxPolicyStatement = new PolicyStatement(sandboxPermissionSet); | ||
1025 | //CodeGroup sandboxCodeGroup = new UnionCodeGroup(sandboxMembershipCondition, sandboxPolicyStatement); | ||
1026 | //sandboxPolicy.RootCodeGroup = sandboxCodeGroup; | ||
1027 | //sandbox.SetAppDomainPolicy(sandboxPolicy); | ||
1028 | |||
1029 | m_AppDomains[appDomain] = sandbox; | ||
1030 | 1068 | ||
1031 | m_AppDomains[appDomain].AssemblyResolve += | 1069 | if (!m_AppDomains.ContainsKey(appDomain)) |
1032 | new ResolveEventHandler( | 1070 | { |
1033 | AssemblyResolver.OnAssemblyResolve); | 1071 | try |
1034 | m_DomainScripts[appDomain] = new List<UUID>(); | 1072 | { |
1035 | } | 1073 | AppDomainSetup appSetup = new AppDomainSetup(); |
1036 | catch (Exception e) | 1074 | appSetup.PrivateBinPath = Path.Combine( |
1075 | m_ScriptEnginesPath, | ||
1076 | m_Scene.RegionInfo.RegionID.ToString()); | ||
1077 | |||
1078 | Evidence baseEvidence = AppDomain.CurrentDomain.Evidence; | ||
1079 | Evidence evidence = new Evidence(baseEvidence); | ||
1080 | |||
1081 | AppDomain sandbox; | ||
1082 | if (m_AppDomainLoading) | ||
1083 | sandbox = AppDomain.CreateDomain( | ||
1084 | m_Scene.RegionInfo.RegionID.ToString(), | ||
1085 | evidence, appSetup); | ||
1086 | else | ||
1087 | sandbox = AppDomain.CurrentDomain; | ||
1088 | |||
1089 | //PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel(); | ||
1090 | //AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition(); | ||
1091 | //PermissionSet sandboxPermissionSet = sandboxPolicy.GetNamedPermissionSet("Internet"); | ||
1092 | //PolicyStatement sandboxPolicyStatement = new PolicyStatement(sandboxPermissionSet); | ||
1093 | //CodeGroup sandboxCodeGroup = new UnionCodeGroup(sandboxMembershipCondition, sandboxPolicyStatement); | ||
1094 | //sandboxPolicy.RootCodeGroup = sandboxCodeGroup; | ||
1095 | //sandbox.SetAppDomainPolicy(sandboxPolicy); | ||
1096 | |||
1097 | m_AppDomains[appDomain] = sandbox; | ||
1098 | |||
1099 | m_AppDomains[appDomain].AssemblyResolve += | ||
1100 | new ResolveEventHandler( | ||
1101 | AssemblyResolver.OnAssemblyResolve); | ||
1102 | m_DomainScripts[appDomain] = new List<UUID>(); | ||
1103 | } | ||
1104 | catch (Exception e) | ||
1105 | { | ||
1106 | m_log.ErrorFormat("[XEngine] Exception creating app domain:\n {0}", e.ToString()); | ||
1107 | m_ScriptErrorMessage += "Exception creating app domain:\n"; | ||
1108 | m_ScriptFailCount++; | ||
1109 | lock (m_AddingAssemblies) | ||
1037 | { | 1110 | { |
1038 | m_log.ErrorFormat("[XEngine] Exception creating app domain:\n {0}", e.ToString()); | 1111 | m_AddingAssemblies[assembly]--; |
1039 | m_ScriptErrorMessage += "Exception creating app domain:\n"; | ||
1040 | m_ScriptFailCount++; | ||
1041 | lock (m_AddingAssemblies) | ||
1042 | { | ||
1043 | m_AddingAssemblies[assembly]--; | ||
1044 | } | ||
1045 | return false; | ||
1046 | } | 1112 | } |
1113 | return false; | ||
1047 | } | 1114 | } |
1048 | m_DomainScripts[appDomain].Add(itemID); | 1115 | } |
1049 | 1116 | m_DomainScripts[appDomain].Add(itemID); | |
1050 | instance = new ScriptInstance(this, part, | 1117 | |
1051 | itemID, assetID, assembly, | 1118 | instance = new ScriptInstance(this, part, |
1052 | m_AppDomains[appDomain], | 1119 | itemID, assetID, assembly, |
1053 | part.ParentGroup.RootPart.Name, | 1120 | m_AppDomains[appDomain], |
1054 | item.Name, startParam, postOnRez, | 1121 | part.ParentGroup.RootPart.Name, |
1055 | stateSource, m_MaxScriptQueue); | 1122 | item.Name, startParam, postOnRez, |
1056 | 1123 | stateSource, m_MaxScriptQueue); | |
1057 | m_log.DebugFormat( | 1124 | |
1058 | "[XEngine] Loaded script {0}.{1}, item UUID {2}, prim UUID {3} @ {4}.{5}", | 1125 | m_log.DebugFormat( |
1059 | part.ParentGroup.RootPart.Name, item.Name, itemID, part.UUID, | 1126 | "[XEngine] Loaded script {0}.{1}, script UUID {2}, prim UUID {3} @ {4}.{5}", |
1127 | part.ParentGroup.RootPart.Name, item.Name, assetID, part.UUID, | ||
1060 | part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName); | 1128 | part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName); |
1061 | 1129 | ||
1062 | if (presence != null) | 1130 | if (presence != null) |
1063 | { | 1131 | { |
1064 | ShowScriptSaveResponse(item.OwnerID, | 1132 | ShowScriptSaveResponse(item.OwnerID, |
1065 | assetID, "Compile successful", true); | 1133 | assetID, "Compile successful", true); |
1066 | } | ||
1067 | |||
1068 | instance.AppDomain = appDomain; | ||
1069 | instance.LineMap = linemap; | ||
1070 | |||
1071 | m_Scripts[itemID] = instance; | ||
1072 | } | 1134 | } |
1073 | } | ||
1074 | 1135 | ||
1136 | instance.AppDomain = appDomain; | ||
1137 | instance.LineMap = linemap; | ||
1138 | lockScriptsForWrite(true); | ||
1139 | m_Scripts[itemID] = instance; | ||
1140 | lockScriptsForWrite(false); | ||
1141 | } | ||
1142 | else | ||
1143 | { | ||
1144 | lockScriptsForRead(false); | ||
1145 | } | ||
1075 | lock (m_PrimObjects) | 1146 | lock (m_PrimObjects) |
1076 | { | 1147 | { |
1077 | if (!m_PrimObjects.ContainsKey(localID)) | 1148 | if (!m_PrimObjects.ContainsKey(localID)) |
@@ -1090,9 +1161,9 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1090 | m_AddingAssemblies[assembly]--; | 1161 | m_AddingAssemblies[assembly]--; |
1091 | } | 1162 | } |
1092 | 1163 | ||
1093 | if (instance != null) | 1164 | if (instance!=null) |
1094 | instance.Init(); | 1165 | instance.Init(); |
1095 | 1166 | ||
1096 | return true; | 1167 | return true; |
1097 | } | 1168 | } |
1098 | 1169 | ||
@@ -1105,20 +1176,31 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1105 | m_CompileDict.Remove(itemID); | 1176 | m_CompileDict.Remove(itemID); |
1106 | } | 1177 | } |
1107 | 1178 | ||
1108 | IScriptInstance instance = null; | 1179 | lockScriptsForRead(true); |
1109 | 1180 | // Do we even have it? | |
1110 | lock (m_Scripts) | 1181 | if (!m_Scripts.ContainsKey(itemID)) |
1111 | { | 1182 | { |
1112 | // Do we even have it? | 1183 | // Do we even have it? |
1113 | if (!m_Scripts.ContainsKey(itemID)) | 1184 | if (!m_Scripts.ContainsKey(itemID)) |
1114 | return; | 1185 | return; |
1115 | 1186 | ||
1116 | instance = m_Scripts[itemID]; | 1187 | lockScriptsForRead(false); |
1188 | lockScriptsForWrite(true); | ||
1117 | m_Scripts.Remove(itemID); | 1189 | m_Scripts.Remove(itemID); |
1190 | lockScriptsForWrite(false); | ||
1191 | |||
1192 | return; | ||
1118 | } | 1193 | } |
1194 | |||
1119 | 1195 | ||
1196 | IScriptInstance instance=m_Scripts[itemID]; | ||
1197 | lockScriptsForRead(false); | ||
1198 | lockScriptsForWrite(true); | ||
1199 | m_Scripts.Remove(itemID); | ||
1200 | lockScriptsForWrite(false); | ||
1120 | instance.ClearQueue(); | 1201 | instance.ClearQueue(); |
1121 | instance.Stop(0); | 1202 | instance.Stop(0); |
1203 | |||
1122 | // bool objectRemoved = false; | 1204 | // bool objectRemoved = false; |
1123 | 1205 | ||
1124 | lock (m_PrimObjects) | 1206 | lock (m_PrimObjects) |
@@ -1154,10 +1236,12 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1154 | ObjectRemoved handlerObjectRemoved = OnObjectRemoved; | 1236 | ObjectRemoved handlerObjectRemoved = OnObjectRemoved; |
1155 | if (handlerObjectRemoved != null) | 1237 | if (handlerObjectRemoved != null) |
1156 | { | 1238 | { |
1157 | SceneObjectPart part = m_Scene.GetSceneObjectPart(localID); | 1239 | SceneObjectPart part = m_Scene.GetSceneObjectPart(localID); |
1158 | handlerObjectRemoved(part.UUID); | 1240 | handlerObjectRemoved(part.UUID); |
1159 | } | 1241 | } |
1160 | 1242 | ||
1243 | CleanAssemblies(); | ||
1244 | |||
1161 | ScriptRemoved handlerScriptRemoved = OnScriptRemoved; | 1245 | ScriptRemoved handlerScriptRemoved = OnScriptRemoved; |
1162 | if (handlerScriptRemoved != null) | 1246 | if (handlerScriptRemoved != null) |
1163 | handlerScriptRemoved(itemID); | 1247 | handlerScriptRemoved(itemID); |
@@ -1299,7 +1383,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1299 | return false; | 1383 | return false; |
1300 | 1384 | ||
1301 | uuids = m_PrimObjects[localID]; | 1385 | uuids = m_PrimObjects[localID]; |
1302 | } | 1386 | |
1303 | 1387 | ||
1304 | foreach (UUID itemID in uuids) | 1388 | foreach (UUID itemID in uuids) |
1305 | { | 1389 | { |
@@ -1317,6 +1401,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1317 | result = true; | 1401 | result = true; |
1318 | } | 1402 | } |
1319 | } | 1403 | } |
1404 | } | ||
1320 | 1405 | ||
1321 | return result; | 1406 | return result; |
1322 | } | 1407 | } |
@@ -1418,12 +1503,14 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1418 | private IScriptInstance GetInstance(UUID itemID) | 1503 | private IScriptInstance GetInstance(UUID itemID) |
1419 | { | 1504 | { |
1420 | IScriptInstance instance; | 1505 | IScriptInstance instance; |
1421 | lock (m_Scripts) | 1506 | lockScriptsForRead(true); |
1507 | if (!m_Scripts.ContainsKey(itemID)) | ||
1422 | { | 1508 | { |
1423 | if (!m_Scripts.ContainsKey(itemID)) | 1509 | lockScriptsForRead(false); |
1424 | return null; | 1510 | return null; |
1425 | instance = m_Scripts[itemID]; | ||
1426 | } | 1511 | } |
1512 | instance = m_Scripts[itemID]; | ||
1513 | lockScriptsForRead(false); | ||
1427 | return instance; | 1514 | return instance; |
1428 | } | 1515 | } |
1429 | 1516 | ||
@@ -1447,6 +1534,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1447 | return false; | 1534 | return false; |
1448 | } | 1535 | } |
1449 | 1536 | ||
1537 | [DebuggerNonUserCode] | ||
1450 | public void ApiResetScript(UUID itemID) | 1538 | public void ApiResetScript(UUID itemID) |
1451 | { | 1539 | { |
1452 | IScriptInstance instance = GetInstance(itemID); | 1540 | IScriptInstance instance = GetInstance(itemID); |
@@ -1498,6 +1586,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1498 | return UUID.Zero; | 1586 | return UUID.Zero; |
1499 | } | 1587 | } |
1500 | 1588 | ||
1589 | [DebuggerNonUserCode] | ||
1501 | public void SetState(UUID itemID, string newState) | 1590 | public void SetState(UUID itemID, string newState) |
1502 | { | 1591 | { |
1503 | IScriptInstance instance = GetInstance(itemID); | 1592 | IScriptInstance instance = GetInstance(itemID); |
@@ -1520,11 +1609,10 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1520 | 1609 | ||
1521 | List<IScriptInstance> instances = new List<IScriptInstance>(); | 1610 | List<IScriptInstance> instances = new List<IScriptInstance>(); |
1522 | 1611 | ||
1523 | lock (m_Scripts) | 1612 | lockScriptsForRead(true); |
1524 | { | 1613 | foreach (IScriptInstance instance in m_Scripts.Values) |
1525 | foreach (IScriptInstance instance in m_Scripts.Values) | ||
1526 | instances.Add(instance); | 1614 | instances.Add(instance); |
1527 | } | 1615 | lockScriptsForRead(false); |
1528 | 1616 | ||
1529 | foreach (IScriptInstance i in instances) | 1617 | foreach (IScriptInstance i in instances) |
1530 | { | 1618 | { |
@@ -1909,5 +1997,17 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1909 | // else | 1997 | // else |
1910 | // m_log.DebugFormat("[XEngine]: Could not find script with ID {0} to resume", itemID); | 1998 | // m_log.DebugFormat("[XEngine]: Could not find script with ID {0} to resume", itemID); |
1911 | } | 1999 | } |
2000 | |||
2001 | public bool HasScript(UUID itemID, out bool running) | ||
2002 | { | ||
2003 | running = true; | ||
2004 | |||
2005 | IScriptInstance instance = GetInstance(itemID); | ||
2006 | if (instance == null) | ||
2007 | return false; | ||
2008 | |||
2009 | running = instance.Running; | ||
2010 | return true; | ||
2011 | } | ||
1912 | } | 2012 | } |
1913 | } \ No newline at end of file | 2013 | } |