diff options
Diffstat (limited to 'OpenSim/Region/ScriptEngine/XEngine/XEngine.cs')
-rw-r--r-- | OpenSim/Region/ScriptEngine/XEngine/XEngine.cs | 362 |
1 files changed, 230 insertions, 132 deletions
diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs index 12e1a78..65c7416 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; |
@@ -108,6 +109,8 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
108 | private Dictionary<UUID, IScriptInstance> m_Scripts = | 109 | private Dictionary<UUID, IScriptInstance> m_Scripts = |
109 | new Dictionary<UUID, IScriptInstance>(); | 110 | new Dictionary<UUID, IScriptInstance>(); |
110 | 111 | ||
112 | private OpenMetaverse.ReaderWriterLockSlim m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim(); | ||
113 | |||
111 | // Maps the asset ID to the assembly | 114 | // Maps the asset ID to the assembly |
112 | 115 | ||
113 | private Dictionary<UUID, string> m_Assemblies = | 116 | private Dictionary<UUID, string> m_Assemblies = |
@@ -130,6 +133,71 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
130 | IWorkItemResult m_CurrentCompile = null; | 133 | IWorkItemResult m_CurrentCompile = null; |
131 | private Dictionary<UUID, int> m_CompileDict = new Dictionary<UUID, int>(); | 134 | private Dictionary<UUID, int> m_CompileDict = new Dictionary<UUID, int>(); |
132 | 135 | ||
136 | private void lockScriptsForRead(bool locked) | ||
137 | { | ||
138 | if (locked) | ||
139 | { | ||
140 | if (m_scriptsLock.RecursiveReadCount > 0) | ||
141 | { | ||
142 | 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."); | ||
143 | m_scriptsLock.ExitReadLock(); | ||
144 | } | ||
145 | if (m_scriptsLock.RecursiveWriteCount > 0) | ||
146 | { | ||
147 | m_log.Error("[XEngine.m_Scripts] Recursive write lock requested. This should not happen and means something needs to be fixed."); | ||
148 | m_scriptsLock.ExitWriteLock(); | ||
149 | } | ||
150 | |||
151 | while (!m_scriptsLock.TryEnterReadLock(60000)) | ||
152 | { | ||
153 | 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."); | ||
154 | if (m_scriptsLock.IsWriteLockHeld) | ||
155 | { | ||
156 | m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim(); | ||
157 | } | ||
158 | } | ||
159 | } | ||
160 | else | ||
161 | { | ||
162 | if (m_scriptsLock.RecursiveReadCount > 0) | ||
163 | { | ||
164 | m_scriptsLock.ExitReadLock(); | ||
165 | } | ||
166 | } | ||
167 | } | ||
168 | private void lockScriptsForWrite(bool locked) | ||
169 | { | ||
170 | if (locked) | ||
171 | { | ||
172 | if (m_scriptsLock.RecursiveReadCount > 0) | ||
173 | { | ||
174 | 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."); | ||
175 | m_scriptsLock.ExitReadLock(); | ||
176 | } | ||
177 | if (m_scriptsLock.RecursiveWriteCount > 0) | ||
178 | { | ||
179 | m_log.Error("[XEngine.m_Scripts] Recursive write lock requested. This should not happen and means something needs to be fixed."); | ||
180 | m_scriptsLock.ExitWriteLock(); | ||
181 | } | ||
182 | |||
183 | while (!m_scriptsLock.TryEnterWriteLock(60000)) | ||
184 | { | ||
185 | 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."); | ||
186 | if (m_scriptsLock.IsWriteLockHeld) | ||
187 | { | ||
188 | m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim(); | ||
189 | } | ||
190 | } | ||
191 | } | ||
192 | else | ||
193 | { | ||
194 | if (m_scriptsLock.RecursiveWriteCount > 0) | ||
195 | { | ||
196 | m_scriptsLock.ExitWriteLock(); | ||
197 | } | ||
198 | } | ||
199 | } | ||
200 | |||
133 | public string ScriptEngineName | 201 | public string ScriptEngineName |
134 | { | 202 | { |
135 | get { return "XEngine"; } | 203 | get { return "XEngine"; } |
@@ -450,44 +518,37 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
450 | { | 518 | { |
451 | if (!m_Enabled) | 519 | if (!m_Enabled) |
452 | return; | 520 | return; |
453 | 521 | lockScriptsForRead(true); | |
454 | lock (m_Scripts) | 522 | foreach (IScriptInstance instance in m_Scripts.Values) |
455 | { | 523 | { |
456 | m_log.InfoFormat( | 524 | // Force a final state save |
457 | "[XEngine]: Shutting down {0} scripts in {1}", m_Scripts.Count, m_Scene.RegionInfo.RegionName); | 525 | // |
458 | 526 | if (m_Assemblies.ContainsKey(instance.AssetID)) | |
459 | foreach (IScriptInstance instance in m_Scripts.Values) | ||
460 | { | 527 | { |
461 | // Force a final state save | 528 | string assembly = m_Assemblies[instance.AssetID]; |
462 | // | 529 | instance.SaveState(assembly); |
463 | if (m_Assemblies.ContainsKey(instance.AssetID)) | 530 | } |
464 | { | ||
465 | string assembly = m_Assemblies[instance.AssetID]; | ||
466 | instance.SaveState(assembly); | ||
467 | } | ||
468 | 531 | ||
469 | // Clear the event queue and abort the instance thread | 532 | // Clear the event queue and abort the instance thread |
470 | // | 533 | // |
471 | instance.ClearQueue(); | 534 | instance.ClearQueue(); |
472 | instance.Stop(0); | 535 | instance.Stop(0); |
473 | 536 | ||
474 | // Release events, timer, etc | 537 | // Release events, timer, etc |
475 | // | 538 | // |
476 | instance.DestroyScriptInstance(); | 539 | instance.DestroyScriptInstance(); |
477 | 540 | ||
478 | // Unload scripts and app domains. | 541 | // Unload scripts and app domains |
479 | // Must be done explicitly because they have infinite | 542 | // Must be done explicitly because they have infinite |
480 | // lifetime. | 543 | // lifetime |
481 | // However, don't bother to do this if the simulator is shutting | 544 | // |
482 | // down since it takes a long time with many scripts. | 545 | if (!m_SimulatorShuttingDown) |
483 | if (!m_SimulatorShuttingDown) | 546 | { |
547 | m_DomainScripts[instance.AppDomain].Remove(instance.ItemID); | ||
548 | if (m_DomainScripts[instance.AppDomain].Count == 0) | ||
484 | { | 549 | { |
485 | m_DomainScripts[instance.AppDomain].Remove(instance.ItemID); | 550 | m_DomainScripts.Remove(instance.AppDomain); |
486 | if (m_DomainScripts[instance.AppDomain].Count == 0) | 551 | UnloadAppDomain(instance.AppDomain); |
487 | { | ||
488 | m_DomainScripts.Remove(instance.AppDomain); | ||
489 | UnloadAppDomain(instance.AppDomain); | ||
490 | } | ||
491 | } | 552 | } |
492 | } | 553 | } |
493 | 554 | ||
@@ -496,6 +557,14 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
496 | m_Assemblies.Clear(); | 557 | m_Assemblies.Clear(); |
497 | m_DomainScripts.Clear(); | 558 | m_DomainScripts.Clear(); |
498 | } | 559 | } |
560 | lockScriptsForRead(false); | ||
561 | lockScriptsForWrite(true); | ||
562 | m_Scripts.Clear(); | ||
563 | lockScriptsForWrite(false); | ||
564 | m_PrimObjects.Clear(); | ||
565 | m_Assemblies.Clear(); | ||
566 | m_DomainScripts.Clear(); | ||
567 | |||
499 | lock (m_ScriptEngines) | 568 | lock (m_ScriptEngines) |
500 | { | 569 | { |
501 | m_ScriptEngines.Remove(this); | 570 | m_ScriptEngines.Remove(this); |
@@ -560,22 +629,20 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
560 | 629 | ||
561 | List<IScriptInstance> instances = new List<IScriptInstance>(); | 630 | List<IScriptInstance> instances = new List<IScriptInstance>(); |
562 | 631 | ||
563 | lock (m_Scripts) | 632 | lockScriptsForRead(true); |
564 | { | 633 | foreach (IScriptInstance instance in m_Scripts.Values) |
565 | foreach (IScriptInstance instance in m_Scripts.Values) | ||
566 | instances.Add(instance); | 634 | instances.Add(instance); |
567 | } | 635 | lockScriptsForRead(false); |
568 | 636 | ||
569 | foreach (IScriptInstance i in instances) | 637 | foreach (IScriptInstance i in instances) |
570 | { | 638 | { |
571 | string assembly = String.Empty; | 639 | string assembly = String.Empty; |
572 | 640 | ||
573 | lock (m_Scripts) | 641 | |
574 | { | ||
575 | if (!m_Assemblies.ContainsKey(i.AssetID)) | 642 | if (!m_Assemblies.ContainsKey(i.AssetID)) |
576 | continue; | 643 | continue; |
577 | assembly = m_Assemblies[i.AssetID]; | 644 | assembly = m_Assemblies[i.AssetID]; |
578 | } | 645 | |
579 | 646 | ||
580 | i.SaveState(assembly); | 647 | i.SaveState(assembly); |
581 | } | 648 | } |
@@ -909,92 +976,95 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
909 | } | 976 | } |
910 | 977 | ||
911 | ScriptInstance instance = null; | 978 | ScriptInstance instance = null; |
912 | lock (m_Scripts) | 979 | // Create the object record |
980 | lockScriptsForRead(true); | ||
981 | if ((!m_Scripts.ContainsKey(itemID)) || | ||
982 | (m_Scripts[itemID].AssetID != assetID)) | ||
913 | { | 983 | { |
914 | // Create the object record | 984 | lockScriptsForRead(false); |
915 | 985 | ||
916 | if ((!m_Scripts.ContainsKey(itemID)) || | 986 | UUID appDomain = assetID; |
917 | (m_Scripts[itemID].AssetID != assetID)) | ||
918 | { | ||
919 | UUID appDomain = assetID; | ||
920 | 987 | ||
921 | if (part.ParentGroup.IsAttachment) | 988 | if (part.ParentGroup.IsAttachment) |
922 | appDomain = part.ParentGroup.RootPart.UUID; | 989 | appDomain = part.ParentGroup.RootPart.UUID; |
923 | 990 | ||
924 | if (!m_AppDomains.ContainsKey(appDomain)) | 991 | if (!m_AppDomains.ContainsKey(appDomain)) |
992 | { | ||
993 | try | ||
925 | { | 994 | { |
926 | try | 995 | AppDomainSetup appSetup = new AppDomainSetup(); |
927 | { | 996 | appSetup.PrivateBinPath = Path.Combine( |
928 | AppDomainSetup appSetup = new AppDomainSetup(); | 997 | m_ScriptEnginesPath, |
929 | appSetup.PrivateBinPath = Path.Combine( | 998 | m_Scene.RegionInfo.RegionID.ToString()); |
930 | m_ScriptEnginesPath, | 999 | |
931 | m_Scene.RegionInfo.RegionID.ToString()); | 1000 | Evidence baseEvidence = AppDomain.CurrentDomain.Evidence; |
932 | 1001 | Evidence evidence = new Evidence(baseEvidence); | |
933 | Evidence baseEvidence = AppDomain.CurrentDomain.Evidence; | 1002 | |
934 | Evidence evidence = new Evidence(baseEvidence); | 1003 | AppDomain sandbox; |
935 | 1004 | if (m_AppDomainLoading) | |
936 | AppDomain sandbox; | 1005 | sandbox = AppDomain.CreateDomain( |
937 | if (m_AppDomainLoading) | 1006 | m_Scene.RegionInfo.RegionID.ToString(), |
938 | sandbox = AppDomain.CreateDomain( | 1007 | evidence, appSetup); |
939 | m_Scene.RegionInfo.RegionID.ToString(), | 1008 | else |
940 | evidence, appSetup); | 1009 | sandbox = AppDomain.CurrentDomain; |
941 | else | 1010 | |
942 | sandbox = AppDomain.CurrentDomain; | 1011 | //PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel(); |
943 | 1012 | //AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition(); | |
944 | //PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel(); | 1013 | //PermissionSet sandboxPermissionSet = sandboxPolicy.GetNamedPermissionSet("Internet"); |
945 | //AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition(); | 1014 | //PolicyStatement sandboxPolicyStatement = new PolicyStatement(sandboxPermissionSet); |
946 | //PermissionSet sandboxPermissionSet = sandboxPolicy.GetNamedPermissionSet("Internet"); | 1015 | //CodeGroup sandboxCodeGroup = new UnionCodeGroup(sandboxMembershipCondition, sandboxPolicyStatement); |
947 | //PolicyStatement sandboxPolicyStatement = new PolicyStatement(sandboxPermissionSet); | 1016 | //sandboxPolicy.RootCodeGroup = sandboxCodeGroup; |
948 | //CodeGroup sandboxCodeGroup = new UnionCodeGroup(sandboxMembershipCondition, sandboxPolicyStatement); | 1017 | //sandbox.SetAppDomainPolicy(sandboxPolicy); |
949 | //sandboxPolicy.RootCodeGroup = sandboxCodeGroup; | 1018 | |
950 | //sandbox.SetAppDomainPolicy(sandboxPolicy); | 1019 | m_AppDomains[appDomain] = sandbox; |
951 | 1020 | ||
952 | m_AppDomains[appDomain] = sandbox; | 1021 | m_AppDomains[appDomain].AssemblyResolve += |
953 | 1022 | new ResolveEventHandler( | |
954 | m_AppDomains[appDomain].AssemblyResolve += | 1023 | AssemblyResolver.OnAssemblyResolve); |
955 | new ResolveEventHandler( | 1024 | m_DomainScripts[appDomain] = new List<UUID>(); |
956 | AssemblyResolver.OnAssemblyResolve); | 1025 | } |
957 | m_DomainScripts[appDomain] = new List<UUID>(); | 1026 | catch (Exception e) |
958 | } | 1027 | { |
959 | catch (Exception e) | 1028 | m_log.ErrorFormat("[XEngine] Exception creating app domain:\n {0}", e.ToString()); |
1029 | m_ScriptErrorMessage += "Exception creating app domain:\n"; | ||
1030 | m_ScriptFailCount++; | ||
1031 | lock (m_AddingAssemblies) | ||
960 | { | 1032 | { |
961 | m_log.ErrorFormat("[XEngine] Exception creating app domain:\n {0}", e.ToString()); | 1033 | m_AddingAssemblies[assembly]--; |
962 | m_ScriptErrorMessage += "Exception creating app domain:\n"; | ||
963 | m_ScriptFailCount++; | ||
964 | lock (m_AddingAssemblies) | ||
965 | { | ||
966 | m_AddingAssemblies[assembly]--; | ||
967 | } | ||
968 | return false; | ||
969 | } | 1034 | } |
1035 | return false; | ||
970 | } | 1036 | } |
971 | m_DomainScripts[appDomain].Add(itemID); | 1037 | } |
972 | 1038 | m_DomainScripts[appDomain].Add(itemID); | |
973 | instance = new ScriptInstance(this, part, | 1039 | |
974 | itemID, assetID, assembly, | 1040 | instance = new ScriptInstance(this, part, |
975 | m_AppDomains[appDomain], | 1041 | itemID, assetID, assembly, |
976 | part.ParentGroup.RootPart.Name, | 1042 | m_AppDomains[appDomain], |
977 | item.Name, startParam, postOnRez, | 1043 | part.ParentGroup.RootPart.Name, |
978 | stateSource, m_MaxScriptQueue); | 1044 | item.Name, startParam, postOnRez, |
979 | 1045 | stateSource, m_MaxScriptQueue); | |
980 | m_log.DebugFormat( | 1046 | |
981 | "[XEngine] Loaded script {0}.{1}, item UUID {2}, prim UUID {3} @ {4}.{5}", | 1047 | m_log.DebugFormat( |
982 | part.ParentGroup.RootPart.Name, item.Name, itemID, part.UUID, | 1048 | "[XEngine] Loaded script {0}.{1}, script UUID {2}, prim UUID {3} @ {4}.{5}", |
1049 | part.ParentGroup.RootPart.Name, item.Name, assetID, part.UUID, | ||
983 | part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName); | 1050 | part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName); |
984 | 1051 | ||
985 | if (presence != null) | 1052 | if (presence != null) |
986 | { | 1053 | { |
987 | ShowScriptSaveResponse(item.OwnerID, | 1054 | ShowScriptSaveResponse(item.OwnerID, |
988 | assetID, "Compile successful", true); | 1055 | assetID, "Compile successful", true); |
989 | } | ||
990 | |||
991 | instance.AppDomain = appDomain; | ||
992 | instance.LineMap = linemap; | ||
993 | |||
994 | m_Scripts[itemID] = instance; | ||
995 | } | 1056 | } |
996 | } | ||
997 | 1057 | ||
1058 | instance.AppDomain = appDomain; | ||
1059 | instance.LineMap = linemap; | ||
1060 | lockScriptsForWrite(true); | ||
1061 | m_Scripts[itemID] = instance; | ||
1062 | lockScriptsForWrite(false); | ||
1063 | } | ||
1064 | else | ||
1065 | { | ||
1066 | lockScriptsForRead(false); | ||
1067 | } | ||
998 | lock (m_PrimObjects) | 1068 | lock (m_PrimObjects) |
999 | { | 1069 | { |
1000 | if (!m_PrimObjects.ContainsKey(localID)) | 1070 | if (!m_PrimObjects.ContainsKey(localID)) |
@@ -1013,9 +1083,9 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1013 | m_AddingAssemblies[assembly]--; | 1083 | m_AddingAssemblies[assembly]--; |
1014 | } | 1084 | } |
1015 | 1085 | ||
1016 | if (instance != null) | 1086 | if (instance!=null) |
1017 | instance.Init(); | 1087 | instance.Init(); |
1018 | 1088 | ||
1019 | return true; | 1089 | return true; |
1020 | } | 1090 | } |
1021 | 1091 | ||
@@ -1028,20 +1098,31 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1028 | m_CompileDict.Remove(itemID); | 1098 | m_CompileDict.Remove(itemID); |
1029 | } | 1099 | } |
1030 | 1100 | ||
1031 | IScriptInstance instance = null; | 1101 | lockScriptsForRead(true); |
1032 | 1102 | // Do we even have it? | |
1033 | lock (m_Scripts) | 1103 | if (!m_Scripts.ContainsKey(itemID)) |
1034 | { | 1104 | { |
1035 | // Do we even have it? | 1105 | // Do we even have it? |
1036 | if (!m_Scripts.ContainsKey(itemID)) | 1106 | if (!m_Scripts.ContainsKey(itemID)) |
1037 | return; | 1107 | return; |
1038 | 1108 | ||
1039 | instance = m_Scripts[itemID]; | 1109 | lockScriptsForRead(false); |
1110 | lockScriptsForWrite(true); | ||
1040 | m_Scripts.Remove(itemID); | 1111 | m_Scripts.Remove(itemID); |
1112 | lockScriptsForWrite(false); | ||
1113 | |||
1114 | return; | ||
1041 | } | 1115 | } |
1116 | |||
1042 | 1117 | ||
1118 | IScriptInstance instance=m_Scripts[itemID]; | ||
1119 | lockScriptsForRead(false); | ||
1120 | lockScriptsForWrite(true); | ||
1121 | m_Scripts.Remove(itemID); | ||
1122 | lockScriptsForWrite(false); | ||
1043 | instance.ClearQueue(); | 1123 | instance.ClearQueue(); |
1044 | instance.Stop(0); | 1124 | instance.Stop(0); |
1125 | |||
1045 | // bool objectRemoved = false; | 1126 | // bool objectRemoved = false; |
1046 | 1127 | ||
1047 | lock (m_PrimObjects) | 1128 | lock (m_PrimObjects) |
@@ -1077,11 +1158,12 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1077 | ObjectRemoved handlerObjectRemoved = OnObjectRemoved; | 1158 | ObjectRemoved handlerObjectRemoved = OnObjectRemoved; |
1078 | if (handlerObjectRemoved != null) | 1159 | if (handlerObjectRemoved != null) |
1079 | { | 1160 | { |
1080 | SceneObjectPart part = m_Scene.GetSceneObjectPart(localID); | 1161 | SceneObjectPart part = m_Scene.GetSceneObjectPart(localID); |
1081 | handlerObjectRemoved(part.UUID); | 1162 | handlerObjectRemoved(part.UUID); |
1082 | } | 1163 | } |
1083 | 1164 | ||
1084 | 1165 | CleanAssemblies(); | |
1166 | |||
1085 | ScriptRemoved handlerScriptRemoved = OnScriptRemoved; | 1167 | ScriptRemoved handlerScriptRemoved = OnScriptRemoved; |
1086 | if (handlerScriptRemoved != null) | 1168 | if (handlerScriptRemoved != null) |
1087 | handlerScriptRemoved(itemID); | 1169 | handlerScriptRemoved(itemID); |
@@ -1223,7 +1305,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1223 | return false; | 1305 | return false; |
1224 | 1306 | ||
1225 | uuids = m_PrimObjects[localID]; | 1307 | uuids = m_PrimObjects[localID]; |
1226 | } | 1308 | |
1227 | 1309 | ||
1228 | foreach (UUID itemID in uuids) | 1310 | foreach (UUID itemID in uuids) |
1229 | { | 1311 | { |
@@ -1241,6 +1323,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1241 | result = true; | 1323 | result = true; |
1242 | } | 1324 | } |
1243 | } | 1325 | } |
1326 | } | ||
1244 | 1327 | ||
1245 | return result; | 1328 | return result; |
1246 | } | 1329 | } |
@@ -1340,12 +1423,14 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1340 | private IScriptInstance GetInstance(UUID itemID) | 1423 | private IScriptInstance GetInstance(UUID itemID) |
1341 | { | 1424 | { |
1342 | IScriptInstance instance; | 1425 | IScriptInstance instance; |
1343 | lock (m_Scripts) | 1426 | lockScriptsForRead(true); |
1427 | if (!m_Scripts.ContainsKey(itemID)) | ||
1344 | { | 1428 | { |
1345 | if (!m_Scripts.ContainsKey(itemID)) | 1429 | lockScriptsForRead(false); |
1346 | return null; | 1430 | return null; |
1347 | instance = m_Scripts[itemID]; | ||
1348 | } | 1431 | } |
1432 | instance = m_Scripts[itemID]; | ||
1433 | lockScriptsForRead(false); | ||
1349 | return instance; | 1434 | return instance; |
1350 | } | 1435 | } |
1351 | 1436 | ||
@@ -1369,6 +1454,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1369 | return false; | 1454 | return false; |
1370 | } | 1455 | } |
1371 | 1456 | ||
1457 | [DebuggerNonUserCode] | ||
1372 | public void ApiResetScript(UUID itemID) | 1458 | public void ApiResetScript(UUID itemID) |
1373 | { | 1459 | { |
1374 | IScriptInstance instance = GetInstance(itemID); | 1460 | IScriptInstance instance = GetInstance(itemID); |
@@ -1420,6 +1506,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1420 | return UUID.Zero; | 1506 | return UUID.Zero; |
1421 | } | 1507 | } |
1422 | 1508 | ||
1509 | [DebuggerNonUserCode] | ||
1423 | public void SetState(UUID itemID, string newState) | 1510 | public void SetState(UUID itemID, string newState) |
1424 | { | 1511 | { |
1425 | IScriptInstance instance = GetInstance(itemID); | 1512 | IScriptInstance instance = GetInstance(itemID); |
@@ -1442,11 +1529,10 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1442 | 1529 | ||
1443 | List<IScriptInstance> instances = new List<IScriptInstance>(); | 1530 | List<IScriptInstance> instances = new List<IScriptInstance>(); |
1444 | 1531 | ||
1445 | lock (m_Scripts) | 1532 | lockScriptsForRead(true); |
1446 | { | 1533 | foreach (IScriptInstance instance in m_Scripts.Values) |
1447 | foreach (IScriptInstance instance in m_Scripts.Values) | ||
1448 | instances.Add(instance); | 1534 | instances.Add(instance); |
1449 | } | 1535 | lockScriptsForRead(false); |
1450 | 1536 | ||
1451 | foreach (IScriptInstance i in instances) | 1537 | foreach (IScriptInstance i in instances) |
1452 | { | 1538 | { |
@@ -1823,5 +1909,17 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1823 | if (instance != null) | 1909 | if (instance != null) |
1824 | instance.Resume(); | 1910 | instance.Resume(); |
1825 | } | 1911 | } |
1912 | |||
1913 | public bool HasScript(UUID itemID, out bool running) | ||
1914 | { | ||
1915 | running = true; | ||
1916 | |||
1917 | IScriptInstance instance = GetInstance(itemID); | ||
1918 | if (instance == null) | ||
1919 | return false; | ||
1920 | |||
1921 | running = instance.Running; | ||
1922 | return true; | ||
1923 | } | ||
1826 | } | 1924 | } |
1827 | } \ No newline at end of file | 1925 | } |