diff options
Diffstat (limited to 'OpenSim/Region/ScriptEngine/XEngine')
-rw-r--r-- | OpenSim/Region/ScriptEngine/XEngine/XEngine.cs | 361 |
1 files changed, 224 insertions, 137 deletions
diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs index bb08d90..696c216 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"; } |
@@ -365,47 +433,45 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
365 | { | 433 | { |
366 | if (!m_Enabled) | 434 | if (!m_Enabled) |
367 | return; | 435 | return; |
368 | 436 | lockScriptsForRead(true); | |
369 | lock (m_Scripts) | 437 | foreach (IScriptInstance instance in m_Scripts.Values) |
370 | { | 438 | { |
371 | m_log.InfoFormat( | 439 | // Force a final state save |
372 | "[XEngine]: Shutting down {0} scripts in {1}", m_Scripts.Count, m_Scene.RegionInfo.RegionName); | 440 | // |
373 | 441 | if (m_Assemblies.ContainsKey(instance.AssetID)) | |
374 | foreach (IScriptInstance instance in m_Scripts.Values) | ||
375 | { | 442 | { |
376 | // Force a final state save | 443 | string assembly = m_Assemblies[instance.AssetID]; |
377 | // | 444 | instance.SaveState(assembly); |
378 | if (m_Assemblies.ContainsKey(instance.AssetID)) | 445 | } |
379 | { | ||
380 | string assembly = m_Assemblies[instance.AssetID]; | ||
381 | instance.SaveState(assembly); | ||
382 | } | ||
383 | 446 | ||
384 | // Clear the event queue and abort the instance thread | 447 | // Clear the event queue and abort the instance thread |
385 | // | 448 | // |
386 | instance.ClearQueue(); | 449 | instance.ClearQueue(); |
387 | instance.Stop(0); | 450 | instance.Stop(0); |
388 | 451 | ||
389 | // Release events, timer, etc | 452 | // Release events, timer, etc |
390 | // | 453 | // |
391 | instance.DestroyScriptInstance(); | 454 | instance.DestroyScriptInstance(); |
392 | 455 | ||
393 | // Unload scripts and app domains | 456 | // Unload scripts and app domains |
394 | // Must be done explicitly because they have infinite | 457 | // Must be done explicitly because they have infinite |
395 | // lifetime | 458 | // lifetime |
396 | // | 459 | // |
397 | m_DomainScripts[instance.AppDomain].Remove(instance.ItemID); | 460 | m_DomainScripts[instance.AppDomain].Remove(instance.ItemID); |
398 | if (m_DomainScripts[instance.AppDomain].Count == 0) | 461 | if (m_DomainScripts[instance.AppDomain].Count == 0) |
399 | { | 462 | { |
400 | m_DomainScripts.Remove(instance.AppDomain); | 463 | m_DomainScripts.Remove(instance.AppDomain); |
401 | UnloadAppDomain(instance.AppDomain); | 464 | UnloadAppDomain(instance.AppDomain); |
402 | } | ||
403 | } | 465 | } |
404 | m_Scripts.Clear(); | ||
405 | m_PrimObjects.Clear(); | ||
406 | m_Assemblies.Clear(); | ||
407 | m_DomainScripts.Clear(); | ||
408 | } | 466 | } |
467 | lockScriptsForRead(false); | ||
468 | lockScriptsForWrite(true); | ||
469 | m_Scripts.Clear(); | ||
470 | lockScriptsForWrite(false); | ||
471 | m_PrimObjects.Clear(); | ||
472 | m_Assemblies.Clear(); | ||
473 | m_DomainScripts.Clear(); | ||
474 | |||
409 | lock (m_ScriptEngines) | 475 | lock (m_ScriptEngines) |
410 | { | 476 | { |
411 | m_ScriptEngines.Remove(this); | 477 | m_ScriptEngines.Remove(this); |
@@ -470,22 +536,20 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
470 | 536 | ||
471 | List<IScriptInstance> instances = new List<IScriptInstance>(); | 537 | List<IScriptInstance> instances = new List<IScriptInstance>(); |
472 | 538 | ||
473 | lock (m_Scripts) | 539 | lockScriptsForRead(true); |
474 | { | 540 | foreach (IScriptInstance instance in m_Scripts.Values) |
475 | foreach (IScriptInstance instance in m_Scripts.Values) | ||
476 | instances.Add(instance); | 541 | instances.Add(instance); |
477 | } | 542 | lockScriptsForRead(false); |
478 | 543 | ||
479 | foreach (IScriptInstance i in instances) | 544 | foreach (IScriptInstance i in instances) |
480 | { | 545 | { |
481 | string assembly = String.Empty; | 546 | string assembly = String.Empty; |
482 | 547 | ||
483 | lock (m_Scripts) | 548 | |
484 | { | ||
485 | if (!m_Assemblies.ContainsKey(i.AssetID)) | 549 | if (!m_Assemblies.ContainsKey(i.AssetID)) |
486 | continue; | 550 | continue; |
487 | assembly = m_Assemblies[i.AssetID]; | 551 | assembly = m_Assemblies[i.AssetID]; |
488 | } | 552 | |
489 | 553 | ||
490 | i.SaveState(assembly); | 554 | i.SaveState(assembly); |
491 | } | 555 | } |
@@ -819,92 +883,95 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
819 | } | 883 | } |
820 | 884 | ||
821 | ScriptInstance instance = null; | 885 | ScriptInstance instance = null; |
822 | lock (m_Scripts) | 886 | // Create the object record |
887 | lockScriptsForRead(true); | ||
888 | if ((!m_Scripts.ContainsKey(itemID)) || | ||
889 | (m_Scripts[itemID].AssetID != assetID)) | ||
823 | { | 890 | { |
824 | // Create the object record | 891 | lockScriptsForRead(false); |
825 | 892 | ||
826 | if ((!m_Scripts.ContainsKey(itemID)) || | 893 | UUID appDomain = assetID; |
827 | (m_Scripts[itemID].AssetID != assetID)) | ||
828 | { | ||
829 | UUID appDomain = assetID; | ||
830 | 894 | ||
831 | if (part.ParentGroup.IsAttachment) | 895 | if (part.ParentGroup.IsAttachment) |
832 | appDomain = part.ParentGroup.RootPart.UUID; | 896 | appDomain = part.ParentGroup.RootPart.UUID; |
833 | 897 | ||
834 | if (!m_AppDomains.ContainsKey(appDomain)) | 898 | if (!m_AppDomains.ContainsKey(appDomain)) |
899 | { | ||
900 | try | ||
835 | { | 901 | { |
836 | try | 902 | AppDomainSetup appSetup = new AppDomainSetup(); |
837 | { | 903 | appSetup.PrivateBinPath = Path.Combine( |
838 | AppDomainSetup appSetup = new AppDomainSetup(); | 904 | m_ScriptEnginesPath, |
839 | appSetup.PrivateBinPath = Path.Combine( | 905 | m_Scene.RegionInfo.RegionID.ToString()); |
840 | m_ScriptEnginesPath, | 906 | |
841 | m_Scene.RegionInfo.RegionID.ToString()); | 907 | Evidence baseEvidence = AppDomain.CurrentDomain.Evidence; |
842 | 908 | Evidence evidence = new Evidence(baseEvidence); | |
843 | Evidence baseEvidence = AppDomain.CurrentDomain.Evidence; | 909 | |
844 | Evidence evidence = new Evidence(baseEvidence); | 910 | AppDomain sandbox; |
845 | 911 | if (m_AppDomainLoading) | |
846 | AppDomain sandbox; | 912 | sandbox = AppDomain.CreateDomain( |
847 | if (m_AppDomainLoading) | 913 | m_Scene.RegionInfo.RegionID.ToString(), |
848 | sandbox = AppDomain.CreateDomain( | 914 | evidence, appSetup); |
849 | m_Scene.RegionInfo.RegionID.ToString(), | 915 | else |
850 | evidence, appSetup); | 916 | sandbox = AppDomain.CurrentDomain; |
851 | else | 917 | |
852 | sandbox = AppDomain.CurrentDomain; | 918 | //PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel(); |
853 | 919 | //AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition(); | |
854 | //PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel(); | 920 | //PermissionSet sandboxPermissionSet = sandboxPolicy.GetNamedPermissionSet("Internet"); |
855 | //AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition(); | 921 | //PolicyStatement sandboxPolicyStatement = new PolicyStatement(sandboxPermissionSet); |
856 | //PermissionSet sandboxPermissionSet = sandboxPolicy.GetNamedPermissionSet("Internet"); | 922 | //CodeGroup sandboxCodeGroup = new UnionCodeGroup(sandboxMembershipCondition, sandboxPolicyStatement); |
857 | //PolicyStatement sandboxPolicyStatement = new PolicyStatement(sandboxPermissionSet); | 923 | //sandboxPolicy.RootCodeGroup = sandboxCodeGroup; |
858 | //CodeGroup sandboxCodeGroup = new UnionCodeGroup(sandboxMembershipCondition, sandboxPolicyStatement); | 924 | //sandbox.SetAppDomainPolicy(sandboxPolicy); |
859 | //sandboxPolicy.RootCodeGroup = sandboxCodeGroup; | 925 | |
860 | //sandbox.SetAppDomainPolicy(sandboxPolicy); | 926 | m_AppDomains[appDomain] = sandbox; |
861 | 927 | ||
862 | m_AppDomains[appDomain] = sandbox; | 928 | m_AppDomains[appDomain].AssemblyResolve += |
863 | 929 | new ResolveEventHandler( | |
864 | m_AppDomains[appDomain].AssemblyResolve += | 930 | AssemblyResolver.OnAssemblyResolve); |
865 | new ResolveEventHandler( | 931 | m_DomainScripts[appDomain] = new List<UUID>(); |
866 | AssemblyResolver.OnAssemblyResolve); | 932 | } |
867 | m_DomainScripts[appDomain] = new List<UUID>(); | 933 | catch (Exception e) |
868 | } | 934 | { |
869 | catch (Exception e) | 935 | m_log.ErrorFormat("[XEngine] Exception creating app domain:\n {0}", e.ToString()); |
936 | m_ScriptErrorMessage += "Exception creating app domain:\n"; | ||
937 | m_ScriptFailCount++; | ||
938 | lock (m_AddingAssemblies) | ||
870 | { | 939 | { |
871 | m_log.ErrorFormat("[XEngine] Exception creating app domain:\n {0}", e.ToString()); | 940 | m_AddingAssemblies[assembly]--; |
872 | m_ScriptErrorMessage += "Exception creating app domain:\n"; | ||
873 | m_ScriptFailCount++; | ||
874 | lock (m_AddingAssemblies) | ||
875 | { | ||
876 | m_AddingAssemblies[assembly]--; | ||
877 | } | ||
878 | return false; | ||
879 | } | 941 | } |
942 | return false; | ||
880 | } | 943 | } |
881 | m_DomainScripts[appDomain].Add(itemID); | 944 | } |
882 | 945 | m_DomainScripts[appDomain].Add(itemID); | |
883 | instance = new ScriptInstance(this, part, | 946 | |
884 | itemID, assetID, assembly, | 947 | instance = new ScriptInstance(this, part, |
885 | m_AppDomains[appDomain], | 948 | itemID, assetID, assembly, |
886 | part.ParentGroup.RootPart.Name, | 949 | m_AppDomains[appDomain], |
887 | item.Name, startParam, postOnRez, | 950 | part.ParentGroup.RootPart.Name, |
888 | stateSource, m_MaxScriptQueue); | 951 | item.Name, startParam, postOnRez, |
889 | 952 | stateSource, m_MaxScriptQueue); | |
890 | m_log.DebugFormat( | 953 | |
891 | "[XEngine] Loaded script {0}.{1}, item UUID {2}, prim UUID {3} @ {4}.{5}", | 954 | m_log.DebugFormat( |
892 | part.ParentGroup.RootPart.Name, item.Name, itemID, part.UUID, | 955 | "[XEngine] Loaded script {0}.{1}, script UUID {2}, prim UUID {3} @ {4}.{5}", |
956 | part.ParentGroup.RootPart.Name, item.Name, assetID, part.UUID, | ||
893 | part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName); | 957 | part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName); |
894 | 958 | ||
895 | if (presence != null) | 959 | if (presence != null) |
896 | { | 960 | { |
897 | ShowScriptSaveResponse(item.OwnerID, | 961 | ShowScriptSaveResponse(item.OwnerID, |
898 | assetID, "Compile successful", true); | 962 | assetID, "Compile successful", true); |
899 | } | ||
900 | |||
901 | instance.AppDomain = appDomain; | ||
902 | instance.LineMap = linemap; | ||
903 | |||
904 | m_Scripts[itemID] = instance; | ||
905 | } | 963 | } |
906 | } | ||
907 | 964 | ||
965 | instance.AppDomain = appDomain; | ||
966 | instance.LineMap = linemap; | ||
967 | lockScriptsForWrite(true); | ||
968 | m_Scripts[itemID] = instance; | ||
969 | lockScriptsForWrite(false); | ||
970 | } | ||
971 | else | ||
972 | { | ||
973 | lockScriptsForRead(false); | ||
974 | } | ||
908 | lock (m_PrimObjects) | 975 | lock (m_PrimObjects) |
909 | { | 976 | { |
910 | if (!m_PrimObjects.ContainsKey(localID)) | 977 | if (!m_PrimObjects.ContainsKey(localID)) |
@@ -923,9 +990,9 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
923 | m_AddingAssemblies[assembly]--; | 990 | m_AddingAssemblies[assembly]--; |
924 | } | 991 | } |
925 | 992 | ||
926 | if (instance != null) | 993 | if (instance!=null) |
927 | instance.Init(); | 994 | instance.Init(); |
928 | 995 | ||
929 | return true; | 996 | return true; |
930 | } | 997 | } |
931 | 998 | ||
@@ -938,20 +1005,23 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
938 | m_CompileDict.Remove(itemID); | 1005 | m_CompileDict.Remove(itemID); |
939 | } | 1006 | } |
940 | 1007 | ||
941 | IScriptInstance instance = null; | 1008 | lockScriptsForRead(true); |
942 | 1009 | // Do we even have it? | |
943 | lock (m_Scripts) | 1010 | if (!m_Scripts.ContainsKey(itemID)) |
944 | { | 1011 | { |
945 | // Do we even have it? | 1012 | lockScriptsForRead(false); |
946 | if (!m_Scripts.ContainsKey(itemID)) | 1013 | return; |
947 | return; | ||
948 | |||
949 | instance=m_Scripts[itemID]; | ||
950 | m_Scripts.Remove(itemID); | ||
951 | } | 1014 | } |
1015 | |||
952 | 1016 | ||
1017 | IScriptInstance instance=m_Scripts[itemID]; | ||
1018 | lockScriptsForRead(false); | ||
1019 | lockScriptsForWrite(true); | ||
1020 | m_Scripts.Remove(itemID); | ||
1021 | lockScriptsForWrite(false); | ||
953 | instance.ClearQueue(); | 1022 | instance.ClearQueue(); |
954 | instance.Stop(0); | 1023 | instance.Stop(0); |
1024 | |||
955 | // bool objectRemoved = false; | 1025 | // bool objectRemoved = false; |
956 | 1026 | ||
957 | lock (m_PrimObjects) | 1027 | lock (m_PrimObjects) |
@@ -987,11 +1057,12 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
987 | ObjectRemoved handlerObjectRemoved = OnObjectRemoved; | 1057 | ObjectRemoved handlerObjectRemoved = OnObjectRemoved; |
988 | if (handlerObjectRemoved != null) | 1058 | if (handlerObjectRemoved != null) |
989 | { | 1059 | { |
990 | SceneObjectPart part = m_Scene.GetSceneObjectPart(localID); | 1060 | SceneObjectPart part = m_Scene.GetSceneObjectPart(localID); |
991 | handlerObjectRemoved(part.UUID); | 1061 | handlerObjectRemoved(part.UUID); |
992 | } | 1062 | } |
993 | 1063 | ||
994 | 1064 | CleanAssemblies(); | |
1065 | |||
995 | ScriptRemoved handlerScriptRemoved = OnScriptRemoved; | 1066 | ScriptRemoved handlerScriptRemoved = OnScriptRemoved; |
996 | if (handlerScriptRemoved != null) | 1067 | if (handlerScriptRemoved != null) |
997 | handlerScriptRemoved(itemID); | 1068 | handlerScriptRemoved(itemID); |
@@ -1133,7 +1204,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1133 | return false; | 1204 | return false; |
1134 | 1205 | ||
1135 | uuids = m_PrimObjects[localID]; | 1206 | uuids = m_PrimObjects[localID]; |
1136 | } | 1207 | |
1137 | 1208 | ||
1138 | foreach (UUID itemID in uuids) | 1209 | foreach (UUID itemID in uuids) |
1139 | { | 1210 | { |
@@ -1151,6 +1222,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1151 | result = true; | 1222 | result = true; |
1152 | } | 1223 | } |
1153 | } | 1224 | } |
1225 | } | ||
1154 | 1226 | ||
1155 | return result; | 1227 | return result; |
1156 | } | 1228 | } |
@@ -1250,12 +1322,14 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1250 | private IScriptInstance GetInstance(UUID itemID) | 1322 | private IScriptInstance GetInstance(UUID itemID) |
1251 | { | 1323 | { |
1252 | IScriptInstance instance; | 1324 | IScriptInstance instance; |
1253 | lock (m_Scripts) | 1325 | lockScriptsForRead(true); |
1326 | if (!m_Scripts.ContainsKey(itemID)) | ||
1254 | { | 1327 | { |
1255 | if (!m_Scripts.ContainsKey(itemID)) | 1328 | lockScriptsForRead(false); |
1256 | return null; | 1329 | return null; |
1257 | instance = m_Scripts[itemID]; | ||
1258 | } | 1330 | } |
1331 | instance = m_Scripts[itemID]; | ||
1332 | lockScriptsForRead(false); | ||
1259 | return instance; | 1333 | return instance; |
1260 | } | 1334 | } |
1261 | 1335 | ||
@@ -1279,6 +1353,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1279 | return false; | 1353 | return false; |
1280 | } | 1354 | } |
1281 | 1355 | ||
1356 | [DebuggerNonUserCode] | ||
1282 | public void ApiResetScript(UUID itemID) | 1357 | public void ApiResetScript(UUID itemID) |
1283 | { | 1358 | { |
1284 | IScriptInstance instance = GetInstance(itemID); | 1359 | IScriptInstance instance = GetInstance(itemID); |
@@ -1330,6 +1405,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1330 | return UUID.Zero; | 1405 | return UUID.Zero; |
1331 | } | 1406 | } |
1332 | 1407 | ||
1408 | [DebuggerNonUserCode] | ||
1333 | public void SetState(UUID itemID, string newState) | 1409 | public void SetState(UUID itemID, string newState) |
1334 | { | 1410 | { |
1335 | IScriptInstance instance = GetInstance(itemID); | 1411 | IScriptInstance instance = GetInstance(itemID); |
@@ -1350,11 +1426,10 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1350 | { | 1426 | { |
1351 | List<IScriptInstance> instances = new List<IScriptInstance>(); | 1427 | List<IScriptInstance> instances = new List<IScriptInstance>(); |
1352 | 1428 | ||
1353 | lock (m_Scripts) | 1429 | lockScriptsForRead(true); |
1354 | { | 1430 | foreach (IScriptInstance instance in m_Scripts.Values) |
1355 | foreach (IScriptInstance instance in m_Scripts.Values) | ||
1356 | instances.Add(instance); | 1431 | instances.Add(instance); |
1357 | } | 1432 | lockScriptsForRead(false); |
1358 | 1433 | ||
1359 | foreach (IScriptInstance i in instances) | 1434 | foreach (IScriptInstance i in instances) |
1360 | { | 1435 | { |
@@ -1735,5 +1810,17 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1735 | 1810 | ||
1736 | instance.Resume(); | 1811 | instance.Resume(); |
1737 | } | 1812 | } |
1813 | |||
1814 | public bool HasScript(UUID itemID, out bool running) | ||
1815 | { | ||
1816 | running = true; | ||
1817 | |||
1818 | IScriptInstance instance = GetInstance(itemID); | ||
1819 | if (instance == null) | ||
1820 | return false; | ||
1821 | |||
1822 | running = instance.Running; | ||
1823 | return true; | ||
1824 | } | ||
1738 | } | 1825 | } |
1739 | } | 1826 | } |