diff options
Diffstat (limited to '')
-rw-r--r-- | OpenSim/Region/ScriptEngine/XEngine/XEngine.cs | 363 |
1 files changed, 224 insertions, 139 deletions
diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs index 8931be4..17243ab 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.Linq; | 34 | using System.Linq; |
@@ -148,6 +149,8 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
148 | private Dictionary<UUID, IScriptInstance> m_Scripts = | 149 | private Dictionary<UUID, IScriptInstance> m_Scripts = |
149 | new Dictionary<UUID, IScriptInstance>(); | 150 | new Dictionary<UUID, IScriptInstance>(); |
150 | 151 | ||
152 | private OpenMetaverse.ReaderWriterLockSlim m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim(); | ||
153 | |||
151 | // Maps the asset ID to the assembly | 154 | // Maps the asset ID to the assembly |
152 | 155 | ||
153 | private Dictionary<UUID, string> m_Assemblies = | 156 | private Dictionary<UUID, string> m_Assemblies = |
@@ -170,6 +173,71 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
170 | IWorkItemResult m_CurrentCompile = null; | 173 | IWorkItemResult m_CurrentCompile = null; |
171 | private Dictionary<UUID, int> m_CompileDict = new Dictionary<UUID, int>(); | 174 | private Dictionary<UUID, int> m_CompileDict = new Dictionary<UUID, int>(); |
172 | 175 | ||
176 | private void lockScriptsForRead(bool locked) | ||
177 | { | ||
178 | if (locked) | ||
179 | { | ||
180 | if (m_scriptsLock.RecursiveReadCount > 0) | ||
181 | { | ||
182 | 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."); | ||
183 | m_scriptsLock.ExitReadLock(); | ||
184 | } | ||
185 | if (m_scriptsLock.RecursiveWriteCount > 0) | ||
186 | { | ||
187 | m_log.Error("[XEngine.m_Scripts] Recursive write lock requested. This should not happen and means something needs to be fixed."); | ||
188 | m_scriptsLock.ExitWriteLock(); | ||
189 | } | ||
190 | |||
191 | while (!m_scriptsLock.TryEnterReadLock(60000)) | ||
192 | { | ||
193 | 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."); | ||
194 | if (m_scriptsLock.IsWriteLockHeld) | ||
195 | { | ||
196 | m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim(); | ||
197 | } | ||
198 | } | ||
199 | } | ||
200 | else | ||
201 | { | ||
202 | if (m_scriptsLock.RecursiveReadCount > 0) | ||
203 | { | ||
204 | m_scriptsLock.ExitReadLock(); | ||
205 | } | ||
206 | } | ||
207 | } | ||
208 | private void lockScriptsForWrite(bool locked) | ||
209 | { | ||
210 | if (locked) | ||
211 | { | ||
212 | if (m_scriptsLock.RecursiveReadCount > 0) | ||
213 | { | ||
214 | 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."); | ||
215 | m_scriptsLock.ExitReadLock(); | ||
216 | } | ||
217 | if (m_scriptsLock.RecursiveWriteCount > 0) | ||
218 | { | ||
219 | m_log.Error("[XEngine.m_Scripts] Recursive write lock requested. This should not happen and means something needs to be fixed."); | ||
220 | m_scriptsLock.ExitWriteLock(); | ||
221 | } | ||
222 | |||
223 | while (!m_scriptsLock.TryEnterWriteLock(60000)) | ||
224 | { | ||
225 | 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."); | ||
226 | if (m_scriptsLock.IsWriteLockHeld) | ||
227 | { | ||
228 | m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim(); | ||
229 | } | ||
230 | } | ||
231 | } | ||
232 | else | ||
233 | { | ||
234 | if (m_scriptsLock.RecursiveWriteCount > 0) | ||
235 | { | ||
236 | m_scriptsLock.ExitWriteLock(); | ||
237 | } | ||
238 | } | ||
239 | } | ||
240 | |||
173 | private ScriptEngineConsoleCommands m_consoleCommands; | 241 | private ScriptEngineConsoleCommands m_consoleCommands; |
174 | 242 | ||
175 | public string ScriptEngineName | 243 | public string ScriptEngineName |
@@ -699,64 +767,69 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
699 | { | 767 | { |
700 | if (!m_Enabled) | 768 | if (!m_Enabled) |
701 | return; | 769 | return; |
770 | lockScriptsForRead(true); | ||
702 | 771 | ||
703 | lock (m_Scripts) | 772 | List<IScriptInstance> instancesToDel = new List<IScriptInstance>(m_Scripts.Values); |
704 | { | ||
705 | m_log.InfoFormat( | ||
706 | "[XEngine]: Shutting down {0} scripts in {1}", m_Scripts.Count, m_Scene.RegionInfo.RegionName); | ||
707 | 773 | ||
708 | foreach (IScriptInstance instance in m_Scripts.Values) | 774 | // foreach (IScriptInstance instance in m_Scripts.Values) |
775 | foreach (IScriptInstance instance in instancesToDel) | ||
776 | { | ||
777 | // Force a final state save | ||
778 | // | ||
779 | if (m_Assemblies.ContainsKey(instance.AssetID)) | ||
709 | { | 780 | { |
710 | // Force a final state save | 781 | string assembly = m_Assemblies[instance.AssetID]; |
711 | // | ||
712 | if (m_Assemblies.ContainsKey(instance.AssetID)) | ||
713 | { | ||
714 | string assembly = m_Assemblies[instance.AssetID]; | ||
715 | 782 | ||
716 | try | 783 | try |
717 | { | 784 | { |
718 | instance.SaveState(assembly); | 785 | instance.SaveState(assembly); |
719 | } | ||
720 | catch (Exception e) | ||
721 | { | ||
722 | m_log.Error( | ||
723 | string.Format( | ||
724 | "[XEngine]: Failed final state save for script {0}.{1}, item UUID {2}, prim UUID {3} in {4}. Exception ", | ||
725 | instance.PrimName, instance.ScriptName, instance.ItemID, instance.ObjectID, World.Name) | ||
726 | , e); | ||
727 | } | ||
728 | } | 786 | } |
787 | catch (Exception e) | ||
788 | { | ||
789 | m_log.Error( | ||
790 | string.Format( | ||
791 | "[XEngine]: Failed final state save for script {0}.{1}, item UUID {2}, prim UUID {3} in {4}. Exception ", | ||
792 | instance.PrimName, instance.ScriptName, instance.ItemID, instance.ObjectID, World.Name) | ||
793 | , e); | ||
794 | } | ||
795 | } | ||
729 | 796 | ||
730 | // Clear the event queue and abort the instance thread | 797 | // Clear the event queue and abort the instance thread |
731 | // | 798 | // |
732 | instance.ClearQueue(); | 799 | instance.ClearQueue(); |
733 | instance.Stop(0); | 800 | instance.Stop(0); |
734 | 801 | ||
735 | // Release events, timer, etc | 802 | // Release events, timer, etc |
736 | // | 803 | // |
737 | instance.DestroyScriptInstance(); | 804 | instance.DestroyScriptInstance(); |
738 | 805 | ||
739 | // Unload scripts and app domains. | 806 | // Unload scripts and app domains |
740 | // Must be done explicitly because they have infinite | 807 | // Must be done explicitly because they have infinite |
741 | // lifetime. | 808 | // lifetime |
742 | // However, don't bother to do this if the simulator is shutting | 809 | // |
743 | // down since it takes a long time with many scripts. | 810 | // if (!m_SimulatorShuttingDown) |
744 | if (!m_SimulatorShuttingDown) | 811 | { |
812 | m_DomainScripts[instance.AppDomain].Remove(instance.ItemID); | ||
813 | if (m_DomainScripts[instance.AppDomain].Count == 0) | ||
745 | { | 814 | { |
746 | m_DomainScripts[instance.AppDomain].Remove(instance.ItemID); | 815 | m_DomainScripts.Remove(instance.AppDomain); |
747 | if (m_DomainScripts[instance.AppDomain].Count == 0) | 816 | UnloadAppDomain(instance.AppDomain); |
748 | { | ||
749 | m_DomainScripts.Remove(instance.AppDomain); | ||
750 | UnloadAppDomain(instance.AppDomain); | ||
751 | } | ||
752 | } | 817 | } |
753 | } | 818 | } |
754 | 819 | ||
755 | m_Scripts.Clear(); | 820 | // m_Scripts.Clear(); |
756 | m_PrimObjects.Clear(); | 821 | // m_PrimObjects.Clear(); |
757 | m_Assemblies.Clear(); | 822 | // m_Assemblies.Clear(); |
758 | m_DomainScripts.Clear(); | 823 | // m_DomainScripts.Clear(); |
759 | } | 824 | } |
825 | lockScriptsForRead(false); | ||
826 | lockScriptsForWrite(true); | ||
827 | m_Scripts.Clear(); | ||
828 | lockScriptsForWrite(false); | ||
829 | m_PrimObjects.Clear(); | ||
830 | m_Assemblies.Clear(); | ||
831 | m_DomainScripts.Clear(); | ||
832 | |||
760 | lock (m_ScriptEngines) | 833 | lock (m_ScriptEngines) |
761 | { | 834 | { |
762 | m_ScriptEngines.Remove(this); | 835 | m_ScriptEngines.Remove(this); |
@@ -825,22 +898,20 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
825 | 898 | ||
826 | List<IScriptInstance> instances = new List<IScriptInstance>(); | 899 | List<IScriptInstance> instances = new List<IScriptInstance>(); |
827 | 900 | ||
828 | lock (m_Scripts) | 901 | lockScriptsForRead(true); |
829 | { | 902 | foreach (IScriptInstance instance in m_Scripts.Values) |
830 | foreach (IScriptInstance instance in m_Scripts.Values) | ||
831 | instances.Add(instance); | 903 | instances.Add(instance); |
832 | } | 904 | lockScriptsForRead(false); |
833 | 905 | ||
834 | foreach (IScriptInstance i in instances) | 906 | foreach (IScriptInstance i in instances) |
835 | { | 907 | { |
836 | string assembly = String.Empty; | 908 | string assembly = String.Empty; |
837 | 909 | ||
838 | lock (m_Scripts) | 910 | |
839 | { | ||
840 | if (!m_Assemblies.ContainsKey(i.AssetID)) | 911 | if (!m_Assemblies.ContainsKey(i.AssetID)) |
841 | continue; | 912 | continue; |
842 | assembly = m_Assemblies[i.AssetID]; | 913 | assembly = m_Assemblies[i.AssetID]; |
843 | } | 914 | |
844 | 915 | ||
845 | try | 916 | try |
846 | { | 917 | { |
@@ -1244,97 +1315,93 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1244 | } | 1315 | } |
1245 | 1316 | ||
1246 | ScriptInstance instance = null; | 1317 | ScriptInstance instance = null; |
1247 | lock (m_Scripts) | 1318 | // Create the object record |
1319 | lockScriptsForRead(true); | ||
1320 | if ((!m_Scripts.ContainsKey(itemID)) || | ||
1321 | (m_Scripts[itemID].AssetID != assetID)) | ||
1248 | { | 1322 | { |
1249 | // Create the object record | 1323 | lockScriptsForRead(false); |
1250 | if ((!m_Scripts.ContainsKey(itemID)) || | ||
1251 | (m_Scripts[itemID].AssetID != assetID)) | ||
1252 | { | ||
1253 | UUID appDomain = assetID; | ||
1254 | 1324 | ||
1255 | if (part.ParentGroup.IsAttachment) | 1325 | UUID appDomain = assetID; |
1256 | appDomain = part.ParentGroup.RootPart.UUID; | ||
1257 | 1326 | ||
1258 | if (!m_AppDomains.ContainsKey(appDomain)) | 1327 | if (part.ParentGroup.IsAttachment) |
1259 | { | 1328 | appDomain = part.ParentGroup.RootPart.UUID; |
1260 | try | ||
1261 | { | ||
1262 | AppDomainSetup appSetup = new AppDomainSetup(); | ||
1263 | appSetup.PrivateBinPath = Path.Combine( | ||
1264 | m_ScriptEnginesPath, | ||
1265 | m_Scene.RegionInfo.RegionID.ToString()); | ||
1266 | 1329 | ||
1267 | Evidence baseEvidence = AppDomain.CurrentDomain.Evidence; | 1330 | if (!m_AppDomains.ContainsKey(appDomain)) |
1268 | Evidence evidence = new Evidence(baseEvidence); | 1331 | { |
1332 | try | ||
1333 | { | ||
1334 | AppDomainSetup appSetup = new AppDomainSetup(); | ||
1335 | appSetup.PrivateBinPath = Path.Combine( | ||
1336 | m_ScriptEnginesPath, | ||
1337 | m_Scene.RegionInfo.RegionID.ToString()); | ||
1269 | 1338 | ||
1270 | AppDomain sandbox; | 1339 | Evidence baseEvidence = AppDomain.CurrentDomain.Evidence; |
1271 | if (m_AppDomainLoading) | 1340 | Evidence evidence = new Evidence(baseEvidence); |
1272 | { | ||
1273 | sandbox = AppDomain.CreateDomain( | ||
1274 | m_Scene.RegionInfo.RegionID.ToString(), | ||
1275 | evidence, appSetup); | ||
1276 | sandbox.AssemblyResolve += | ||
1277 | new ResolveEventHandler( | ||
1278 | AssemblyResolver.OnAssemblyResolve); | ||
1279 | } | ||
1280 | else | ||
1281 | { | ||
1282 | sandbox = AppDomain.CurrentDomain; | ||
1283 | } | ||
1284 | |||
1285 | //PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel(); | ||
1286 | //AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition(); | ||
1287 | //PermissionSet sandboxPermissionSet = sandboxPolicy.GetNamedPermissionSet("Internet"); | ||
1288 | //PolicyStatement sandboxPolicyStatement = new PolicyStatement(sandboxPermissionSet); | ||
1289 | //CodeGroup sandboxCodeGroup = new UnionCodeGroup(sandboxMembershipCondition, sandboxPolicyStatement); | ||
1290 | //sandboxPolicy.RootCodeGroup = sandboxCodeGroup; | ||
1291 | //sandbox.SetAppDomainPolicy(sandboxPolicy); | ||
1292 | |||
1293 | m_AppDomains[appDomain] = sandbox; | ||
1294 | 1341 | ||
1295 | m_DomainScripts[appDomain] = new List<UUID>(); | 1342 | AppDomain sandbox; |
1343 | if (m_AppDomainLoading) | ||
1344 | { | ||
1345 | sandbox = AppDomain.CreateDomain( | ||
1346 | m_Scene.RegionInfo.RegionID.ToString(), | ||
1347 | evidence, appSetup); | ||
1348 | m_AppDomains[appDomain].AssemblyResolve += | ||
1349 | new ResolveEventHandler( | ||
1350 | AssemblyResolver.OnAssemblyResolve); | ||
1296 | } | 1351 | } |
1297 | catch (Exception e) | 1352 | else |
1298 | { | 1353 | { |
1299 | m_log.ErrorFormat("[XEngine] Exception creating app domain:\n {0}", e.ToString()); | 1354 | sandbox = AppDomain.CurrentDomain; |
1300 | m_ScriptErrorMessage += "Exception creating app domain:\n"; | ||
1301 | m_ScriptFailCount++; | ||
1302 | lock (m_AddingAssemblies) | ||
1303 | { | ||
1304 | m_AddingAssemblies[assembly]--; | ||
1305 | } | ||
1306 | return false; | ||
1307 | } | 1355 | } |
1308 | } | ||
1309 | m_DomainScripts[appDomain].Add(itemID); | ||
1310 | |||
1311 | instance = new ScriptInstance(this, part, | ||
1312 | item, | ||
1313 | startParam, postOnRez, | ||
1314 | m_MaxScriptQueue); | ||
1315 | 1356 | ||
1316 | if (!instance.Load(m_AppDomains[appDomain], assembly, stateSource)) | 1357 | if (!instance.Load(m_AppDomains[appDomain], assembly, stateSource)) |
1317 | return false; | 1358 | return false; |
1318 | 1359 | ||
1319 | // if (DebugLevel >= 1) | 1360 | m_AppDomains[appDomain] = sandbox; |
1320 | // m_log.DebugFormat( | ||
1321 | // "[XEngine] Loaded script {0}.{1}, item UUID {2}, prim UUID {3} @ {4}.{5}", | ||
1322 | // part.ParentGroup.RootPart.Name, item.Name, itemID, part.UUID, | ||
1323 | // part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName); | ||
1324 | 1361 | ||
1325 | if (presence != null) | 1362 | m_DomainScripts[appDomain] = new List<UUID>(); |
1363 | } | ||
1364 | catch (Exception e) | ||
1326 | { | 1365 | { |
1327 | ShowScriptSaveResponse(item.OwnerID, | 1366 | m_log.ErrorFormat("[XEngine] Exception creating app domain:\n {0}", e.ToString()); |
1328 | assetID, "Compile successful", true); | 1367 | m_ScriptErrorMessage += "Exception creating app domain:\n"; |
1368 | m_ScriptFailCount++; | ||
1369 | lock (m_AddingAssemblies) | ||
1370 | { | ||
1371 | m_AddingAssemblies[assembly]--; | ||
1372 | } | ||
1373 | return false; | ||
1329 | } | 1374 | } |
1375 | } | ||
1376 | m_DomainScripts[appDomain].Add(itemID); | ||
1377 | |||
1378 | instance = new ScriptInstance(this, part, | ||
1379 | item, | ||
1380 | startParam, postOnRez, | ||
1381 | m_MaxScriptQueue); | ||
1330 | 1382 | ||
1331 | instance.AppDomain = appDomain; | 1383 | instance.Load(m_AppDomains[appDomain], assembly, stateSource); |
1332 | instance.LineMap = linemap; | 1384 | // m_log.DebugFormat( |
1385 | // "[XEngine] Loaded script {0}.{1}, script UUID {2}, prim UUID {3} @ {4}.{5}", | ||
1386 | // part.ParentGroup.RootPart.Name, item.Name, assetID, part.UUID, | ||
1387 | // part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName); | ||
1333 | 1388 | ||
1334 | m_Scripts[itemID] = instance; | 1389 | if (presence != null) |
1390 | { | ||
1391 | ShowScriptSaveResponse(item.OwnerID, | ||
1392 | assetID, "Compile successful", true); | ||
1335 | } | 1393 | } |
1336 | } | ||
1337 | 1394 | ||
1395 | instance.AppDomain = appDomain; | ||
1396 | instance.LineMap = linemap; | ||
1397 | lockScriptsForWrite(true); | ||
1398 | m_Scripts[itemID] = instance; | ||
1399 | lockScriptsForWrite(false); | ||
1400 | } | ||
1401 | else | ||
1402 | { | ||
1403 | lockScriptsForRead(false); | ||
1404 | } | ||
1338 | lock (m_PrimObjects) | 1405 | lock (m_PrimObjects) |
1339 | { | 1406 | { |
1340 | if (!m_PrimObjects.ContainsKey(localID)) | 1407 | if (!m_PrimObjects.ContainsKey(localID)) |
@@ -1352,7 +1419,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1352 | m_AddingAssemblies[assembly]--; | 1419 | m_AddingAssemblies[assembly]--; |
1353 | } | 1420 | } |
1354 | 1421 | ||
1355 | if (instance != null) | 1422 | if (instance!=null) |
1356 | instance.Init(); | 1423 | instance.Init(); |
1357 | 1424 | ||
1358 | bool runIt; | 1425 | bool runIt; |
@@ -1375,18 +1442,28 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1375 | m_CompileDict.Remove(itemID); | 1442 | m_CompileDict.Remove(itemID); |
1376 | } | 1443 | } |
1377 | 1444 | ||
1378 | IScriptInstance instance = null; | 1445 | lockScriptsForRead(true); |
1379 | 1446 | // Do we even have it? | |
1380 | lock (m_Scripts) | 1447 | if (!m_Scripts.ContainsKey(itemID)) |
1381 | { | 1448 | { |
1382 | // Do we even have it? | 1449 | // Do we even have it? |
1383 | if (!m_Scripts.ContainsKey(itemID)) | 1450 | if (!m_Scripts.ContainsKey(itemID)) |
1384 | return; | 1451 | return; |
1385 | 1452 | ||
1386 | instance = m_Scripts[itemID]; | 1453 | lockScriptsForRead(false); |
1454 | lockScriptsForWrite(true); | ||
1387 | m_Scripts.Remove(itemID); | 1455 | m_Scripts.Remove(itemID); |
1456 | lockScriptsForWrite(false); | ||
1457 | |||
1458 | return; | ||
1388 | } | 1459 | } |
1460 | |||
1389 | 1461 | ||
1462 | IScriptInstance instance=m_Scripts[itemID]; | ||
1463 | lockScriptsForRead(false); | ||
1464 | lockScriptsForWrite(true); | ||
1465 | m_Scripts.Remove(itemID); | ||
1466 | lockScriptsForWrite(false); | ||
1390 | instance.ClearQueue(); | 1467 | instance.ClearQueue(); |
1391 | 1468 | ||
1392 | instance.Stop(m_WaitForEventCompletionOnScriptStop); | 1469 | instance.Stop(m_WaitForEventCompletionOnScriptStop); |
@@ -1423,8 +1500,13 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1423 | 1500 | ||
1424 | ObjectRemoved handlerObjectRemoved = OnObjectRemoved; | 1501 | ObjectRemoved handlerObjectRemoved = OnObjectRemoved; |
1425 | if (handlerObjectRemoved != null) | 1502 | if (handlerObjectRemoved != null) |
1426 | handlerObjectRemoved(instance.ObjectID); | 1503 | { |
1504 | SceneObjectPart part = m_Scene.GetSceneObjectPart(localID); | ||
1505 | handlerObjectRemoved(part.UUID); | ||
1506 | } | ||
1427 | 1507 | ||
1508 | CleanAssemblies(); | ||
1509 | |||
1428 | ScriptRemoved handlerScriptRemoved = OnScriptRemoved; | 1510 | ScriptRemoved handlerScriptRemoved = OnScriptRemoved; |
1429 | if (handlerScriptRemoved != null) | 1511 | if (handlerScriptRemoved != null) |
1430 | handlerScriptRemoved(itemID); | 1512 | handlerScriptRemoved(itemID); |
@@ -1685,12 +1767,14 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1685 | private IScriptInstance GetInstance(UUID itemID) | 1767 | private IScriptInstance GetInstance(UUID itemID) |
1686 | { | 1768 | { |
1687 | IScriptInstance instance; | 1769 | IScriptInstance instance; |
1688 | lock (m_Scripts) | 1770 | lockScriptsForRead(true); |
1771 | if (!m_Scripts.ContainsKey(itemID)) | ||
1689 | { | 1772 | { |
1690 | if (!m_Scripts.ContainsKey(itemID)) | 1773 | lockScriptsForRead(false); |
1691 | return null; | 1774 | return null; |
1692 | instance = m_Scripts[itemID]; | ||
1693 | } | 1775 | } |
1776 | instance = m_Scripts[itemID]; | ||
1777 | lockScriptsForRead(false); | ||
1694 | return instance; | 1778 | return instance; |
1695 | } | 1779 | } |
1696 | 1780 | ||
@@ -1714,6 +1798,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1714 | return false; | 1798 | return false; |
1715 | } | 1799 | } |
1716 | 1800 | ||
1801 | [DebuggerNonUserCode] | ||
1717 | public void ApiResetScript(UUID itemID) | 1802 | public void ApiResetScript(UUID itemID) |
1718 | { | 1803 | { |
1719 | IScriptInstance instance = GetInstance(itemID); | 1804 | IScriptInstance instance = GetInstance(itemID); |
@@ -1775,6 +1860,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1775 | return UUID.Zero; | 1860 | return UUID.Zero; |
1776 | } | 1861 | } |
1777 | 1862 | ||
1863 | [DebuggerNonUserCode] | ||
1778 | public void SetState(UUID itemID, string newState) | 1864 | public void SetState(UUID itemID, string newState) |
1779 | { | 1865 | { |
1780 | IScriptInstance instance = GetInstance(itemID); | 1866 | IScriptInstance instance = GetInstance(itemID); |
@@ -1797,11 +1883,10 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1797 | 1883 | ||
1798 | List<IScriptInstance> instances = new List<IScriptInstance>(); | 1884 | List<IScriptInstance> instances = new List<IScriptInstance>(); |
1799 | 1885 | ||
1800 | lock (m_Scripts) | 1886 | lockScriptsForRead(true); |
1801 | { | 1887 | foreach (IScriptInstance instance in m_Scripts.Values) |
1802 | foreach (IScriptInstance instance in m_Scripts.Values) | ||
1803 | instances.Add(instance); | 1888 | instances.Add(instance); |
1804 | } | 1889 | lockScriptsForRead(false); |
1805 | 1890 | ||
1806 | foreach (IScriptInstance i in instances) | 1891 | foreach (IScriptInstance i in instances) |
1807 | { | 1892 | { |