diff options
Diffstat (limited to 'OpenSim/Region/ScriptEngine/XEngine/XEngine.cs')
-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 9f8ee1c..572ca07 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; |
@@ -103,6 +104,8 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
103 | private Dictionary<UUID, IScriptInstance> m_Scripts = | 104 | private Dictionary<UUID, IScriptInstance> m_Scripts = |
104 | new Dictionary<UUID, IScriptInstance>(); | 105 | new Dictionary<UUID, IScriptInstance>(); |
105 | 106 | ||
107 | private OpenMetaverse.ReaderWriterLockSlim m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim(); | ||
108 | |||
106 | // Maps the asset ID to the assembly | 109 | // Maps the asset ID to the assembly |
107 | 110 | ||
108 | private Dictionary<UUID, string> m_Assemblies = | 111 | private Dictionary<UUID, string> m_Assemblies = |
@@ -125,6 +128,71 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
125 | IWorkItemResult m_CurrentCompile = null; | 128 | IWorkItemResult m_CurrentCompile = null; |
126 | private Dictionary<UUID, int> m_CompileDict = new Dictionary<UUID, int>(); | 129 | private Dictionary<UUID, int> m_CompileDict = new Dictionary<UUID, int>(); |
127 | 130 | ||
131 | private void lockScriptsForRead(bool locked) | ||
132 | { | ||
133 | if (locked) | ||
134 | { | ||
135 | if (m_scriptsLock.RecursiveReadCount > 0) | ||
136 | { | ||
137 | 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."); | ||
138 | m_scriptsLock.ExitReadLock(); | ||
139 | } | ||
140 | if (m_scriptsLock.RecursiveWriteCount > 0) | ||
141 | { | ||
142 | m_log.Error("[XEngine.m_Scripts] Recursive write lock requested. This should not happen and means something needs to be fixed."); | ||
143 | m_scriptsLock.ExitWriteLock(); | ||
144 | } | ||
145 | |||
146 | while (!m_scriptsLock.TryEnterReadLock(60000)) | ||
147 | { | ||
148 | 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."); | ||
149 | if (m_scriptsLock.IsWriteLockHeld) | ||
150 | { | ||
151 | m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim(); | ||
152 | } | ||
153 | } | ||
154 | } | ||
155 | else | ||
156 | { | ||
157 | if (m_scriptsLock.RecursiveReadCount > 0) | ||
158 | { | ||
159 | m_scriptsLock.ExitReadLock(); | ||
160 | } | ||
161 | } | ||
162 | } | ||
163 | private void lockScriptsForWrite(bool locked) | ||
164 | { | ||
165 | if (locked) | ||
166 | { | ||
167 | if (m_scriptsLock.RecursiveReadCount > 0) | ||
168 | { | ||
169 | 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."); | ||
170 | m_scriptsLock.ExitReadLock(); | ||
171 | } | ||
172 | if (m_scriptsLock.RecursiveWriteCount > 0) | ||
173 | { | ||
174 | m_log.Error("[XEngine.m_Scripts] Recursive write lock requested. This should not happen and means something needs to be fixed."); | ||
175 | m_scriptsLock.ExitWriteLock(); | ||
176 | } | ||
177 | |||
178 | while (!m_scriptsLock.TryEnterWriteLock(60000)) | ||
179 | { | ||
180 | 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."); | ||
181 | if (m_scriptsLock.IsWriteLockHeld) | ||
182 | { | ||
183 | m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim(); | ||
184 | } | ||
185 | } | ||
186 | } | ||
187 | else | ||
188 | { | ||
189 | if (m_scriptsLock.RecursiveWriteCount > 0) | ||
190 | { | ||
191 | m_scriptsLock.ExitWriteLock(); | ||
192 | } | ||
193 | } | ||
194 | } | ||
195 | |||
128 | public string ScriptEngineName | 196 | public string ScriptEngineName |
129 | { | 197 | { |
130 | get { return "XEngine"; } | 198 | get { return "XEngine"; } |
@@ -299,47 +367,45 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
299 | { | 367 | { |
300 | if (!m_Enabled) | 368 | if (!m_Enabled) |
301 | return; | 369 | return; |
302 | 370 | lockScriptsForRead(true); | |
303 | lock (m_Scripts) | 371 | foreach (IScriptInstance instance in m_Scripts.Values) |
304 | { | 372 | { |
305 | m_log.InfoFormat( | 373 | // Force a final state save |
306 | "[XEngine]: Shutting down {0} scripts in {1}", m_Scripts.Count, m_Scene.RegionInfo.RegionName); | 374 | // |
307 | 375 | if (m_Assemblies.ContainsKey(instance.AssetID)) | |
308 | foreach (IScriptInstance instance in m_Scripts.Values) | ||
309 | { | 376 | { |
310 | // Force a final state save | 377 | string assembly = m_Assemblies[instance.AssetID]; |
311 | // | 378 | instance.SaveState(assembly); |
312 | if (m_Assemblies.ContainsKey(instance.AssetID)) | 379 | } |
313 | { | ||
314 | string assembly = m_Assemblies[instance.AssetID]; | ||
315 | instance.SaveState(assembly); | ||
316 | } | ||
317 | 380 | ||
318 | // Clear the event queue and abort the instance thread | 381 | // Clear the event queue and abort the instance thread |
319 | // | 382 | // |
320 | instance.ClearQueue(); | 383 | instance.ClearQueue(); |
321 | instance.Stop(0); | 384 | instance.Stop(0); |
322 | 385 | ||
323 | // Release events, timer, etc | 386 | // Release events, timer, etc |
324 | // | 387 | // |
325 | instance.DestroyScriptInstance(); | 388 | instance.DestroyScriptInstance(); |
326 | 389 | ||
327 | // Unload scripts and app domains | 390 | // Unload scripts and app domains |
328 | // Must be done explicitly because they have infinite | 391 | // Must be done explicitly because they have infinite |
329 | // lifetime | 392 | // lifetime |
330 | // | 393 | // |
331 | m_DomainScripts[instance.AppDomain].Remove(instance.ItemID); | 394 | m_DomainScripts[instance.AppDomain].Remove(instance.ItemID); |
332 | if (m_DomainScripts[instance.AppDomain].Count == 0) | 395 | if (m_DomainScripts[instance.AppDomain].Count == 0) |
333 | { | 396 | { |
334 | m_DomainScripts.Remove(instance.AppDomain); | 397 | m_DomainScripts.Remove(instance.AppDomain); |
335 | UnloadAppDomain(instance.AppDomain); | 398 | UnloadAppDomain(instance.AppDomain); |
336 | } | ||
337 | } | 399 | } |
338 | m_Scripts.Clear(); | ||
339 | m_PrimObjects.Clear(); | ||
340 | m_Assemblies.Clear(); | ||
341 | m_DomainScripts.Clear(); | ||
342 | } | 400 | } |
401 | lockScriptsForRead(false); | ||
402 | lockScriptsForWrite(true); | ||
403 | m_Scripts.Clear(); | ||
404 | lockScriptsForWrite(false); | ||
405 | m_PrimObjects.Clear(); | ||
406 | m_Assemblies.Clear(); | ||
407 | m_DomainScripts.Clear(); | ||
408 | |||
343 | lock (m_ScriptEngines) | 409 | lock (m_ScriptEngines) |
344 | { | 410 | { |
345 | m_ScriptEngines.Remove(this); | 411 | m_ScriptEngines.Remove(this); |
@@ -404,22 +470,20 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
404 | 470 | ||
405 | List<IScriptInstance> instances = new List<IScriptInstance>(); | 471 | List<IScriptInstance> instances = new List<IScriptInstance>(); |
406 | 472 | ||
407 | lock (m_Scripts) | 473 | lockScriptsForRead(true); |
408 | { | 474 | foreach (IScriptInstance instance in m_Scripts.Values) |
409 | foreach (IScriptInstance instance in m_Scripts.Values) | ||
410 | instances.Add(instance); | 475 | instances.Add(instance); |
411 | } | 476 | lockScriptsForRead(false); |
412 | 477 | ||
413 | foreach (IScriptInstance i in instances) | 478 | foreach (IScriptInstance i in instances) |
414 | { | 479 | { |
415 | string assembly = String.Empty; | 480 | string assembly = String.Empty; |
416 | 481 | ||
417 | lock (m_Scripts) | 482 | |
418 | { | ||
419 | if (!m_Assemblies.ContainsKey(i.AssetID)) | 483 | if (!m_Assemblies.ContainsKey(i.AssetID)) |
420 | continue; | 484 | continue; |
421 | assembly = m_Assemblies[i.AssetID]; | 485 | assembly = m_Assemblies[i.AssetID]; |
422 | } | 486 | |
423 | 487 | ||
424 | i.SaveState(assembly); | 488 | i.SaveState(assembly); |
425 | } | 489 | } |
@@ -753,92 +817,95 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
753 | } | 817 | } |
754 | 818 | ||
755 | ScriptInstance instance = null; | 819 | ScriptInstance instance = null; |
756 | lock (m_Scripts) | 820 | // Create the object record |
821 | lockScriptsForRead(true); | ||
822 | if ((!m_Scripts.ContainsKey(itemID)) || | ||
823 | (m_Scripts[itemID].AssetID != assetID)) | ||
757 | { | 824 | { |
758 | // Create the object record | 825 | lockScriptsForRead(false); |
759 | 826 | ||
760 | if ((!m_Scripts.ContainsKey(itemID)) || | 827 | UUID appDomain = assetID; |
761 | (m_Scripts[itemID].AssetID != assetID)) | ||
762 | { | ||
763 | UUID appDomain = assetID; | ||
764 | 828 | ||
765 | if (part.ParentGroup.IsAttachment) | 829 | if (part.ParentGroup.IsAttachment) |
766 | appDomain = part.ParentGroup.RootPart.UUID; | 830 | appDomain = part.ParentGroup.RootPart.UUID; |
767 | 831 | ||
768 | if (!m_AppDomains.ContainsKey(appDomain)) | 832 | if (!m_AppDomains.ContainsKey(appDomain)) |
833 | { | ||
834 | try | ||
769 | { | 835 | { |
770 | try | 836 | AppDomainSetup appSetup = new AppDomainSetup(); |
771 | { | 837 | appSetup.PrivateBinPath = Path.Combine( |
772 | AppDomainSetup appSetup = new AppDomainSetup(); | 838 | m_ScriptEnginesPath, |
773 | appSetup.PrivateBinPath = Path.Combine( | 839 | m_Scene.RegionInfo.RegionID.ToString()); |
774 | m_ScriptEnginesPath, | 840 | |
775 | m_Scene.RegionInfo.RegionID.ToString()); | 841 | Evidence baseEvidence = AppDomain.CurrentDomain.Evidence; |
776 | 842 | Evidence evidence = new Evidence(baseEvidence); | |
777 | Evidence baseEvidence = AppDomain.CurrentDomain.Evidence; | 843 | |
778 | Evidence evidence = new Evidence(baseEvidence); | 844 | AppDomain sandbox; |
779 | 845 | if (m_AppDomainLoading) | |
780 | AppDomain sandbox; | 846 | sandbox = AppDomain.CreateDomain( |
781 | if (m_AppDomainLoading) | 847 | m_Scene.RegionInfo.RegionID.ToString(), |
782 | sandbox = AppDomain.CreateDomain( | 848 | evidence, appSetup); |
783 | m_Scene.RegionInfo.RegionID.ToString(), | 849 | else |
784 | evidence, appSetup); | 850 | sandbox = AppDomain.CurrentDomain; |
785 | else | 851 | |
786 | sandbox = AppDomain.CurrentDomain; | 852 | //PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel(); |
787 | 853 | //AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition(); | |
788 | //PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel(); | 854 | //PermissionSet sandboxPermissionSet = sandboxPolicy.GetNamedPermissionSet("Internet"); |
789 | //AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition(); | 855 | //PolicyStatement sandboxPolicyStatement = new PolicyStatement(sandboxPermissionSet); |
790 | //PermissionSet sandboxPermissionSet = sandboxPolicy.GetNamedPermissionSet("Internet"); | 856 | //CodeGroup sandboxCodeGroup = new UnionCodeGroup(sandboxMembershipCondition, sandboxPolicyStatement); |
791 | //PolicyStatement sandboxPolicyStatement = new PolicyStatement(sandboxPermissionSet); | 857 | //sandboxPolicy.RootCodeGroup = sandboxCodeGroup; |
792 | //CodeGroup sandboxCodeGroup = new UnionCodeGroup(sandboxMembershipCondition, sandboxPolicyStatement); | 858 | //sandbox.SetAppDomainPolicy(sandboxPolicy); |
793 | //sandboxPolicy.RootCodeGroup = sandboxCodeGroup; | 859 | |
794 | //sandbox.SetAppDomainPolicy(sandboxPolicy); | 860 | m_AppDomains[appDomain] = sandbox; |
795 | 861 | ||
796 | m_AppDomains[appDomain] = sandbox; | 862 | m_AppDomains[appDomain].AssemblyResolve += |
797 | 863 | new ResolveEventHandler( | |
798 | m_AppDomains[appDomain].AssemblyResolve += | 864 | AssemblyResolver.OnAssemblyResolve); |
799 | new ResolveEventHandler( | 865 | m_DomainScripts[appDomain] = new List<UUID>(); |
800 | AssemblyResolver.OnAssemblyResolve); | 866 | } |
801 | m_DomainScripts[appDomain] = new List<UUID>(); | 867 | catch (Exception e) |
802 | } | 868 | { |
803 | catch (Exception e) | 869 | m_log.ErrorFormat("[XEngine] Exception creating app domain:\n {0}", e.ToString()); |
870 | m_ScriptErrorMessage += "Exception creating app domain:\n"; | ||
871 | m_ScriptFailCount++; | ||
872 | lock (m_AddingAssemblies) | ||
804 | { | 873 | { |
805 | m_log.ErrorFormat("[XEngine] Exception creating app domain:\n {0}", e.ToString()); | 874 | m_AddingAssemblies[assembly]--; |
806 | m_ScriptErrorMessage += "Exception creating app domain:\n"; | ||
807 | m_ScriptFailCount++; | ||
808 | lock (m_AddingAssemblies) | ||
809 | { | ||
810 | m_AddingAssemblies[assembly]--; | ||
811 | } | ||
812 | return false; | ||
813 | } | 875 | } |
876 | return false; | ||
814 | } | 877 | } |
815 | m_DomainScripts[appDomain].Add(itemID); | 878 | } |
816 | 879 | m_DomainScripts[appDomain].Add(itemID); | |
817 | instance = new ScriptInstance(this, part, | 880 | |
818 | itemID, assetID, assembly, | 881 | instance = new ScriptInstance(this, part, |
819 | m_AppDomains[appDomain], | 882 | itemID, assetID, assembly, |
820 | part.ParentGroup.RootPart.Name, | 883 | m_AppDomains[appDomain], |
821 | item.Name, startParam, postOnRez, | 884 | part.ParentGroup.RootPart.Name, |
822 | stateSource, m_MaxScriptQueue); | 885 | item.Name, startParam, postOnRez, |
823 | 886 | stateSource, m_MaxScriptQueue); | |
824 | m_log.DebugFormat( | 887 | |
888 | m_log.DebugFormat( | ||
825 | "[XEngine] Loaded script {0}.{1}, script UUID {2}, prim UUID {3} @ {4}.{5}", | 889 | "[XEngine] Loaded script {0}.{1}, script UUID {2}, prim UUID {3} @ {4}.{5}", |
826 | part.ParentGroup.RootPart.Name, item.Name, assetID, part.UUID, | 890 | part.ParentGroup.RootPart.Name, item.Name, assetID, part.UUID, |
827 | part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName); | 891 | part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName); |
828 | 892 | ||
829 | if (presence != null) | 893 | if (presence != null) |
830 | { | 894 | { |
831 | ShowScriptSaveResponse(item.OwnerID, | 895 | ShowScriptSaveResponse(item.OwnerID, |
832 | assetID, "Compile successful", true); | 896 | assetID, "Compile successful", true); |
833 | } | ||
834 | |||
835 | instance.AppDomain = appDomain; | ||
836 | instance.LineMap = linemap; | ||
837 | |||
838 | m_Scripts[itemID] = instance; | ||
839 | } | 897 | } |
840 | } | ||
841 | 898 | ||
899 | instance.AppDomain = appDomain; | ||
900 | instance.LineMap = linemap; | ||
901 | lockScriptsForWrite(true); | ||
902 | m_Scripts[itemID] = instance; | ||
903 | lockScriptsForWrite(false); | ||
904 | } | ||
905 | else | ||
906 | { | ||
907 | lockScriptsForRead(false); | ||
908 | } | ||
842 | lock (m_PrimObjects) | 909 | lock (m_PrimObjects) |
843 | { | 910 | { |
844 | if (!m_PrimObjects.ContainsKey(localID)) | 911 | if (!m_PrimObjects.ContainsKey(localID)) |
@@ -857,9 +924,9 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
857 | m_AddingAssemblies[assembly]--; | 924 | m_AddingAssemblies[assembly]--; |
858 | } | 925 | } |
859 | 926 | ||
860 | if (instance != null) | 927 | if (instance!=null) |
861 | instance.Init(); | 928 | instance.Init(); |
862 | 929 | ||
863 | return true; | 930 | return true; |
864 | } | 931 | } |
865 | 932 | ||
@@ -872,20 +939,23 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
872 | m_CompileDict.Remove(itemID); | 939 | m_CompileDict.Remove(itemID); |
873 | } | 940 | } |
874 | 941 | ||
875 | IScriptInstance instance = null; | 942 | lockScriptsForRead(true); |
876 | 943 | // Do we even have it? | |
877 | lock (m_Scripts) | 944 | if (!m_Scripts.ContainsKey(itemID)) |
878 | { | 945 | { |
879 | // Do we even have it? | 946 | lockScriptsForRead(false); |
880 | if (!m_Scripts.ContainsKey(itemID)) | 947 | return; |
881 | return; | ||
882 | |||
883 | instance=m_Scripts[itemID]; | ||
884 | m_Scripts.Remove(itemID); | ||
885 | } | 948 | } |
949 | |||
886 | 950 | ||
951 | IScriptInstance instance=m_Scripts[itemID]; | ||
952 | lockScriptsForRead(false); | ||
953 | lockScriptsForWrite(true); | ||
954 | m_Scripts.Remove(itemID); | ||
955 | lockScriptsForWrite(false); | ||
887 | instance.ClearQueue(); | 956 | instance.ClearQueue(); |
888 | instance.Stop(0); | 957 | instance.Stop(0); |
958 | |||
889 | // bool objectRemoved = false; | 959 | // bool objectRemoved = false; |
890 | 960 | ||
891 | lock (m_PrimObjects) | 961 | lock (m_PrimObjects) |
@@ -921,11 +991,12 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
921 | ObjectRemoved handlerObjectRemoved = OnObjectRemoved; | 991 | ObjectRemoved handlerObjectRemoved = OnObjectRemoved; |
922 | if (handlerObjectRemoved != null) | 992 | if (handlerObjectRemoved != null) |
923 | { | 993 | { |
924 | SceneObjectPart part = m_Scene.GetSceneObjectPart(localID); | 994 | SceneObjectPart part = m_Scene.GetSceneObjectPart(localID); |
925 | handlerObjectRemoved(part.UUID); | 995 | handlerObjectRemoved(part.UUID); |
926 | } | 996 | } |
927 | 997 | ||
928 | 998 | CleanAssemblies(); | |
999 | |||
929 | ScriptRemoved handlerScriptRemoved = OnScriptRemoved; | 1000 | ScriptRemoved handlerScriptRemoved = OnScriptRemoved; |
930 | if (handlerScriptRemoved != null) | 1001 | if (handlerScriptRemoved != null) |
931 | handlerScriptRemoved(itemID); | 1002 | handlerScriptRemoved(itemID); |
@@ -1067,7 +1138,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1067 | return false; | 1138 | return false; |
1068 | 1139 | ||
1069 | uuids = m_PrimObjects[localID]; | 1140 | uuids = m_PrimObjects[localID]; |
1070 | } | 1141 | |
1071 | 1142 | ||
1072 | foreach (UUID itemID in uuids) | 1143 | foreach (UUID itemID in uuids) |
1073 | { | 1144 | { |
@@ -1085,6 +1156,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1085 | result = true; | 1156 | result = true; |
1086 | } | 1157 | } |
1087 | } | 1158 | } |
1159 | } | ||
1088 | 1160 | ||
1089 | return result; | 1161 | return result; |
1090 | } | 1162 | } |
@@ -1184,12 +1256,14 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1184 | private IScriptInstance GetInstance(UUID itemID) | 1256 | private IScriptInstance GetInstance(UUID itemID) |
1185 | { | 1257 | { |
1186 | IScriptInstance instance; | 1258 | IScriptInstance instance; |
1187 | lock (m_Scripts) | 1259 | lockScriptsForRead(true); |
1260 | if (!m_Scripts.ContainsKey(itemID)) | ||
1188 | { | 1261 | { |
1189 | if (!m_Scripts.ContainsKey(itemID)) | 1262 | lockScriptsForRead(false); |
1190 | return null; | 1263 | return null; |
1191 | instance = m_Scripts[itemID]; | ||
1192 | } | 1264 | } |
1265 | instance = m_Scripts[itemID]; | ||
1266 | lockScriptsForRead(false); | ||
1193 | return instance; | 1267 | return instance; |
1194 | } | 1268 | } |
1195 | 1269 | ||
@@ -1213,6 +1287,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1213 | return false; | 1287 | return false; |
1214 | } | 1288 | } |
1215 | 1289 | ||
1290 | [DebuggerNonUserCode] | ||
1216 | public void ApiResetScript(UUID itemID) | 1291 | public void ApiResetScript(UUID itemID) |
1217 | { | 1292 | { |
1218 | IScriptInstance instance = GetInstance(itemID); | 1293 | IScriptInstance instance = GetInstance(itemID); |
@@ -1264,6 +1339,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1264 | return UUID.Zero; | 1339 | return UUID.Zero; |
1265 | } | 1340 | } |
1266 | 1341 | ||
1342 | [DebuggerNonUserCode] | ||
1267 | public void SetState(UUID itemID, string newState) | 1343 | public void SetState(UUID itemID, string newState) |
1268 | { | 1344 | { |
1269 | IScriptInstance instance = GetInstance(itemID); | 1345 | IScriptInstance instance = GetInstance(itemID); |
@@ -1284,11 +1360,10 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1284 | { | 1360 | { |
1285 | List<IScriptInstance> instances = new List<IScriptInstance>(); | 1361 | List<IScriptInstance> instances = new List<IScriptInstance>(); |
1286 | 1362 | ||
1287 | lock (m_Scripts) | 1363 | lockScriptsForRead(true); |
1288 | { | 1364 | foreach (IScriptInstance instance in m_Scripts.Values) |
1289 | foreach (IScriptInstance instance in m_Scripts.Values) | ||
1290 | instances.Add(instance); | 1365 | instances.Add(instance); |
1291 | } | 1366 | lockScriptsForRead(false); |
1292 | 1367 | ||
1293 | foreach (IScriptInstance i in instances) | 1368 | foreach (IScriptInstance i in instances) |
1294 | { | 1369 | { |
@@ -1669,5 +1744,17 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1669 | 1744 | ||
1670 | instance.Resume(); | 1745 | instance.Resume(); |
1671 | } | 1746 | } |
1747 | |||
1748 | public bool HasScript(UUID itemID, out bool running) | ||
1749 | { | ||
1750 | running = true; | ||
1751 | |||
1752 | IScriptInstance instance = GetInstance(itemID); | ||
1753 | if (instance == null) | ||
1754 | return false; | ||
1755 | |||
1756 | running = instance.Running; | ||
1757 | return true; | ||
1758 | } | ||
1672 | } | 1759 | } |
1673 | } | 1760 | } |