diff options
Diffstat (limited to '')
-rw-r--r-- | OpenSim/Region/ScriptEngine/XEngine/XEngine.cs | 359 |
1 files changed, 227 insertions, 132 deletions
diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs index 1c16c87..402377d 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"; } |
@@ -445,47 +513,45 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
445 | { | 513 | { |
446 | if (!m_Enabled) | 514 | if (!m_Enabled) |
447 | return; | 515 | return; |
448 | 516 | lockScriptsForRead(true); | |
449 | lock (m_Scripts) | 517 | foreach (IScriptInstance instance in m_Scripts.Values) |
450 | { | 518 | { |
451 | m_log.InfoFormat( | 519 | // Force a final state save |
452 | "[XEngine]: Shutting down {0} scripts in {1}", m_Scripts.Count, m_Scene.RegionInfo.RegionName); | 520 | // |
453 | 521 | if (m_Assemblies.ContainsKey(instance.AssetID)) | |
454 | foreach (IScriptInstance instance in m_Scripts.Values) | ||
455 | { | 522 | { |
456 | // Force a final state save | 523 | string assembly = m_Assemblies[instance.AssetID]; |
457 | // | 524 | instance.SaveState(assembly); |
458 | if (m_Assemblies.ContainsKey(instance.AssetID)) | 525 | } |
459 | { | ||
460 | string assembly = m_Assemblies[instance.AssetID]; | ||
461 | instance.SaveState(assembly); | ||
462 | } | ||
463 | 526 | ||
464 | // Clear the event queue and abort the instance thread | 527 | // Clear the event queue and abort the instance thread |
465 | // | 528 | // |
466 | instance.ClearQueue(); | 529 | instance.ClearQueue(); |
467 | instance.Stop(0); | 530 | instance.Stop(0); |
468 | 531 | ||
469 | // Release events, timer, etc | 532 | // Release events, timer, etc |
470 | // | 533 | // |
471 | instance.DestroyScriptInstance(); | 534 | instance.DestroyScriptInstance(); |
472 | 535 | ||
473 | // Unload scripts and app domains | 536 | // Unload scripts and app domains |
474 | // Must be done explicitly because they have infinite | 537 | // Must be done explicitly because they have infinite |
475 | // lifetime | 538 | // lifetime |
476 | // | 539 | // |
477 | m_DomainScripts[instance.AppDomain].Remove(instance.ItemID); | 540 | m_DomainScripts[instance.AppDomain].Remove(instance.ItemID); |
478 | if (m_DomainScripts[instance.AppDomain].Count == 0) | 541 | if (m_DomainScripts[instance.AppDomain].Count == 0) |
479 | { | 542 | { |
480 | m_DomainScripts.Remove(instance.AppDomain); | 543 | m_DomainScripts.Remove(instance.AppDomain); |
481 | UnloadAppDomain(instance.AppDomain); | 544 | UnloadAppDomain(instance.AppDomain); |
482 | } | ||
483 | } | 545 | } |
484 | m_Scripts.Clear(); | ||
485 | m_PrimObjects.Clear(); | ||
486 | m_Assemblies.Clear(); | ||
487 | m_DomainScripts.Clear(); | ||
488 | } | 546 | } |
547 | lockScriptsForRead(false); | ||
548 | lockScriptsForWrite(true); | ||
549 | m_Scripts.Clear(); | ||
550 | lockScriptsForWrite(false); | ||
551 | m_PrimObjects.Clear(); | ||
552 | m_Assemblies.Clear(); | ||
553 | m_DomainScripts.Clear(); | ||
554 | |||
489 | lock (m_ScriptEngines) | 555 | lock (m_ScriptEngines) |
490 | { | 556 | { |
491 | m_ScriptEngines.Remove(this); | 557 | m_ScriptEngines.Remove(this); |
@@ -550,22 +616,20 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
550 | 616 | ||
551 | List<IScriptInstance> instances = new List<IScriptInstance>(); | 617 | List<IScriptInstance> instances = new List<IScriptInstance>(); |
552 | 618 | ||
553 | lock (m_Scripts) | 619 | lockScriptsForRead(true); |
554 | { | 620 | foreach (IScriptInstance instance in m_Scripts.Values) |
555 | foreach (IScriptInstance instance in m_Scripts.Values) | ||
556 | instances.Add(instance); | 621 | instances.Add(instance); |
557 | } | 622 | lockScriptsForRead(false); |
558 | 623 | ||
559 | foreach (IScriptInstance i in instances) | 624 | foreach (IScriptInstance i in instances) |
560 | { | 625 | { |
561 | string assembly = String.Empty; | 626 | string assembly = String.Empty; |
562 | 627 | ||
563 | lock (m_Scripts) | 628 | |
564 | { | ||
565 | if (!m_Assemblies.ContainsKey(i.AssetID)) | 629 | if (!m_Assemblies.ContainsKey(i.AssetID)) |
566 | continue; | 630 | continue; |
567 | assembly = m_Assemblies[i.AssetID]; | 631 | assembly = m_Assemblies[i.AssetID]; |
568 | } | 632 | |
569 | 633 | ||
570 | i.SaveState(assembly); | 634 | i.SaveState(assembly); |
571 | } | 635 | } |
@@ -899,92 +963,95 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
899 | } | 963 | } |
900 | 964 | ||
901 | ScriptInstance instance = null; | 965 | ScriptInstance instance = null; |
902 | lock (m_Scripts) | 966 | // Create the object record |
967 | lockScriptsForRead(true); | ||
968 | if ((!m_Scripts.ContainsKey(itemID)) || | ||
969 | (m_Scripts[itemID].AssetID != assetID)) | ||
903 | { | 970 | { |
904 | // Create the object record | 971 | lockScriptsForRead(false); |
905 | 972 | ||
906 | if ((!m_Scripts.ContainsKey(itemID)) || | 973 | UUID appDomain = assetID; |
907 | (m_Scripts[itemID].AssetID != assetID)) | ||
908 | { | ||
909 | UUID appDomain = assetID; | ||
910 | 974 | ||
911 | if (part.ParentGroup.IsAttachment) | 975 | if (part.ParentGroup.IsAttachment) |
912 | appDomain = part.ParentGroup.RootPart.UUID; | 976 | appDomain = part.ParentGroup.RootPart.UUID; |
913 | 977 | ||
914 | if (!m_AppDomains.ContainsKey(appDomain)) | 978 | if (!m_AppDomains.ContainsKey(appDomain)) |
979 | { | ||
980 | try | ||
915 | { | 981 | { |
916 | try | 982 | AppDomainSetup appSetup = new AppDomainSetup(); |
917 | { | 983 | appSetup.PrivateBinPath = Path.Combine( |
918 | AppDomainSetup appSetup = new AppDomainSetup(); | 984 | m_ScriptEnginesPath, |
919 | appSetup.PrivateBinPath = Path.Combine( | 985 | m_Scene.RegionInfo.RegionID.ToString()); |
920 | m_ScriptEnginesPath, | 986 | |
921 | m_Scene.RegionInfo.RegionID.ToString()); | 987 | Evidence baseEvidence = AppDomain.CurrentDomain.Evidence; |
922 | 988 | Evidence evidence = new Evidence(baseEvidence); | |
923 | Evidence baseEvidence = AppDomain.CurrentDomain.Evidence; | 989 | |
924 | Evidence evidence = new Evidence(baseEvidence); | 990 | AppDomain sandbox; |
925 | 991 | if (m_AppDomainLoading) | |
926 | AppDomain sandbox; | 992 | sandbox = AppDomain.CreateDomain( |
927 | if (m_AppDomainLoading) | 993 | m_Scene.RegionInfo.RegionID.ToString(), |
928 | sandbox = AppDomain.CreateDomain( | 994 | evidence, appSetup); |
929 | m_Scene.RegionInfo.RegionID.ToString(), | 995 | else |
930 | evidence, appSetup); | 996 | sandbox = AppDomain.CurrentDomain; |
931 | else | 997 | |
932 | sandbox = AppDomain.CurrentDomain; | 998 | //PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel(); |
933 | 999 | //AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition(); | |
934 | //PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel(); | 1000 | //PermissionSet sandboxPermissionSet = sandboxPolicy.GetNamedPermissionSet("Internet"); |
935 | //AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition(); | 1001 | //PolicyStatement sandboxPolicyStatement = new PolicyStatement(sandboxPermissionSet); |
936 | //PermissionSet sandboxPermissionSet = sandboxPolicy.GetNamedPermissionSet("Internet"); | 1002 | //CodeGroup sandboxCodeGroup = new UnionCodeGroup(sandboxMembershipCondition, sandboxPolicyStatement); |
937 | //PolicyStatement sandboxPolicyStatement = new PolicyStatement(sandboxPermissionSet); | 1003 | //sandboxPolicy.RootCodeGroup = sandboxCodeGroup; |
938 | //CodeGroup sandboxCodeGroup = new UnionCodeGroup(sandboxMembershipCondition, sandboxPolicyStatement); | 1004 | //sandbox.SetAppDomainPolicy(sandboxPolicy); |
939 | //sandboxPolicy.RootCodeGroup = sandboxCodeGroup; | 1005 | |
940 | //sandbox.SetAppDomainPolicy(sandboxPolicy); | 1006 | m_AppDomains[appDomain] = sandbox; |
941 | 1007 | ||
942 | m_AppDomains[appDomain] = sandbox; | 1008 | m_AppDomains[appDomain].AssemblyResolve += |
943 | 1009 | new ResolveEventHandler( | |
944 | m_AppDomains[appDomain].AssemblyResolve += | 1010 | AssemblyResolver.OnAssemblyResolve); |
945 | new ResolveEventHandler( | 1011 | m_DomainScripts[appDomain] = new List<UUID>(); |
946 | AssemblyResolver.OnAssemblyResolve); | 1012 | } |
947 | m_DomainScripts[appDomain] = new List<UUID>(); | 1013 | catch (Exception e) |
948 | } | 1014 | { |
949 | catch (Exception e) | 1015 | m_log.ErrorFormat("[XEngine] Exception creating app domain:\n {0}", e.ToString()); |
1016 | m_ScriptErrorMessage += "Exception creating app domain:\n"; | ||
1017 | m_ScriptFailCount++; | ||
1018 | lock (m_AddingAssemblies) | ||
950 | { | 1019 | { |
951 | m_log.ErrorFormat("[XEngine] Exception creating app domain:\n {0}", e.ToString()); | 1020 | m_AddingAssemblies[assembly]--; |
952 | m_ScriptErrorMessage += "Exception creating app domain:\n"; | ||
953 | m_ScriptFailCount++; | ||
954 | lock (m_AddingAssemblies) | ||
955 | { | ||
956 | m_AddingAssemblies[assembly]--; | ||
957 | } | ||
958 | return false; | ||
959 | } | 1021 | } |
1022 | return false; | ||
960 | } | 1023 | } |
961 | m_DomainScripts[appDomain].Add(itemID); | 1024 | } |
962 | 1025 | m_DomainScripts[appDomain].Add(itemID); | |
963 | instance = new ScriptInstance(this, part, | 1026 | |
964 | itemID, assetID, assembly, | 1027 | instance = new ScriptInstance(this, part, |
965 | m_AppDomains[appDomain], | 1028 | itemID, assetID, assembly, |
966 | part.ParentGroup.RootPart.Name, | 1029 | m_AppDomains[appDomain], |
967 | item.Name, startParam, postOnRez, | 1030 | part.ParentGroup.RootPart.Name, |
968 | stateSource, m_MaxScriptQueue); | 1031 | item.Name, startParam, postOnRez, |
969 | 1032 | stateSource, m_MaxScriptQueue); | |
970 | m_log.DebugFormat( | 1033 | |
971 | "[XEngine] Loaded script {0}.{1}, item UUID {2}, prim UUID {3} @ {4}.{5}", | 1034 | m_log.DebugFormat( |
972 | part.ParentGroup.RootPart.Name, item.Name, itemID, part.UUID, | 1035 | "[XEngine] Loaded script {0}.{1}, script UUID {2}, prim UUID {3} @ {4}.{5}", |
1036 | part.ParentGroup.RootPart.Name, item.Name, assetID, part.UUID, | ||
973 | part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName); | 1037 | part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName); |
974 | 1038 | ||
975 | if (presence != null) | 1039 | if (presence != null) |
976 | { | 1040 | { |
977 | ShowScriptSaveResponse(item.OwnerID, | 1041 | ShowScriptSaveResponse(item.OwnerID, |
978 | assetID, "Compile successful", true); | 1042 | assetID, "Compile successful", true); |
979 | } | ||
980 | |||
981 | instance.AppDomain = appDomain; | ||
982 | instance.LineMap = linemap; | ||
983 | |||
984 | m_Scripts[itemID] = instance; | ||
985 | } | 1043 | } |
986 | } | ||
987 | 1044 | ||
1045 | instance.AppDomain = appDomain; | ||
1046 | instance.LineMap = linemap; | ||
1047 | lockScriptsForWrite(true); | ||
1048 | m_Scripts[itemID] = instance; | ||
1049 | lockScriptsForWrite(false); | ||
1050 | } | ||
1051 | else | ||
1052 | { | ||
1053 | lockScriptsForRead(false); | ||
1054 | } | ||
988 | lock (m_PrimObjects) | 1055 | lock (m_PrimObjects) |
989 | { | 1056 | { |
990 | if (!m_PrimObjects.ContainsKey(localID)) | 1057 | if (!m_PrimObjects.ContainsKey(localID)) |
@@ -1003,9 +1070,9 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1003 | m_AddingAssemblies[assembly]--; | 1070 | m_AddingAssemblies[assembly]--; |
1004 | } | 1071 | } |
1005 | 1072 | ||
1006 | if (instance != null) | 1073 | if (instance!=null) |
1007 | instance.Init(); | 1074 | instance.Init(); |
1008 | 1075 | ||
1009 | return true; | 1076 | return true; |
1010 | } | 1077 | } |
1011 | 1078 | ||
@@ -1018,20 +1085,31 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1018 | m_CompileDict.Remove(itemID); | 1085 | m_CompileDict.Remove(itemID); |
1019 | } | 1086 | } |
1020 | 1087 | ||
1021 | IScriptInstance instance = null; | 1088 | lockScriptsForRead(true); |
1022 | 1089 | // Do we even have it? | |
1023 | lock (m_Scripts) | 1090 | if (!m_Scripts.ContainsKey(itemID)) |
1024 | { | 1091 | { |
1025 | // Do we even have it? | 1092 | // Do we even have it? |
1026 | if (!m_Scripts.ContainsKey(itemID)) | 1093 | if (!m_Scripts.ContainsKey(itemID)) |
1027 | return; | 1094 | return; |
1028 | 1095 | ||
1029 | instance = m_Scripts[itemID]; | 1096 | lockScriptsForRead(false); |
1097 | lockScriptsForWrite(true); | ||
1030 | m_Scripts.Remove(itemID); | 1098 | m_Scripts.Remove(itemID); |
1099 | lockScriptsForWrite(false); | ||
1100 | |||
1101 | return; | ||
1031 | } | 1102 | } |
1103 | |||
1032 | 1104 | ||
1105 | IScriptInstance instance=m_Scripts[itemID]; | ||
1106 | lockScriptsForRead(false); | ||
1107 | lockScriptsForWrite(true); | ||
1108 | m_Scripts.Remove(itemID); | ||
1109 | lockScriptsForWrite(false); | ||
1033 | instance.ClearQueue(); | 1110 | instance.ClearQueue(); |
1034 | instance.Stop(0); | 1111 | instance.Stop(0); |
1112 | |||
1035 | // bool objectRemoved = false; | 1113 | // bool objectRemoved = false; |
1036 | 1114 | ||
1037 | lock (m_PrimObjects) | 1115 | lock (m_PrimObjects) |
@@ -1067,11 +1145,12 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1067 | ObjectRemoved handlerObjectRemoved = OnObjectRemoved; | 1145 | ObjectRemoved handlerObjectRemoved = OnObjectRemoved; |
1068 | if (handlerObjectRemoved != null) | 1146 | if (handlerObjectRemoved != null) |
1069 | { | 1147 | { |
1070 | SceneObjectPart part = m_Scene.GetSceneObjectPart(localID); | 1148 | SceneObjectPart part = m_Scene.GetSceneObjectPart(localID); |
1071 | handlerObjectRemoved(part.UUID); | 1149 | handlerObjectRemoved(part.UUID); |
1072 | } | 1150 | } |
1073 | 1151 | ||
1074 | 1152 | CleanAssemblies(); | |
1153 | |||
1075 | ScriptRemoved handlerScriptRemoved = OnScriptRemoved; | 1154 | ScriptRemoved handlerScriptRemoved = OnScriptRemoved; |
1076 | if (handlerScriptRemoved != null) | 1155 | if (handlerScriptRemoved != null) |
1077 | handlerScriptRemoved(itemID); | 1156 | handlerScriptRemoved(itemID); |
@@ -1213,7 +1292,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1213 | return false; | 1292 | return false; |
1214 | 1293 | ||
1215 | uuids = m_PrimObjects[localID]; | 1294 | uuids = m_PrimObjects[localID]; |
1216 | } | 1295 | |
1217 | 1296 | ||
1218 | foreach (UUID itemID in uuids) | 1297 | foreach (UUID itemID in uuids) |
1219 | { | 1298 | { |
@@ -1231,6 +1310,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1231 | result = true; | 1310 | result = true; |
1232 | } | 1311 | } |
1233 | } | 1312 | } |
1313 | } | ||
1234 | 1314 | ||
1235 | return result; | 1315 | return result; |
1236 | } | 1316 | } |
@@ -1330,12 +1410,14 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1330 | private IScriptInstance GetInstance(UUID itemID) | 1410 | private IScriptInstance GetInstance(UUID itemID) |
1331 | { | 1411 | { |
1332 | IScriptInstance instance; | 1412 | IScriptInstance instance; |
1333 | lock (m_Scripts) | 1413 | lockScriptsForRead(true); |
1414 | if (!m_Scripts.ContainsKey(itemID)) | ||
1334 | { | 1415 | { |
1335 | if (!m_Scripts.ContainsKey(itemID)) | 1416 | lockScriptsForRead(false); |
1336 | return null; | 1417 | return null; |
1337 | instance = m_Scripts[itemID]; | ||
1338 | } | 1418 | } |
1419 | instance = m_Scripts[itemID]; | ||
1420 | lockScriptsForRead(false); | ||
1339 | return instance; | 1421 | return instance; |
1340 | } | 1422 | } |
1341 | 1423 | ||
@@ -1359,6 +1441,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1359 | return false; | 1441 | return false; |
1360 | } | 1442 | } |
1361 | 1443 | ||
1444 | [DebuggerNonUserCode] | ||
1362 | public void ApiResetScript(UUID itemID) | 1445 | public void ApiResetScript(UUID itemID) |
1363 | { | 1446 | { |
1364 | IScriptInstance instance = GetInstance(itemID); | 1447 | IScriptInstance instance = GetInstance(itemID); |
@@ -1410,6 +1493,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1410 | return UUID.Zero; | 1493 | return UUID.Zero; |
1411 | } | 1494 | } |
1412 | 1495 | ||
1496 | [DebuggerNonUserCode] | ||
1413 | public void SetState(UUID itemID, string newState) | 1497 | public void SetState(UUID itemID, string newState) |
1414 | { | 1498 | { |
1415 | IScriptInstance instance = GetInstance(itemID); | 1499 | IScriptInstance instance = GetInstance(itemID); |
@@ -1430,11 +1514,10 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1430 | { | 1514 | { |
1431 | List<IScriptInstance> instances = new List<IScriptInstance>(); | 1515 | List<IScriptInstance> instances = new List<IScriptInstance>(); |
1432 | 1516 | ||
1433 | lock (m_Scripts) | 1517 | lockScriptsForRead(true); |
1434 | { | 1518 | foreach (IScriptInstance instance in m_Scripts.Values) |
1435 | foreach (IScriptInstance instance in m_Scripts.Values) | ||
1436 | instances.Add(instance); | 1519 | instances.Add(instance); |
1437 | } | 1520 | lockScriptsForRead(false); |
1438 | 1521 | ||
1439 | foreach (IScriptInstance i in instances) | 1522 | foreach (IScriptInstance i in instances) |
1440 | { | 1523 | { |
@@ -1811,5 +1894,17 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1811 | if (instance != null) | 1894 | if (instance != null) |
1812 | instance.Resume(); | 1895 | instance.Resume(); |
1813 | } | 1896 | } |
1897 | |||
1898 | public bool HasScript(UUID itemID, out bool running) | ||
1899 | { | ||
1900 | running = true; | ||
1901 | |||
1902 | IScriptInstance instance = GetInstance(itemID); | ||
1903 | if (instance == null) | ||
1904 | return false; | ||
1905 | |||
1906 | running = instance.Running; | ||
1907 | return true; | ||
1908 | } | ||
1814 | } | 1909 | } |
1815 | } \ No newline at end of file | 1910 | } \ No newline at end of file |