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