diff options
Diffstat (limited to '')
-rw-r--r-- | OpenSim/Region/ScriptEngine/XEngine/XEngine.cs | 357 |
1 files changed, 222 insertions, 135 deletions
diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs index 2a0ec37..32d1fd3 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs | |||
@@ -30,6 +30,7 @@ using System.IO; | |||
30 | using System.Threading; | 30 | using System.Threading; |
31 | using System.Collections; | 31 | using System.Collections; |
32 | using System.Collections.Generic; | 32 | using System.Collections.Generic; |
33 | using System.Diagnostics; //for [DebuggerNonUserCode] | ||
33 | using System.Security; | 34 | using System.Security; |
34 | using System.Security.Policy; | 35 | using System.Security.Policy; |
35 | using System.Reflection; | 36 | using System.Reflection; |
@@ -102,6 +103,8 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
102 | private Dictionary<UUID, IScriptInstance> m_Scripts = | 103 | private Dictionary<UUID, IScriptInstance> m_Scripts = |
103 | new Dictionary<UUID, IScriptInstance>(); | 104 | new Dictionary<UUID, IScriptInstance>(); |
104 | 105 | ||
106 | private OpenMetaverse.ReaderWriterLockSlim m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim(); | ||
107 | |||
105 | // Maps the asset ID to the assembly | 108 | // Maps the asset ID to the assembly |
106 | 109 | ||
107 | private Dictionary<UUID, string> m_Assemblies = | 110 | private Dictionary<UUID, string> m_Assemblies = |
@@ -124,6 +127,71 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
124 | IWorkItemResult m_CurrentCompile = null; | 127 | IWorkItemResult m_CurrentCompile = null; |
125 | private Dictionary<UUID, int> m_CompileDict = new Dictionary<UUID, int>(); | 128 | private Dictionary<UUID, int> m_CompileDict = new Dictionary<UUID, int>(); |
126 | 129 | ||
130 | private void lockScriptsForRead(bool locked) | ||
131 | { | ||
132 | if (locked) | ||
133 | { | ||
134 | if (m_scriptsLock.RecursiveReadCount > 0) | ||
135 | { | ||
136 | 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."); | ||
137 | m_scriptsLock.ExitReadLock(); | ||
138 | } | ||
139 | if (m_scriptsLock.RecursiveWriteCount > 0) | ||
140 | { | ||
141 | m_log.Error("[XEngine.m_Scripts] Recursive write lock requested. This should not happen and means something needs to be fixed."); | ||
142 | m_scriptsLock.ExitWriteLock(); | ||
143 | } | ||
144 | |||
145 | while (!m_scriptsLock.TryEnterReadLock(60000)) | ||
146 | { | ||
147 | 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."); | ||
148 | if (m_scriptsLock.IsWriteLockHeld) | ||
149 | { | ||
150 | m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim(); | ||
151 | } | ||
152 | } | ||
153 | } | ||
154 | else | ||
155 | { | ||
156 | if (m_scriptsLock.RecursiveReadCount > 0) | ||
157 | { | ||
158 | m_scriptsLock.ExitReadLock(); | ||
159 | } | ||
160 | } | ||
161 | } | ||
162 | private void lockScriptsForWrite(bool locked) | ||
163 | { | ||
164 | if (locked) | ||
165 | { | ||
166 | if (m_scriptsLock.RecursiveReadCount > 0) | ||
167 | { | ||
168 | 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."); | ||
169 | m_scriptsLock.ExitReadLock(); | ||
170 | } | ||
171 | if (m_scriptsLock.RecursiveWriteCount > 0) | ||
172 | { | ||
173 | m_log.Error("[XEngine.m_Scripts] Recursive write lock requested. This should not happen and means something needs to be fixed."); | ||
174 | m_scriptsLock.ExitWriteLock(); | ||
175 | } | ||
176 | |||
177 | while (!m_scriptsLock.TryEnterWriteLock(60000)) | ||
178 | { | ||
179 | 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."); | ||
180 | if (m_scriptsLock.IsWriteLockHeld) | ||
181 | { | ||
182 | m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim(); | ||
183 | } | ||
184 | } | ||
185 | } | ||
186 | else | ||
187 | { | ||
188 | if (m_scriptsLock.RecursiveWriteCount > 0) | ||
189 | { | ||
190 | m_scriptsLock.ExitWriteLock(); | ||
191 | } | ||
192 | } | ||
193 | } | ||
194 | |||
127 | public string ScriptEngineName | 195 | public string ScriptEngineName |
128 | { | 196 | { |
129 | get { return "XEngine"; } | 197 | get { return "XEngine"; } |
@@ -271,47 +339,45 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
271 | { | 339 | { |
272 | if (!m_Enabled) | 340 | if (!m_Enabled) |
273 | return; | 341 | return; |
274 | 342 | lockScriptsForRead(true); | |
275 | lock (m_Scripts) | 343 | foreach (IScriptInstance instance in m_Scripts.Values) |
276 | { | 344 | { |
277 | m_log.InfoFormat( | 345 | // Force a final state save |
278 | "[XEngine]: Shutting down {0} scripts in {1}", m_Scripts.Count, m_Scene.RegionInfo.RegionName); | 346 | // |
279 | 347 | if (m_Assemblies.ContainsKey(instance.AssetID)) | |
280 | foreach (IScriptInstance instance in m_Scripts.Values) | ||
281 | { | 348 | { |
282 | // Force a final state save | 349 | string assembly = m_Assemblies[instance.AssetID]; |
283 | // | 350 | instance.SaveState(assembly); |
284 | if (m_Assemblies.ContainsKey(instance.AssetID)) | 351 | } |
285 | { | ||
286 | string assembly = m_Assemblies[instance.AssetID]; | ||
287 | instance.SaveState(assembly); | ||
288 | } | ||
289 | 352 | ||
290 | // Clear the event queue and abort the instance thread | 353 | // Clear the event queue and abort the instance thread |
291 | // | 354 | // |
292 | instance.ClearQueue(); | 355 | instance.ClearQueue(); |
293 | instance.Stop(0); | 356 | instance.Stop(0); |
294 | 357 | ||
295 | // Release events, timer, etc | 358 | // Release events, timer, etc |
296 | // | 359 | // |
297 | instance.DestroyScriptInstance(); | 360 | instance.DestroyScriptInstance(); |
298 | 361 | ||
299 | // Unload scripts and app domains | 362 | // Unload scripts and app domains |
300 | // Must be done explicitly because they have infinite | 363 | // Must be done explicitly because they have infinite |
301 | // lifetime | 364 | // lifetime |
302 | // | 365 | // |
303 | m_DomainScripts[instance.AppDomain].Remove(instance.ItemID); | 366 | m_DomainScripts[instance.AppDomain].Remove(instance.ItemID); |
304 | if (m_DomainScripts[instance.AppDomain].Count == 0) | 367 | if (m_DomainScripts[instance.AppDomain].Count == 0) |
305 | { | 368 | { |
306 | m_DomainScripts.Remove(instance.AppDomain); | 369 | m_DomainScripts.Remove(instance.AppDomain); |
307 | UnloadAppDomain(instance.AppDomain); | 370 | UnloadAppDomain(instance.AppDomain); |
308 | } | ||
309 | } | 371 | } |
310 | m_Scripts.Clear(); | ||
311 | m_PrimObjects.Clear(); | ||
312 | m_Assemblies.Clear(); | ||
313 | m_DomainScripts.Clear(); | ||
314 | } | 372 | } |
373 | lockScriptsForRead(false); | ||
374 | lockScriptsForWrite(true); | ||
375 | m_Scripts.Clear(); | ||
376 | lockScriptsForWrite(false); | ||
377 | m_PrimObjects.Clear(); | ||
378 | m_Assemblies.Clear(); | ||
379 | m_DomainScripts.Clear(); | ||
380 | |||
315 | lock (m_ScriptEngines) | 381 | lock (m_ScriptEngines) |
316 | { | 382 | { |
317 | m_ScriptEngines.Remove(this); | 383 | m_ScriptEngines.Remove(this); |
@@ -376,22 +442,20 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
376 | 442 | ||
377 | List<IScriptInstance> instances = new List<IScriptInstance>(); | 443 | List<IScriptInstance> instances = new List<IScriptInstance>(); |
378 | 444 | ||
379 | lock (m_Scripts) | 445 | lockScriptsForRead(true); |
380 | { | 446 | foreach (IScriptInstance instance in m_Scripts.Values) |
381 | foreach (IScriptInstance instance in m_Scripts.Values) | ||
382 | instances.Add(instance); | 447 | instances.Add(instance); |
383 | } | 448 | lockScriptsForRead(false); |
384 | 449 | ||
385 | foreach (IScriptInstance i in instances) | 450 | foreach (IScriptInstance i in instances) |
386 | { | 451 | { |
387 | string assembly = String.Empty; | 452 | string assembly = String.Empty; |
388 | 453 | ||
389 | lock (m_Scripts) | 454 | |
390 | { | ||
391 | if (!m_Assemblies.ContainsKey(i.AssetID)) | 455 | if (!m_Assemblies.ContainsKey(i.AssetID)) |
392 | continue; | 456 | continue; |
393 | assembly = m_Assemblies[i.AssetID]; | 457 | assembly = m_Assemblies[i.AssetID]; |
394 | } | 458 | |
395 | 459 | ||
396 | i.SaveState(assembly); | 460 | i.SaveState(assembly); |
397 | } | 461 | } |
@@ -725,92 +789,95 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
725 | } | 789 | } |
726 | 790 | ||
727 | ScriptInstance instance = null; | 791 | ScriptInstance instance = null; |
728 | lock (m_Scripts) | 792 | // Create the object record |
793 | lockScriptsForRead(true); | ||
794 | if ((!m_Scripts.ContainsKey(itemID)) || | ||
795 | (m_Scripts[itemID].AssetID != assetID)) | ||
729 | { | 796 | { |
730 | // Create the object record | 797 | lockScriptsForRead(false); |
731 | 798 | ||
732 | if ((!m_Scripts.ContainsKey(itemID)) || | 799 | UUID appDomain = assetID; |
733 | (m_Scripts[itemID].AssetID != assetID)) | ||
734 | { | ||
735 | UUID appDomain = assetID; | ||
736 | 800 | ||
737 | if (part.ParentGroup.IsAttachment) | 801 | if (part.ParentGroup.IsAttachment) |
738 | appDomain = part.ParentGroup.RootPart.UUID; | 802 | appDomain = part.ParentGroup.RootPart.UUID; |
739 | 803 | ||
740 | if (!m_AppDomains.ContainsKey(appDomain)) | 804 | if (!m_AppDomains.ContainsKey(appDomain)) |
805 | { | ||
806 | try | ||
741 | { | 807 | { |
742 | try | 808 | AppDomainSetup appSetup = new AppDomainSetup(); |
743 | { | 809 | appSetup.PrivateBinPath = Path.Combine( |
744 | AppDomainSetup appSetup = new AppDomainSetup(); | 810 | m_ScriptEnginesPath, |
745 | appSetup.PrivateBinPath = Path.Combine( | 811 | m_Scene.RegionInfo.RegionID.ToString()); |
746 | m_ScriptEnginesPath, | 812 | |
747 | m_Scene.RegionInfo.RegionID.ToString()); | 813 | Evidence baseEvidence = AppDomain.CurrentDomain.Evidence; |
748 | 814 | Evidence evidence = new Evidence(baseEvidence); | |
749 | Evidence baseEvidence = AppDomain.CurrentDomain.Evidence; | 815 | |
750 | Evidence evidence = new Evidence(baseEvidence); | 816 | AppDomain sandbox; |
751 | 817 | if (m_AppDomainLoading) | |
752 | AppDomain sandbox; | 818 | sandbox = AppDomain.CreateDomain( |
753 | if (m_AppDomainLoading) | 819 | m_Scene.RegionInfo.RegionID.ToString(), |
754 | sandbox = AppDomain.CreateDomain( | 820 | evidence, appSetup); |
755 | m_Scene.RegionInfo.RegionID.ToString(), | 821 | else |
756 | evidence, appSetup); | 822 | sandbox = AppDomain.CurrentDomain; |
757 | else | 823 | |
758 | sandbox = AppDomain.CurrentDomain; | 824 | //PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel(); |
759 | 825 | //AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition(); | |
760 | //PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel(); | 826 | //PermissionSet sandboxPermissionSet = sandboxPolicy.GetNamedPermissionSet("Internet"); |
761 | //AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition(); | 827 | //PolicyStatement sandboxPolicyStatement = new PolicyStatement(sandboxPermissionSet); |
762 | //PermissionSet sandboxPermissionSet = sandboxPolicy.GetNamedPermissionSet("Internet"); | 828 | //CodeGroup sandboxCodeGroup = new UnionCodeGroup(sandboxMembershipCondition, sandboxPolicyStatement); |
763 | //PolicyStatement sandboxPolicyStatement = new PolicyStatement(sandboxPermissionSet); | 829 | //sandboxPolicy.RootCodeGroup = sandboxCodeGroup; |
764 | //CodeGroup sandboxCodeGroup = new UnionCodeGroup(sandboxMembershipCondition, sandboxPolicyStatement); | 830 | //sandbox.SetAppDomainPolicy(sandboxPolicy); |
765 | //sandboxPolicy.RootCodeGroup = sandboxCodeGroup; | 831 | |
766 | //sandbox.SetAppDomainPolicy(sandboxPolicy); | 832 | m_AppDomains[appDomain] = sandbox; |
767 | 833 | ||
768 | m_AppDomains[appDomain] = sandbox; | 834 | m_AppDomains[appDomain].AssemblyResolve += |
769 | 835 | new ResolveEventHandler( | |
770 | m_AppDomains[appDomain].AssemblyResolve += | 836 | AssemblyResolver.OnAssemblyResolve); |
771 | new ResolveEventHandler( | 837 | m_DomainScripts[appDomain] = new List<UUID>(); |
772 | AssemblyResolver.OnAssemblyResolve); | 838 | } |
773 | m_DomainScripts[appDomain] = new List<UUID>(); | 839 | catch (Exception e) |
774 | } | 840 | { |
775 | catch (Exception e) | 841 | m_log.ErrorFormat("[XEngine] Exception creating app domain:\n {0}", e.ToString()); |
842 | m_ScriptErrorMessage += "Exception creating app domain:\n"; | ||
843 | m_ScriptFailCount++; | ||
844 | lock (m_AddingAssemblies) | ||
776 | { | 845 | { |
777 | m_log.ErrorFormat("[XEngine] Exception creating app domain:\n {0}", e.ToString()); | 846 | m_AddingAssemblies[assembly]--; |
778 | m_ScriptErrorMessage += "Exception creating app domain:\n"; | ||
779 | m_ScriptFailCount++; | ||
780 | lock (m_AddingAssemblies) | ||
781 | { | ||
782 | m_AddingAssemblies[assembly]--; | ||
783 | } | ||
784 | return false; | ||
785 | } | 847 | } |
848 | return false; | ||
786 | } | 849 | } |
787 | m_DomainScripts[appDomain].Add(itemID); | 850 | } |
788 | 851 | m_DomainScripts[appDomain].Add(itemID); | |
789 | instance = new ScriptInstance(this, part, | 852 | |
790 | itemID, assetID, assembly, | 853 | instance = new ScriptInstance(this, part, |
791 | m_AppDomains[appDomain], | 854 | itemID, assetID, assembly, |
792 | part.ParentGroup.RootPart.Name, | 855 | m_AppDomains[appDomain], |
793 | item.Name, startParam, postOnRez, | 856 | part.ParentGroup.RootPart.Name, |
794 | stateSource, m_MaxScriptQueue); | 857 | item.Name, startParam, postOnRez, |
795 | 858 | stateSource, m_MaxScriptQueue); | |
796 | m_log.DebugFormat( | 859 | |
860 | m_log.DebugFormat( | ||
797 | "[XEngine] Loaded script {0}.{1}, script UUID {2}, prim UUID {3} @ {4}.{5}", | 861 | "[XEngine] Loaded script {0}.{1}, script UUID {2}, prim UUID {3} @ {4}.{5}", |
798 | part.ParentGroup.RootPart.Name, item.Name, assetID, part.UUID, | 862 | part.ParentGroup.RootPart.Name, item.Name, assetID, part.UUID, |
799 | part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName); | 863 | part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName); |
800 | 864 | ||
801 | if (presence != null) | 865 | if (presence != null) |
802 | { | 866 | { |
803 | ShowScriptSaveResponse(item.OwnerID, | 867 | ShowScriptSaveResponse(item.OwnerID, |
804 | assetID, "Compile successful", true); | 868 | assetID, "Compile successful", true); |
805 | } | ||
806 | |||
807 | instance.AppDomain = appDomain; | ||
808 | instance.LineMap = linemap; | ||
809 | |||
810 | m_Scripts[itemID] = instance; | ||
811 | } | 869 | } |
812 | } | ||
813 | 870 | ||
871 | instance.AppDomain = appDomain; | ||
872 | instance.LineMap = linemap; | ||
873 | lockScriptsForWrite(true); | ||
874 | m_Scripts[itemID] = instance; | ||
875 | lockScriptsForWrite(false); | ||
876 | } | ||
877 | else | ||
878 | { | ||
879 | lockScriptsForRead(false); | ||
880 | } | ||
814 | lock (m_PrimObjects) | 881 | lock (m_PrimObjects) |
815 | { | 882 | { |
816 | if (!m_PrimObjects.ContainsKey(localID)) | 883 | if (!m_PrimObjects.ContainsKey(localID)) |
@@ -829,9 +896,9 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
829 | m_AddingAssemblies[assembly]--; | 896 | m_AddingAssemblies[assembly]--; |
830 | } | 897 | } |
831 | 898 | ||
832 | if (instance != null) | 899 | if (instance!=null) |
833 | instance.Init(); | 900 | instance.Init(); |
834 | 901 | ||
835 | return true; | 902 | return true; |
836 | } | 903 | } |
837 | 904 | ||
@@ -844,20 +911,23 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
844 | m_CompileDict.Remove(itemID); | 911 | m_CompileDict.Remove(itemID); |
845 | } | 912 | } |
846 | 913 | ||
847 | IScriptInstance instance = null; | 914 | lockScriptsForRead(true); |
848 | 915 | // Do we even have it? | |
849 | lock (m_Scripts) | 916 | if (!m_Scripts.ContainsKey(itemID)) |
850 | { | 917 | { |
851 | // Do we even have it? | 918 | lockScriptsForRead(false); |
852 | if (!m_Scripts.ContainsKey(itemID)) | 919 | return; |
853 | return; | ||
854 | |||
855 | instance=m_Scripts[itemID]; | ||
856 | m_Scripts.Remove(itemID); | ||
857 | } | 920 | } |
921 | |||
858 | 922 | ||
923 | IScriptInstance instance=m_Scripts[itemID]; | ||
924 | lockScriptsForRead(false); | ||
925 | lockScriptsForWrite(true); | ||
926 | m_Scripts.Remove(itemID); | ||
927 | lockScriptsForWrite(false); | ||
859 | instance.ClearQueue(); | 928 | instance.ClearQueue(); |
860 | instance.Stop(0); | 929 | instance.Stop(0); |
930 | |||
861 | // bool objectRemoved = false; | 931 | // bool objectRemoved = false; |
862 | 932 | ||
863 | lock (m_PrimObjects) | 933 | lock (m_PrimObjects) |
@@ -893,11 +963,12 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
893 | ObjectRemoved handlerObjectRemoved = OnObjectRemoved; | 963 | ObjectRemoved handlerObjectRemoved = OnObjectRemoved; |
894 | if (handlerObjectRemoved != null) | 964 | if (handlerObjectRemoved != null) |
895 | { | 965 | { |
896 | SceneObjectPart part = m_Scene.GetSceneObjectPart(localID); | 966 | SceneObjectPart part = m_Scene.GetSceneObjectPart(localID); |
897 | handlerObjectRemoved(part.UUID); | 967 | handlerObjectRemoved(part.UUID); |
898 | } | 968 | } |
899 | 969 | ||
900 | 970 | CleanAssemblies(); | |
971 | |||
901 | ScriptRemoved handlerScriptRemoved = OnScriptRemoved; | 972 | ScriptRemoved handlerScriptRemoved = OnScriptRemoved; |
902 | if (handlerScriptRemoved != null) | 973 | if (handlerScriptRemoved != null) |
903 | handlerScriptRemoved(itemID); | 974 | handlerScriptRemoved(itemID); |
@@ -1039,7 +1110,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1039 | return false; | 1110 | return false; |
1040 | 1111 | ||
1041 | uuids = m_PrimObjects[localID]; | 1112 | uuids = m_PrimObjects[localID]; |
1042 | } | 1113 | |
1043 | 1114 | ||
1044 | foreach (UUID itemID in uuids) | 1115 | foreach (UUID itemID in uuids) |
1045 | { | 1116 | { |
@@ -1057,6 +1128,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1057 | result = true; | 1128 | result = true; |
1058 | } | 1129 | } |
1059 | } | 1130 | } |
1131 | } | ||
1060 | 1132 | ||
1061 | return result; | 1133 | return result; |
1062 | } | 1134 | } |
@@ -1156,12 +1228,14 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1156 | private IScriptInstance GetInstance(UUID itemID) | 1228 | private IScriptInstance GetInstance(UUID itemID) |
1157 | { | 1229 | { |
1158 | IScriptInstance instance; | 1230 | IScriptInstance instance; |
1159 | lock (m_Scripts) | 1231 | lockScriptsForRead(true); |
1232 | if (!m_Scripts.ContainsKey(itemID)) | ||
1160 | { | 1233 | { |
1161 | if (!m_Scripts.ContainsKey(itemID)) | 1234 | lockScriptsForRead(false); |
1162 | return null; | 1235 | return null; |
1163 | instance = m_Scripts[itemID]; | ||
1164 | } | 1236 | } |
1237 | instance = m_Scripts[itemID]; | ||
1238 | lockScriptsForRead(false); | ||
1165 | return instance; | 1239 | return instance; |
1166 | } | 1240 | } |
1167 | 1241 | ||
@@ -1185,6 +1259,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1185 | return false; | 1259 | return false; |
1186 | } | 1260 | } |
1187 | 1261 | ||
1262 | [DebuggerNonUserCode] | ||
1188 | public void ApiResetScript(UUID itemID) | 1263 | public void ApiResetScript(UUID itemID) |
1189 | { | 1264 | { |
1190 | IScriptInstance instance = GetInstance(itemID); | 1265 | IScriptInstance instance = GetInstance(itemID); |
@@ -1236,6 +1311,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1236 | return UUID.Zero; | 1311 | return UUID.Zero; |
1237 | } | 1312 | } |
1238 | 1313 | ||
1314 | [DebuggerNonUserCode] | ||
1239 | public void SetState(UUID itemID, string newState) | 1315 | public void SetState(UUID itemID, string newState) |
1240 | { | 1316 | { |
1241 | IScriptInstance instance = GetInstance(itemID); | 1317 | IScriptInstance instance = GetInstance(itemID); |
@@ -1256,11 +1332,10 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1256 | { | 1332 | { |
1257 | List<IScriptInstance> instances = new List<IScriptInstance>(); | 1333 | List<IScriptInstance> instances = new List<IScriptInstance>(); |
1258 | 1334 | ||
1259 | lock (m_Scripts) | 1335 | lockScriptsForRead(true); |
1260 | { | 1336 | foreach (IScriptInstance instance in m_Scripts.Values) |
1261 | foreach (IScriptInstance instance in m_Scripts.Values) | ||
1262 | instances.Add(instance); | 1337 | instances.Add(instance); |
1263 | } | 1338 | lockScriptsForRead(false); |
1264 | 1339 | ||
1265 | foreach (IScriptInstance i in instances) | 1340 | foreach (IScriptInstance i in instances) |
1266 | { | 1341 | { |
@@ -1641,5 +1716,17 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1641 | 1716 | ||
1642 | instance.Resume(); | 1717 | instance.Resume(); |
1643 | } | 1718 | } |
1719 | |||
1720 | public bool HasScript(UUID itemID, out bool running) | ||
1721 | { | ||
1722 | running = true; | ||
1723 | |||
1724 | IScriptInstance instance = GetInstance(itemID); | ||
1725 | if (instance == null) | ||
1726 | return false; | ||
1727 | |||
1728 | running = instance.Running; | ||
1729 | return true; | ||
1730 | } | ||
1644 | } | 1731 | } |
1645 | } | 1732 | } |