diff options
Diffstat (limited to '')
-rw-r--r-- | OpenSim/Region/ScriptEngine/XEngine/XEngine.cs | 361 |
1 files changed, 230 insertions, 131 deletions
diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs index c68f03f..02d47bd 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs | |||
@@ -28,6 +28,7 @@ | |||
28 | using System; | 28 | using System; |
29 | using System.Collections; | 29 | using System.Collections; |
30 | using System.Collections.Generic; | 30 | using System.Collections.Generic; |
31 | using System.Diagnostics; //for [DebuggerNonUserCode] | ||
31 | using System.Globalization; | 32 | using System.Globalization; |
32 | using System.IO; | 33 | using System.IO; |
33 | using System.Reflection; | 34 | using System.Reflection; |
@@ -109,6 +110,8 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
109 | private Dictionary<UUID, IScriptInstance> m_Scripts = | 110 | private Dictionary<UUID, IScriptInstance> m_Scripts = |
110 | new Dictionary<UUID, IScriptInstance>(); | 111 | new Dictionary<UUID, IScriptInstance>(); |
111 | 112 | ||
113 | private OpenMetaverse.ReaderWriterLockSlim m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim(); | ||
114 | |||
112 | // Maps the asset ID to the assembly | 115 | // Maps the asset ID to the assembly |
113 | 116 | ||
114 | private Dictionary<UUID, string> m_Assemblies = | 117 | private Dictionary<UUID, string> m_Assemblies = |
@@ -131,6 +134,71 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
131 | IWorkItemResult m_CurrentCompile = null; | 134 | IWorkItemResult m_CurrentCompile = null; |
132 | private Dictionary<UUID, int> m_CompileDict = new Dictionary<UUID, int>(); | 135 | private Dictionary<UUID, int> m_CompileDict = new Dictionary<UUID, int>(); |
133 | 136 | ||
137 | private void lockScriptsForRead(bool locked) | ||
138 | { | ||
139 | if (locked) | ||
140 | { | ||
141 | if (m_scriptsLock.RecursiveReadCount > 0) | ||
142 | { | ||
143 | 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."); | ||
144 | m_scriptsLock.ExitReadLock(); | ||
145 | } | ||
146 | if (m_scriptsLock.RecursiveWriteCount > 0) | ||
147 | { | ||
148 | m_log.Error("[XEngine.m_Scripts] Recursive write lock requested. This should not happen and means something needs to be fixed."); | ||
149 | m_scriptsLock.ExitWriteLock(); | ||
150 | } | ||
151 | |||
152 | while (!m_scriptsLock.TryEnterReadLock(60000)) | ||
153 | { | ||
154 | 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."); | ||
155 | if (m_scriptsLock.IsWriteLockHeld) | ||
156 | { | ||
157 | m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim(); | ||
158 | } | ||
159 | } | ||
160 | } | ||
161 | else | ||
162 | { | ||
163 | if (m_scriptsLock.RecursiveReadCount > 0) | ||
164 | { | ||
165 | m_scriptsLock.ExitReadLock(); | ||
166 | } | ||
167 | } | ||
168 | } | ||
169 | private void lockScriptsForWrite(bool locked) | ||
170 | { | ||
171 | if (locked) | ||
172 | { | ||
173 | if (m_scriptsLock.RecursiveReadCount > 0) | ||
174 | { | ||
175 | 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."); | ||
176 | m_scriptsLock.ExitReadLock(); | ||
177 | } | ||
178 | if (m_scriptsLock.RecursiveWriteCount > 0) | ||
179 | { | ||
180 | m_log.Error("[XEngine.m_Scripts] Recursive write lock requested. This should not happen and means something needs to be fixed."); | ||
181 | m_scriptsLock.ExitWriteLock(); | ||
182 | } | ||
183 | |||
184 | while (!m_scriptsLock.TryEnterWriteLock(60000)) | ||
185 | { | ||
186 | 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."); | ||
187 | if (m_scriptsLock.IsWriteLockHeld) | ||
188 | { | ||
189 | m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim(); | ||
190 | } | ||
191 | } | ||
192 | } | ||
193 | else | ||
194 | { | ||
195 | if (m_scriptsLock.RecursiveWriteCount > 0) | ||
196 | { | ||
197 | m_scriptsLock.ExitWriteLock(); | ||
198 | } | ||
199 | } | ||
200 | } | ||
201 | |||
134 | public string ScriptEngineName | 202 | public string ScriptEngineName |
135 | { | 203 | { |
136 | get { return "XEngine"; } | 204 | get { return "XEngine"; } |
@@ -501,44 +569,37 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
501 | { | 569 | { |
502 | if (!m_Enabled) | 570 | if (!m_Enabled) |
503 | return; | 571 | return; |
504 | 572 | lockScriptsForRead(true); | |
505 | lock (m_Scripts) | 573 | foreach (IScriptInstance instance in m_Scripts.Values) |
506 | { | 574 | { |
507 | m_log.InfoFormat( | 575 | // Force a final state save |
508 | "[XEngine]: Shutting down {0} scripts in {1}", m_Scripts.Count, m_Scene.RegionInfo.RegionName); | 576 | // |
509 | 577 | if (m_Assemblies.ContainsKey(instance.AssetID)) | |
510 | foreach (IScriptInstance instance in m_Scripts.Values) | ||
511 | { | 578 | { |
512 | // Force a final state save | 579 | string assembly = m_Assemblies[instance.AssetID]; |
513 | // | 580 | instance.SaveState(assembly); |
514 | if (m_Assemblies.ContainsKey(instance.AssetID)) | 581 | } |
515 | { | ||
516 | string assembly = m_Assemblies[instance.AssetID]; | ||
517 | instance.SaveState(assembly); | ||
518 | } | ||
519 | 582 | ||
520 | // Clear the event queue and abort the instance thread | 583 | // Clear the event queue and abort the instance thread |
521 | // | 584 | // |
522 | instance.ClearQueue(); | 585 | instance.ClearQueue(); |
523 | instance.Stop(0); | 586 | instance.Stop(0); |
524 | 587 | ||
525 | // Release events, timer, etc | 588 | // Release events, timer, etc |
526 | // | 589 | // |
527 | instance.DestroyScriptInstance(); | 590 | instance.DestroyScriptInstance(); |
528 | 591 | ||
529 | // Unload scripts and app domains. | 592 | // Unload scripts and app domains |
530 | // Must be done explicitly because they have infinite | 593 | // Must be done explicitly because they have infinite |
531 | // lifetime. | 594 | // lifetime |
532 | // However, don't bother to do this if the simulator is shutting | 595 | // |
533 | // down since it takes a long time with many scripts. | 596 | if (!m_SimulatorShuttingDown) |
534 | if (!m_SimulatorShuttingDown) | 597 | { |
598 | m_DomainScripts[instance.AppDomain].Remove(instance.ItemID); | ||
599 | if (m_DomainScripts[instance.AppDomain].Count == 0) | ||
535 | { | 600 | { |
536 | m_DomainScripts[instance.AppDomain].Remove(instance.ItemID); | 601 | m_DomainScripts.Remove(instance.AppDomain); |
537 | if (m_DomainScripts[instance.AppDomain].Count == 0) | 602 | UnloadAppDomain(instance.AppDomain); |
538 | { | ||
539 | m_DomainScripts.Remove(instance.AppDomain); | ||
540 | UnloadAppDomain(instance.AppDomain); | ||
541 | } | ||
542 | } | 603 | } |
543 | } | 604 | } |
544 | 605 | ||
@@ -547,6 +608,14 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
547 | m_Assemblies.Clear(); | 608 | m_Assemblies.Clear(); |
548 | m_DomainScripts.Clear(); | 609 | m_DomainScripts.Clear(); |
549 | } | 610 | } |
611 | lockScriptsForRead(false); | ||
612 | lockScriptsForWrite(true); | ||
613 | m_Scripts.Clear(); | ||
614 | lockScriptsForWrite(false); | ||
615 | m_PrimObjects.Clear(); | ||
616 | m_Assemblies.Clear(); | ||
617 | m_DomainScripts.Clear(); | ||
618 | |||
550 | lock (m_ScriptEngines) | 619 | lock (m_ScriptEngines) |
551 | { | 620 | { |
552 | m_ScriptEngines.Remove(this); | 621 | m_ScriptEngines.Remove(this); |
@@ -611,22 +680,20 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
611 | 680 | ||
612 | List<IScriptInstance> instances = new List<IScriptInstance>(); | 681 | List<IScriptInstance> instances = new List<IScriptInstance>(); |
613 | 682 | ||
614 | lock (m_Scripts) | 683 | lockScriptsForRead(true); |
615 | { | 684 | foreach (IScriptInstance instance in m_Scripts.Values) |
616 | foreach (IScriptInstance instance in m_Scripts.Values) | ||
617 | instances.Add(instance); | 685 | instances.Add(instance); |
618 | } | 686 | lockScriptsForRead(false); |
619 | 687 | ||
620 | foreach (IScriptInstance i in instances) | 688 | foreach (IScriptInstance i in instances) |
621 | { | 689 | { |
622 | string assembly = String.Empty; | 690 | string assembly = String.Empty; |
623 | 691 | ||
624 | lock (m_Scripts) | 692 | |
625 | { | ||
626 | if (!m_Assemblies.ContainsKey(i.AssetID)) | 693 | if (!m_Assemblies.ContainsKey(i.AssetID)) |
627 | continue; | 694 | continue; |
628 | assembly = m_Assemblies[i.AssetID]; | 695 | assembly = m_Assemblies[i.AssetID]; |
629 | } | 696 | |
630 | 697 | ||
631 | i.SaveState(assembly); | 698 | i.SaveState(assembly); |
632 | } | 699 | } |
@@ -970,92 +1037,95 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
970 | } | 1037 | } |
971 | 1038 | ||
972 | ScriptInstance instance = null; | 1039 | ScriptInstance instance = null; |
973 | lock (m_Scripts) | 1040 | // Create the object record |
1041 | lockScriptsForRead(true); | ||
1042 | if ((!m_Scripts.ContainsKey(itemID)) || | ||
1043 | (m_Scripts[itemID].AssetID != assetID)) | ||
974 | { | 1044 | { |
975 | // Create the object record | 1045 | lockScriptsForRead(false); |
976 | 1046 | ||
977 | if ((!m_Scripts.ContainsKey(itemID)) || | 1047 | UUID appDomain = assetID; |
978 | (m_Scripts[itemID].AssetID != assetID)) | ||
979 | { | ||
980 | UUID appDomain = assetID; | ||
981 | 1048 | ||
982 | if (part.ParentGroup.IsAttachment) | 1049 | if (part.ParentGroup.IsAttachment) |
983 | appDomain = part.ParentGroup.RootPart.UUID; | 1050 | appDomain = part.ParentGroup.RootPart.UUID; |
984 | 1051 | ||
985 | if (!m_AppDomains.ContainsKey(appDomain)) | 1052 | if (!m_AppDomains.ContainsKey(appDomain)) |
1053 | { | ||
1054 | try | ||
986 | { | 1055 | { |
987 | try | 1056 | AppDomainSetup appSetup = new AppDomainSetup(); |
988 | { | 1057 | appSetup.PrivateBinPath = Path.Combine( |
989 | AppDomainSetup appSetup = new AppDomainSetup(); | 1058 | m_ScriptEnginesPath, |
990 | appSetup.PrivateBinPath = Path.Combine( | 1059 | m_Scene.RegionInfo.RegionID.ToString()); |
991 | m_ScriptEnginesPath, | 1060 | |
992 | m_Scene.RegionInfo.RegionID.ToString()); | 1061 | Evidence baseEvidence = AppDomain.CurrentDomain.Evidence; |
993 | 1062 | Evidence evidence = new Evidence(baseEvidence); | |
994 | Evidence baseEvidence = AppDomain.CurrentDomain.Evidence; | 1063 | |
995 | Evidence evidence = new Evidence(baseEvidence); | 1064 | AppDomain sandbox; |
996 | 1065 | if (m_AppDomainLoading) | |
997 | AppDomain sandbox; | 1066 | sandbox = AppDomain.CreateDomain( |
998 | if (m_AppDomainLoading) | 1067 | m_Scene.RegionInfo.RegionID.ToString(), |
999 | sandbox = AppDomain.CreateDomain( | 1068 | evidence, appSetup); |
1000 | m_Scene.RegionInfo.RegionID.ToString(), | 1069 | else |
1001 | evidence, appSetup); | 1070 | sandbox = AppDomain.CurrentDomain; |
1002 | else | 1071 | |
1003 | sandbox = AppDomain.CurrentDomain; | 1072 | //PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel(); |
1004 | 1073 | //AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition(); | |
1005 | //PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel(); | 1074 | //PermissionSet sandboxPermissionSet = sandboxPolicy.GetNamedPermissionSet("Internet"); |
1006 | //AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition(); | 1075 | //PolicyStatement sandboxPolicyStatement = new PolicyStatement(sandboxPermissionSet); |
1007 | //PermissionSet sandboxPermissionSet = sandboxPolicy.GetNamedPermissionSet("Internet"); | 1076 | //CodeGroup sandboxCodeGroup = new UnionCodeGroup(sandboxMembershipCondition, sandboxPolicyStatement); |
1008 | //PolicyStatement sandboxPolicyStatement = new PolicyStatement(sandboxPermissionSet); | 1077 | //sandboxPolicy.RootCodeGroup = sandboxCodeGroup; |
1009 | //CodeGroup sandboxCodeGroup = new UnionCodeGroup(sandboxMembershipCondition, sandboxPolicyStatement); | 1078 | //sandbox.SetAppDomainPolicy(sandboxPolicy); |
1010 | //sandboxPolicy.RootCodeGroup = sandboxCodeGroup; | 1079 | |
1011 | //sandbox.SetAppDomainPolicy(sandboxPolicy); | 1080 | m_AppDomains[appDomain] = sandbox; |
1012 | 1081 | ||
1013 | m_AppDomains[appDomain] = sandbox; | 1082 | m_AppDomains[appDomain].AssemblyResolve += |
1014 | 1083 | new ResolveEventHandler( | |
1015 | m_AppDomains[appDomain].AssemblyResolve += | 1084 | AssemblyResolver.OnAssemblyResolve); |
1016 | new ResolveEventHandler( | 1085 | m_DomainScripts[appDomain] = new List<UUID>(); |
1017 | AssemblyResolver.OnAssemblyResolve); | 1086 | } |
1018 | m_DomainScripts[appDomain] = new List<UUID>(); | 1087 | catch (Exception e) |
1019 | } | 1088 | { |
1020 | catch (Exception e) | 1089 | m_log.ErrorFormat("[XEngine] Exception creating app domain:\n {0}", e.ToString()); |
1090 | m_ScriptErrorMessage += "Exception creating app domain:\n"; | ||
1091 | m_ScriptFailCount++; | ||
1092 | lock (m_AddingAssemblies) | ||
1021 | { | 1093 | { |
1022 | m_log.ErrorFormat("[XEngine] Exception creating app domain:\n {0}", e.ToString()); | 1094 | m_AddingAssemblies[assembly]--; |
1023 | m_ScriptErrorMessage += "Exception creating app domain:\n"; | ||
1024 | m_ScriptFailCount++; | ||
1025 | lock (m_AddingAssemblies) | ||
1026 | { | ||
1027 | m_AddingAssemblies[assembly]--; | ||
1028 | } | ||
1029 | return false; | ||
1030 | } | 1095 | } |
1096 | return false; | ||
1031 | } | 1097 | } |
1032 | m_DomainScripts[appDomain].Add(itemID); | 1098 | } |
1033 | 1099 | m_DomainScripts[appDomain].Add(itemID); | |
1034 | instance = new ScriptInstance(this, part, | 1100 | |
1035 | itemID, assetID, assembly, | 1101 | instance = new ScriptInstance(this, part, |
1036 | m_AppDomains[appDomain], | 1102 | itemID, assetID, assembly, |
1037 | part.ParentGroup.RootPart.Name, | 1103 | m_AppDomains[appDomain], |
1038 | item.Name, startParam, postOnRez, | 1104 | part.ParentGroup.RootPart.Name, |
1039 | stateSource, m_MaxScriptQueue); | 1105 | item.Name, startParam, postOnRez, |
1040 | 1106 | stateSource, m_MaxScriptQueue); | |
1041 | m_log.DebugFormat( | 1107 | |
1042 | "[XEngine] Loaded script {0}.{1}, item UUID {2}, prim UUID {3} @ {4}.{5}", | 1108 | m_log.DebugFormat( |
1043 | part.ParentGroup.RootPart.Name, item.Name, itemID, part.UUID, | 1109 | "[XEngine] Loaded script {0}.{1}, script UUID {2}, prim UUID {3} @ {4}.{5}", |
1110 | part.ParentGroup.RootPart.Name, item.Name, assetID, part.UUID, | ||
1044 | part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName); | 1111 | part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName); |
1045 | 1112 | ||
1046 | if (presence != null) | 1113 | if (presence != null) |
1047 | { | 1114 | { |
1048 | ShowScriptSaveResponse(item.OwnerID, | 1115 | ShowScriptSaveResponse(item.OwnerID, |
1049 | assetID, "Compile successful", true); | 1116 | assetID, "Compile successful", true); |
1050 | } | ||
1051 | |||
1052 | instance.AppDomain = appDomain; | ||
1053 | instance.LineMap = linemap; | ||
1054 | |||
1055 | m_Scripts[itemID] = instance; | ||
1056 | } | 1117 | } |
1057 | } | ||
1058 | 1118 | ||
1119 | instance.AppDomain = appDomain; | ||
1120 | instance.LineMap = linemap; | ||
1121 | lockScriptsForWrite(true); | ||
1122 | m_Scripts[itemID] = instance; | ||
1123 | lockScriptsForWrite(false); | ||
1124 | } | ||
1125 | else | ||
1126 | { | ||
1127 | lockScriptsForRead(false); | ||
1128 | } | ||
1059 | lock (m_PrimObjects) | 1129 | lock (m_PrimObjects) |
1060 | { | 1130 | { |
1061 | if (!m_PrimObjects.ContainsKey(localID)) | 1131 | if (!m_PrimObjects.ContainsKey(localID)) |
@@ -1074,9 +1144,9 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1074 | m_AddingAssemblies[assembly]--; | 1144 | m_AddingAssemblies[assembly]--; |
1075 | } | 1145 | } |
1076 | 1146 | ||
1077 | if (instance != null) | 1147 | if (instance!=null) |
1078 | instance.Init(); | 1148 | instance.Init(); |
1079 | 1149 | ||
1080 | return true; | 1150 | return true; |
1081 | } | 1151 | } |
1082 | 1152 | ||
@@ -1089,20 +1159,31 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1089 | m_CompileDict.Remove(itemID); | 1159 | m_CompileDict.Remove(itemID); |
1090 | } | 1160 | } |
1091 | 1161 | ||
1092 | IScriptInstance instance = null; | 1162 | lockScriptsForRead(true); |
1093 | 1163 | // Do we even have it? | |
1094 | lock (m_Scripts) | 1164 | if (!m_Scripts.ContainsKey(itemID)) |
1095 | { | 1165 | { |
1096 | // Do we even have it? | 1166 | // Do we even have it? |
1097 | if (!m_Scripts.ContainsKey(itemID)) | 1167 | if (!m_Scripts.ContainsKey(itemID)) |
1098 | return; | 1168 | return; |
1099 | 1169 | ||
1100 | instance = m_Scripts[itemID]; | 1170 | lockScriptsForRead(false); |
1171 | lockScriptsForWrite(true); | ||
1101 | m_Scripts.Remove(itemID); | 1172 | m_Scripts.Remove(itemID); |
1173 | lockScriptsForWrite(false); | ||
1174 | |||
1175 | return; | ||
1102 | } | 1176 | } |
1177 | |||
1103 | 1178 | ||
1179 | IScriptInstance instance=m_Scripts[itemID]; | ||
1180 | lockScriptsForRead(false); | ||
1181 | lockScriptsForWrite(true); | ||
1182 | m_Scripts.Remove(itemID); | ||
1183 | lockScriptsForWrite(false); | ||
1104 | instance.ClearQueue(); | 1184 | instance.ClearQueue(); |
1105 | instance.Stop(0); | 1185 | instance.Stop(0); |
1186 | |||
1106 | // bool objectRemoved = false; | 1187 | // bool objectRemoved = false; |
1107 | 1188 | ||
1108 | lock (m_PrimObjects) | 1189 | lock (m_PrimObjects) |
@@ -1138,10 +1219,12 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1138 | ObjectRemoved handlerObjectRemoved = OnObjectRemoved; | 1219 | ObjectRemoved handlerObjectRemoved = OnObjectRemoved; |
1139 | if (handlerObjectRemoved != null) | 1220 | if (handlerObjectRemoved != null) |
1140 | { | 1221 | { |
1141 | SceneObjectPart part = m_Scene.GetSceneObjectPart(localID); | 1222 | SceneObjectPart part = m_Scene.GetSceneObjectPart(localID); |
1142 | handlerObjectRemoved(part.UUID); | 1223 | handlerObjectRemoved(part.UUID); |
1143 | } | 1224 | } |
1144 | 1225 | ||
1226 | CleanAssemblies(); | ||
1227 | |||
1145 | ScriptRemoved handlerScriptRemoved = OnScriptRemoved; | 1228 | ScriptRemoved handlerScriptRemoved = OnScriptRemoved; |
1146 | if (handlerScriptRemoved != null) | 1229 | if (handlerScriptRemoved != null) |
1147 | handlerScriptRemoved(itemID); | 1230 | handlerScriptRemoved(itemID); |
@@ -1283,7 +1366,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1283 | return false; | 1366 | return false; |
1284 | 1367 | ||
1285 | uuids = m_PrimObjects[localID]; | 1368 | uuids = m_PrimObjects[localID]; |
1286 | } | 1369 | |
1287 | 1370 | ||
1288 | foreach (UUID itemID in uuids) | 1371 | foreach (UUID itemID in uuids) |
1289 | { | 1372 | { |
@@ -1301,6 +1384,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1301 | result = true; | 1384 | result = true; |
1302 | } | 1385 | } |
1303 | } | 1386 | } |
1387 | } | ||
1304 | 1388 | ||
1305 | return result; | 1389 | return result; |
1306 | } | 1390 | } |
@@ -1402,12 +1486,14 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1402 | private IScriptInstance GetInstance(UUID itemID) | 1486 | private IScriptInstance GetInstance(UUID itemID) |
1403 | { | 1487 | { |
1404 | IScriptInstance instance; | 1488 | IScriptInstance instance; |
1405 | lock (m_Scripts) | 1489 | lockScriptsForRead(true); |
1490 | if (!m_Scripts.ContainsKey(itemID)) | ||
1406 | { | 1491 | { |
1407 | if (!m_Scripts.ContainsKey(itemID)) | 1492 | lockScriptsForRead(false); |
1408 | return null; | 1493 | return null; |
1409 | instance = m_Scripts[itemID]; | ||
1410 | } | 1494 | } |
1495 | instance = m_Scripts[itemID]; | ||
1496 | lockScriptsForRead(false); | ||
1411 | return instance; | 1497 | return instance; |
1412 | } | 1498 | } |
1413 | 1499 | ||
@@ -1431,6 +1517,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1431 | return false; | 1517 | return false; |
1432 | } | 1518 | } |
1433 | 1519 | ||
1520 | [DebuggerNonUserCode] | ||
1434 | public void ApiResetScript(UUID itemID) | 1521 | public void ApiResetScript(UUID itemID) |
1435 | { | 1522 | { |
1436 | IScriptInstance instance = GetInstance(itemID); | 1523 | IScriptInstance instance = GetInstance(itemID); |
@@ -1482,6 +1569,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1482 | return UUID.Zero; | 1569 | return UUID.Zero; |
1483 | } | 1570 | } |
1484 | 1571 | ||
1572 | [DebuggerNonUserCode] | ||
1485 | public void SetState(UUID itemID, string newState) | 1573 | public void SetState(UUID itemID, string newState) |
1486 | { | 1574 | { |
1487 | IScriptInstance instance = GetInstance(itemID); | 1575 | IScriptInstance instance = GetInstance(itemID); |
@@ -1504,11 +1592,10 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1504 | 1592 | ||
1505 | List<IScriptInstance> instances = new List<IScriptInstance>(); | 1593 | List<IScriptInstance> instances = new List<IScriptInstance>(); |
1506 | 1594 | ||
1507 | lock (m_Scripts) | 1595 | lockScriptsForRead(true); |
1508 | { | 1596 | foreach (IScriptInstance instance in m_Scripts.Values) |
1509 | foreach (IScriptInstance instance in m_Scripts.Values) | ||
1510 | instances.Add(instance); | 1597 | instances.Add(instance); |
1511 | } | 1598 | lockScriptsForRead(false); |
1512 | 1599 | ||
1513 | foreach (IScriptInstance i in instances) | 1600 | foreach (IScriptInstance i in instances) |
1514 | { | 1601 | { |
@@ -1893,5 +1980,17 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1893 | // else | 1980 | // else |
1894 | // m_log.DebugFormat("[XEngine]: Could not find script with ID {0} to resume", itemID); | 1981 | // m_log.DebugFormat("[XEngine]: Could not find script with ID {0} to resume", itemID); |
1895 | } | 1982 | } |
1983 | |||
1984 | public bool HasScript(UUID itemID, out bool running) | ||
1985 | { | ||
1986 | running = true; | ||
1987 | |||
1988 | IScriptInstance instance = GetInstance(itemID); | ||
1989 | if (instance == null) | ||
1990 | return false; | ||
1991 | |||
1992 | running = instance.Running; | ||
1993 | return true; | ||
1994 | } | ||
1896 | } | 1995 | } |
1897 | } \ No newline at end of file | 1996 | } |