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