diff options
Diffstat (limited to '')
-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 c9bbf0e..23531a9 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"; } |
@@ -457,44 +525,37 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
457 | { | 525 | { |
458 | if (!m_Enabled) | 526 | if (!m_Enabled) |
459 | return; | 527 | return; |
460 | 528 | lockScriptsForRead(true); | |
461 | lock (m_Scripts) | 529 | foreach (IScriptInstance instance in m_Scripts.Values) |
462 | { | 530 | { |
463 | m_log.InfoFormat( | 531 | // Force a final state save |
464 | "[XEngine]: Shutting down {0} scripts in {1}", m_Scripts.Count, m_Scene.RegionInfo.RegionName); | 532 | // |
465 | 533 | if (m_Assemblies.ContainsKey(instance.AssetID)) | |
466 | foreach (IScriptInstance instance in m_Scripts.Values) | ||
467 | { | 534 | { |
468 | // Force a final state save | 535 | string assembly = m_Assemblies[instance.AssetID]; |
469 | // | 536 | instance.SaveState(assembly); |
470 | if (m_Assemblies.ContainsKey(instance.AssetID)) | 537 | } |
471 | { | ||
472 | string assembly = m_Assemblies[instance.AssetID]; | ||
473 | instance.SaveState(assembly); | ||
474 | } | ||
475 | 538 | ||
476 | // Clear the event queue and abort the instance thread | 539 | // Clear the event queue and abort the instance thread |
477 | // | 540 | // |
478 | instance.ClearQueue(); | 541 | instance.ClearQueue(); |
479 | instance.Stop(0); | 542 | instance.Stop(0); |
480 | 543 | ||
481 | // Release events, timer, etc | 544 | // Release events, timer, etc |
482 | // | 545 | // |
483 | instance.DestroyScriptInstance(); | 546 | instance.DestroyScriptInstance(); |
484 | 547 | ||
485 | // Unload scripts and app domains. | 548 | // Unload scripts and app domains |
486 | // Must be done explicitly because they have infinite | 549 | // Must be done explicitly because they have infinite |
487 | // lifetime. | 550 | // lifetime |
488 | // However, don't bother to do this if the simulator is shutting | 551 | // |
489 | // down since it takes a long time with many scripts. | 552 | if (!m_SimulatorShuttingDown) |
490 | if (!m_SimulatorShuttingDown) | 553 | { |
554 | m_DomainScripts[instance.AppDomain].Remove(instance.ItemID); | ||
555 | if (m_DomainScripts[instance.AppDomain].Count == 0) | ||
491 | { | 556 | { |
492 | m_DomainScripts[instance.AppDomain].Remove(instance.ItemID); | 557 | m_DomainScripts.Remove(instance.AppDomain); |
493 | if (m_DomainScripts[instance.AppDomain].Count == 0) | 558 | UnloadAppDomain(instance.AppDomain); |
494 | { | ||
495 | m_DomainScripts.Remove(instance.AppDomain); | ||
496 | UnloadAppDomain(instance.AppDomain); | ||
497 | } | ||
498 | } | 559 | } |
499 | } | 560 | } |
500 | 561 | ||
@@ -503,6 +564,14 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
503 | m_Assemblies.Clear(); | 564 | m_Assemblies.Clear(); |
504 | m_DomainScripts.Clear(); | 565 | m_DomainScripts.Clear(); |
505 | } | 566 | } |
567 | lockScriptsForRead(false); | ||
568 | lockScriptsForWrite(true); | ||
569 | m_Scripts.Clear(); | ||
570 | lockScriptsForWrite(false); | ||
571 | m_PrimObjects.Clear(); | ||
572 | m_Assemblies.Clear(); | ||
573 | m_DomainScripts.Clear(); | ||
574 | |||
506 | lock (m_ScriptEngines) | 575 | lock (m_ScriptEngines) |
507 | { | 576 | { |
508 | m_ScriptEngines.Remove(this); | 577 | m_ScriptEngines.Remove(this); |
@@ -567,22 +636,20 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
567 | 636 | ||
568 | List<IScriptInstance> instances = new List<IScriptInstance>(); | 637 | List<IScriptInstance> instances = new List<IScriptInstance>(); |
569 | 638 | ||
570 | lock (m_Scripts) | 639 | lockScriptsForRead(true); |
571 | { | 640 | foreach (IScriptInstance instance in m_Scripts.Values) |
572 | foreach (IScriptInstance instance in m_Scripts.Values) | ||
573 | instances.Add(instance); | 641 | instances.Add(instance); |
574 | } | 642 | lockScriptsForRead(false); |
575 | 643 | ||
576 | foreach (IScriptInstance i in instances) | 644 | foreach (IScriptInstance i in instances) |
577 | { | 645 | { |
578 | string assembly = String.Empty; | 646 | string assembly = String.Empty; |
579 | 647 | ||
580 | lock (m_Scripts) | 648 | |
581 | { | ||
582 | if (!m_Assemblies.ContainsKey(i.AssetID)) | 649 | if (!m_Assemblies.ContainsKey(i.AssetID)) |
583 | continue; | 650 | continue; |
584 | assembly = m_Assemblies[i.AssetID]; | 651 | assembly = m_Assemblies[i.AssetID]; |
585 | } | 652 | |
586 | 653 | ||
587 | i.SaveState(assembly); | 654 | i.SaveState(assembly); |
588 | } | 655 | } |
@@ -916,92 +983,95 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
916 | } | 983 | } |
917 | 984 | ||
918 | ScriptInstance instance = null; | 985 | ScriptInstance instance = null; |
919 | lock (m_Scripts) | 986 | // Create the object record |
987 | lockScriptsForRead(true); | ||
988 | if ((!m_Scripts.ContainsKey(itemID)) || | ||
989 | (m_Scripts[itemID].AssetID != assetID)) | ||
920 | { | 990 | { |
921 | // Create the object record | 991 | lockScriptsForRead(false); |
922 | 992 | ||
923 | if ((!m_Scripts.ContainsKey(itemID)) || | 993 | UUID appDomain = assetID; |
924 | (m_Scripts[itemID].AssetID != assetID)) | ||
925 | { | ||
926 | UUID appDomain = assetID; | ||
927 | 994 | ||
928 | if (part.ParentGroup.IsAttachment) | 995 | if (part.ParentGroup.IsAttachment) |
929 | appDomain = part.ParentGroup.RootPart.UUID; | 996 | appDomain = part.ParentGroup.RootPart.UUID; |
930 | 997 | ||
931 | if (!m_AppDomains.ContainsKey(appDomain)) | 998 | if (!m_AppDomains.ContainsKey(appDomain)) |
999 | { | ||
1000 | try | ||
932 | { | 1001 | { |
933 | try | 1002 | AppDomainSetup appSetup = new AppDomainSetup(); |
934 | { | 1003 | appSetup.PrivateBinPath = Path.Combine( |
935 | AppDomainSetup appSetup = new AppDomainSetup(); | 1004 | m_ScriptEnginesPath, |
936 | appSetup.PrivateBinPath = Path.Combine( | 1005 | m_Scene.RegionInfo.RegionID.ToString()); |
937 | m_ScriptEnginesPath, | 1006 | |
938 | m_Scene.RegionInfo.RegionID.ToString()); | 1007 | Evidence baseEvidence = AppDomain.CurrentDomain.Evidence; |
939 | 1008 | Evidence evidence = new Evidence(baseEvidence); | |
940 | Evidence baseEvidence = AppDomain.CurrentDomain.Evidence; | 1009 | |
941 | Evidence evidence = new Evidence(baseEvidence); | 1010 | AppDomain sandbox; |
942 | 1011 | if (m_AppDomainLoading) | |
943 | AppDomain sandbox; | 1012 | sandbox = AppDomain.CreateDomain( |
944 | if (m_AppDomainLoading) | 1013 | m_Scene.RegionInfo.RegionID.ToString(), |
945 | sandbox = AppDomain.CreateDomain( | 1014 | evidence, appSetup); |
946 | m_Scene.RegionInfo.RegionID.ToString(), | 1015 | else |
947 | evidence, appSetup); | 1016 | sandbox = AppDomain.CurrentDomain; |
948 | else | 1017 | |
949 | sandbox = AppDomain.CurrentDomain; | 1018 | //PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel(); |
950 | 1019 | //AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition(); | |
951 | //PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel(); | 1020 | //PermissionSet sandboxPermissionSet = sandboxPolicy.GetNamedPermissionSet("Internet"); |
952 | //AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition(); | 1021 | //PolicyStatement sandboxPolicyStatement = new PolicyStatement(sandboxPermissionSet); |
953 | //PermissionSet sandboxPermissionSet = sandboxPolicy.GetNamedPermissionSet("Internet"); | 1022 | //CodeGroup sandboxCodeGroup = new UnionCodeGroup(sandboxMembershipCondition, sandboxPolicyStatement); |
954 | //PolicyStatement sandboxPolicyStatement = new PolicyStatement(sandboxPermissionSet); | 1023 | //sandboxPolicy.RootCodeGroup = sandboxCodeGroup; |
955 | //CodeGroup sandboxCodeGroup = new UnionCodeGroup(sandboxMembershipCondition, sandboxPolicyStatement); | 1024 | //sandbox.SetAppDomainPolicy(sandboxPolicy); |
956 | //sandboxPolicy.RootCodeGroup = sandboxCodeGroup; | 1025 | |
957 | //sandbox.SetAppDomainPolicy(sandboxPolicy); | 1026 | m_AppDomains[appDomain] = sandbox; |
958 | 1027 | ||
959 | m_AppDomains[appDomain] = sandbox; | 1028 | m_AppDomains[appDomain].AssemblyResolve += |
960 | 1029 | new ResolveEventHandler( | |
961 | m_AppDomains[appDomain].AssemblyResolve += | 1030 | AssemblyResolver.OnAssemblyResolve); |
962 | new ResolveEventHandler( | 1031 | m_DomainScripts[appDomain] = new List<UUID>(); |
963 | AssemblyResolver.OnAssemblyResolve); | 1032 | } |
964 | m_DomainScripts[appDomain] = new List<UUID>(); | 1033 | catch (Exception e) |
965 | } | 1034 | { |
966 | catch (Exception e) | 1035 | m_log.ErrorFormat("[XEngine] Exception creating app domain:\n {0}", e.ToString()); |
1036 | m_ScriptErrorMessage += "Exception creating app domain:\n"; | ||
1037 | m_ScriptFailCount++; | ||
1038 | lock (m_AddingAssemblies) | ||
967 | { | 1039 | { |
968 | m_log.ErrorFormat("[XEngine] Exception creating app domain:\n {0}", e.ToString()); | 1040 | m_AddingAssemblies[assembly]--; |
969 | m_ScriptErrorMessage += "Exception creating app domain:\n"; | ||
970 | m_ScriptFailCount++; | ||
971 | lock (m_AddingAssemblies) | ||
972 | { | ||
973 | m_AddingAssemblies[assembly]--; | ||
974 | } | ||
975 | return false; | ||
976 | } | 1041 | } |
1042 | return false; | ||
977 | } | 1043 | } |
978 | m_DomainScripts[appDomain].Add(itemID); | 1044 | } |
979 | 1045 | m_DomainScripts[appDomain].Add(itemID); | |
980 | instance = new ScriptInstance(this, part, | 1046 | |
981 | itemID, assetID, assembly, | 1047 | instance = new ScriptInstance(this, part, |
982 | m_AppDomains[appDomain], | 1048 | itemID, assetID, assembly, |
983 | part.ParentGroup.RootPart.Name, | 1049 | m_AppDomains[appDomain], |
984 | item.Name, startParam, postOnRez, | 1050 | part.ParentGroup.RootPart.Name, |
985 | stateSource, m_MaxScriptQueue); | 1051 | item.Name, startParam, postOnRez, |
986 | 1052 | stateSource, m_MaxScriptQueue); | |
987 | m_log.DebugFormat( | 1053 | |
988 | "[XEngine] Loaded script {0}.{1}, item UUID {2}, prim UUID {3} @ {4}.{5}", | 1054 | m_log.DebugFormat( |
989 | part.ParentGroup.RootPart.Name, item.Name, itemID, part.UUID, | 1055 | "[XEngine] Loaded script {0}.{1}, script UUID {2}, prim UUID {3} @ {4}.{5}", |
1056 | part.ParentGroup.RootPart.Name, item.Name, assetID, part.UUID, | ||
990 | part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName); | 1057 | part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName); |
991 | 1058 | ||
992 | if (presence != null) | 1059 | if (presence != null) |
993 | { | 1060 | { |
994 | ShowScriptSaveResponse(item.OwnerID, | 1061 | ShowScriptSaveResponse(item.OwnerID, |
995 | assetID, "Compile successful", true); | 1062 | assetID, "Compile successful", true); |
996 | } | ||
997 | |||
998 | instance.AppDomain = appDomain; | ||
999 | instance.LineMap = linemap; | ||
1000 | |||
1001 | m_Scripts[itemID] = instance; | ||
1002 | } | 1063 | } |
1003 | } | ||
1004 | 1064 | ||
1065 | instance.AppDomain = appDomain; | ||
1066 | instance.LineMap = linemap; | ||
1067 | lockScriptsForWrite(true); | ||
1068 | m_Scripts[itemID] = instance; | ||
1069 | lockScriptsForWrite(false); | ||
1070 | } | ||
1071 | else | ||
1072 | { | ||
1073 | lockScriptsForRead(false); | ||
1074 | } | ||
1005 | lock (m_PrimObjects) | 1075 | lock (m_PrimObjects) |
1006 | { | 1076 | { |
1007 | if (!m_PrimObjects.ContainsKey(localID)) | 1077 | if (!m_PrimObjects.ContainsKey(localID)) |
@@ -1020,9 +1090,9 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1020 | m_AddingAssemblies[assembly]--; | 1090 | m_AddingAssemblies[assembly]--; |
1021 | } | 1091 | } |
1022 | 1092 | ||
1023 | if (instance != null) | 1093 | if (instance!=null) |
1024 | instance.Init(); | 1094 | instance.Init(); |
1025 | 1095 | ||
1026 | return true; | 1096 | return true; |
1027 | } | 1097 | } |
1028 | 1098 | ||
@@ -1035,20 +1105,31 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1035 | m_CompileDict.Remove(itemID); | 1105 | m_CompileDict.Remove(itemID); |
1036 | } | 1106 | } |
1037 | 1107 | ||
1038 | IScriptInstance instance = null; | 1108 | lockScriptsForRead(true); |
1039 | 1109 | // Do we even have it? | |
1040 | lock (m_Scripts) | 1110 | if (!m_Scripts.ContainsKey(itemID)) |
1041 | { | 1111 | { |
1042 | // Do we even have it? | 1112 | // Do we even have it? |
1043 | if (!m_Scripts.ContainsKey(itemID)) | 1113 | if (!m_Scripts.ContainsKey(itemID)) |
1044 | return; | 1114 | return; |
1045 | 1115 | ||
1046 | instance = m_Scripts[itemID]; | 1116 | lockScriptsForRead(false); |
1117 | lockScriptsForWrite(true); | ||
1047 | m_Scripts.Remove(itemID); | 1118 | m_Scripts.Remove(itemID); |
1119 | lockScriptsForWrite(false); | ||
1120 | |||
1121 | return; | ||
1048 | } | 1122 | } |
1123 | |||
1049 | 1124 | ||
1125 | IScriptInstance instance=m_Scripts[itemID]; | ||
1126 | lockScriptsForRead(false); | ||
1127 | lockScriptsForWrite(true); | ||
1128 | m_Scripts.Remove(itemID); | ||
1129 | lockScriptsForWrite(false); | ||
1050 | instance.ClearQueue(); | 1130 | instance.ClearQueue(); |
1051 | instance.Stop(0); | 1131 | instance.Stop(0); |
1132 | |||
1052 | // bool objectRemoved = false; | 1133 | // bool objectRemoved = false; |
1053 | 1134 | ||
1054 | lock (m_PrimObjects) | 1135 | lock (m_PrimObjects) |
@@ -1084,11 +1165,12 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1084 | ObjectRemoved handlerObjectRemoved = OnObjectRemoved; | 1165 | ObjectRemoved handlerObjectRemoved = OnObjectRemoved; |
1085 | if (handlerObjectRemoved != null) | 1166 | if (handlerObjectRemoved != null) |
1086 | { | 1167 | { |
1087 | SceneObjectPart part = m_Scene.GetSceneObjectPart(localID); | 1168 | SceneObjectPart part = m_Scene.GetSceneObjectPart(localID); |
1088 | handlerObjectRemoved(part.UUID); | 1169 | handlerObjectRemoved(part.UUID); |
1089 | } | 1170 | } |
1090 | 1171 | ||
1091 | 1172 | CleanAssemblies(); | |
1173 | |||
1092 | ScriptRemoved handlerScriptRemoved = OnScriptRemoved; | 1174 | ScriptRemoved handlerScriptRemoved = OnScriptRemoved; |
1093 | if (handlerScriptRemoved != null) | 1175 | if (handlerScriptRemoved != null) |
1094 | handlerScriptRemoved(itemID); | 1176 | handlerScriptRemoved(itemID); |
@@ -1230,7 +1312,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1230 | return false; | 1312 | return false; |
1231 | 1313 | ||
1232 | uuids = m_PrimObjects[localID]; | 1314 | uuids = m_PrimObjects[localID]; |
1233 | } | 1315 | |
1234 | 1316 | ||
1235 | foreach (UUID itemID in uuids) | 1317 | foreach (UUID itemID in uuids) |
1236 | { | 1318 | { |
@@ -1248,6 +1330,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1248 | result = true; | 1330 | result = true; |
1249 | } | 1331 | } |
1250 | } | 1332 | } |
1333 | } | ||
1251 | 1334 | ||
1252 | return result; | 1335 | return result; |
1253 | } | 1336 | } |
@@ -1347,12 +1430,14 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1347 | private IScriptInstance GetInstance(UUID itemID) | 1430 | private IScriptInstance GetInstance(UUID itemID) |
1348 | { | 1431 | { |
1349 | IScriptInstance instance; | 1432 | IScriptInstance instance; |
1350 | lock (m_Scripts) | 1433 | lockScriptsForRead(true); |
1434 | if (!m_Scripts.ContainsKey(itemID)) | ||
1351 | { | 1435 | { |
1352 | if (!m_Scripts.ContainsKey(itemID)) | 1436 | lockScriptsForRead(false); |
1353 | return null; | 1437 | return null; |
1354 | instance = m_Scripts[itemID]; | ||
1355 | } | 1438 | } |
1439 | instance = m_Scripts[itemID]; | ||
1440 | lockScriptsForRead(false); | ||
1356 | return instance; | 1441 | return instance; |
1357 | } | 1442 | } |
1358 | 1443 | ||
@@ -1376,6 +1461,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1376 | return false; | 1461 | return false; |
1377 | } | 1462 | } |
1378 | 1463 | ||
1464 | [DebuggerNonUserCode] | ||
1379 | public void ApiResetScript(UUID itemID) | 1465 | public void ApiResetScript(UUID itemID) |
1380 | { | 1466 | { |
1381 | IScriptInstance instance = GetInstance(itemID); | 1467 | IScriptInstance instance = GetInstance(itemID); |
@@ -1427,6 +1513,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1427 | return UUID.Zero; | 1513 | return UUID.Zero; |
1428 | } | 1514 | } |
1429 | 1515 | ||
1516 | [DebuggerNonUserCode] | ||
1430 | public void SetState(UUID itemID, string newState) | 1517 | public void SetState(UUID itemID, string newState) |
1431 | { | 1518 | { |
1432 | IScriptInstance instance = GetInstance(itemID); | 1519 | IScriptInstance instance = GetInstance(itemID); |
@@ -1449,11 +1536,10 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1449 | 1536 | ||
1450 | List<IScriptInstance> instances = new List<IScriptInstance>(); | 1537 | List<IScriptInstance> instances = new List<IScriptInstance>(); |
1451 | 1538 | ||
1452 | lock (m_Scripts) | 1539 | lockScriptsForRead(true); |
1453 | { | 1540 | foreach (IScriptInstance instance in m_Scripts.Values) |
1454 | foreach (IScriptInstance instance in m_Scripts.Values) | ||
1455 | instances.Add(instance); | 1541 | instances.Add(instance); |
1456 | } | 1542 | lockScriptsForRead(false); |
1457 | 1543 | ||
1458 | foreach (IScriptInstance i in instances) | 1544 | foreach (IScriptInstance i in instances) |
1459 | { | 1545 | { |
@@ -1830,5 +1916,17 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1830 | if (instance != null) | 1916 | if (instance != null) |
1831 | instance.Resume(); | 1917 | instance.Resume(); |
1832 | } | 1918 | } |
1919 | |||
1920 | public bool HasScript(UUID itemID, out bool running) | ||
1921 | { | ||
1922 | running = true; | ||
1923 | |||
1924 | IScriptInstance instance = GetInstance(itemID); | ||
1925 | if (instance == null) | ||
1926 | return false; | ||
1927 | |||
1928 | running = instance.Running; | ||
1929 | return true; | ||
1930 | } | ||
1833 | } | 1931 | } |
1834 | } \ No newline at end of file | 1932 | } |