diff options
Diffstat (limited to 'OpenSim/Region/ScriptEngine/XEngine/XEngine.cs')
-rw-r--r-- | OpenSim/Region/ScriptEngine/XEngine/XEngine.cs | 378 |
1 files changed, 235 insertions, 143 deletions
diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs index 8c3bb5b..34fcf0c 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; |
@@ -147,6 +148,8 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
147 | private Dictionary<UUID, IScriptInstance> m_Scripts = | 148 | private Dictionary<UUID, IScriptInstance> m_Scripts = |
148 | new Dictionary<UUID, IScriptInstance>(); | 149 | new Dictionary<UUID, IScriptInstance>(); |
149 | 150 | ||
151 | private OpenMetaverse.ReaderWriterLockSlim m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim(); | ||
152 | |||
150 | // Maps the asset ID to the assembly | 153 | // Maps the asset ID to the assembly |
151 | 154 | ||
152 | private Dictionary<UUID, string> m_Assemblies = | 155 | private Dictionary<UUID, string> m_Assemblies = |
@@ -169,6 +172,71 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
169 | IWorkItemResult m_CurrentCompile = null; | 172 | IWorkItemResult m_CurrentCompile = null; |
170 | private Dictionary<UUID, int> m_CompileDict = new Dictionary<UUID, int>(); | 173 | private Dictionary<UUID, int> m_CompileDict = new Dictionary<UUID, int>(); |
171 | 174 | ||
175 | private void lockScriptsForRead(bool locked) | ||
176 | { | ||
177 | if (locked) | ||
178 | { | ||
179 | if (m_scriptsLock.RecursiveReadCount > 0) | ||
180 | { | ||
181 | 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."); | ||
182 | m_scriptsLock.ExitReadLock(); | ||
183 | } | ||
184 | if (m_scriptsLock.RecursiveWriteCount > 0) | ||
185 | { | ||
186 | m_log.Error("[XEngine.m_Scripts] Recursive write lock requested. This should not happen and means something needs to be fixed."); | ||
187 | m_scriptsLock.ExitWriteLock(); | ||
188 | } | ||
189 | |||
190 | while (!m_scriptsLock.TryEnterReadLock(60000)) | ||
191 | { | ||
192 | 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."); | ||
193 | if (m_scriptsLock.IsWriteLockHeld) | ||
194 | { | ||
195 | m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim(); | ||
196 | } | ||
197 | } | ||
198 | } | ||
199 | else | ||
200 | { | ||
201 | if (m_scriptsLock.RecursiveReadCount > 0) | ||
202 | { | ||
203 | m_scriptsLock.ExitReadLock(); | ||
204 | } | ||
205 | } | ||
206 | } | ||
207 | private void lockScriptsForWrite(bool locked) | ||
208 | { | ||
209 | if (locked) | ||
210 | { | ||
211 | if (m_scriptsLock.RecursiveReadCount > 0) | ||
212 | { | ||
213 | 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."); | ||
214 | m_scriptsLock.ExitReadLock(); | ||
215 | } | ||
216 | if (m_scriptsLock.RecursiveWriteCount > 0) | ||
217 | { | ||
218 | m_log.Error("[XEngine.m_Scripts] Recursive write lock requested. This should not happen and means something needs to be fixed."); | ||
219 | m_scriptsLock.ExitWriteLock(); | ||
220 | } | ||
221 | |||
222 | while (!m_scriptsLock.TryEnterWriteLock(60000)) | ||
223 | { | ||
224 | 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."); | ||
225 | if (m_scriptsLock.IsWriteLockHeld) | ||
226 | { | ||
227 | m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim(); | ||
228 | } | ||
229 | } | ||
230 | } | ||
231 | else | ||
232 | { | ||
233 | if (m_scriptsLock.RecursiveWriteCount > 0) | ||
234 | { | ||
235 | m_scriptsLock.ExitWriteLock(); | ||
236 | } | ||
237 | } | ||
238 | } | ||
239 | |||
172 | private ScriptEngineConsoleCommands m_consoleCommands; | 240 | private ScriptEngineConsoleCommands m_consoleCommands; |
173 | 241 | ||
174 | public string ScriptEngineName | 242 | public string ScriptEngineName |
@@ -677,64 +745,69 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
677 | { | 745 | { |
678 | if (!m_Enabled) | 746 | if (!m_Enabled) |
679 | return; | 747 | return; |
748 | lockScriptsForRead(true); | ||
680 | 749 | ||
681 | lock (m_Scripts) | 750 | List<IScriptInstance> instancesToDel = new List<IScriptInstance>(m_Scripts.Values); |
682 | { | ||
683 | m_log.InfoFormat( | ||
684 | "[XEngine]: Shutting down {0} scripts in {1}", m_Scripts.Count, m_Scene.RegionInfo.RegionName); | ||
685 | 751 | ||
686 | foreach (IScriptInstance instance in m_Scripts.Values) | 752 | // foreach (IScriptInstance instance in m_Scripts.Values) |
753 | foreach (IScriptInstance instance in instancesToDel) | ||
754 | { | ||
755 | // Force a final state save | ||
756 | // | ||
757 | if (m_Assemblies.ContainsKey(instance.AssetID)) | ||
687 | { | 758 | { |
688 | // Force a final state save | 759 | string assembly = m_Assemblies[instance.AssetID]; |
689 | // | ||
690 | if (m_Assemblies.ContainsKey(instance.AssetID)) | ||
691 | { | ||
692 | string assembly = m_Assemblies[instance.AssetID]; | ||
693 | 760 | ||
694 | try | 761 | try |
695 | { | 762 | { |
696 | instance.SaveState(assembly); | 763 | instance.SaveState(assembly); |
697 | } | ||
698 | catch (Exception e) | ||
699 | { | ||
700 | m_log.Error( | ||
701 | string.Format( | ||
702 | "[XEngine]: Failed final state save for script {0}.{1}, item UUID {2}, prim UUID {3} in {4}. Exception ", | ||
703 | instance.PrimName, instance.ScriptName, instance.ItemID, instance.ObjectID, World.Name) | ||
704 | , e); | ||
705 | } | ||
706 | } | 764 | } |
765 | catch (Exception e) | ||
766 | { | ||
767 | m_log.Error( | ||
768 | string.Format( | ||
769 | "[XEngine]: Failed final state save for script {0}.{1}, item UUID {2}, prim UUID {3} in {4}. Exception ", | ||
770 | instance.PrimName, instance.ScriptName, instance.ItemID, instance.ObjectID, World.Name) | ||
771 | , e); | ||
772 | } | ||
773 | } | ||
707 | 774 | ||
708 | // Clear the event queue and abort the instance thread | 775 | // Clear the event queue and abort the instance thread |
709 | // | 776 | // |
710 | instance.ClearQueue(); | 777 | instance.ClearQueue(); |
711 | instance.Stop(0); | 778 | instance.Stop(0); |
712 | 779 | ||
713 | // Release events, timer, etc | 780 | // Release events, timer, etc |
714 | // | 781 | // |
715 | instance.DestroyScriptInstance(); | 782 | instance.DestroyScriptInstance(); |
716 | 783 | ||
717 | // Unload scripts and app domains. | 784 | // Unload scripts and app domains |
718 | // Must be done explicitly because they have infinite | 785 | // Must be done explicitly because they have infinite |
719 | // lifetime. | 786 | // lifetime |
720 | // However, don't bother to do this if the simulator is shutting | 787 | // |
721 | // down since it takes a long time with many scripts. | 788 | // if (!m_SimulatorShuttingDown) |
722 | if (!m_SimulatorShuttingDown) | 789 | { |
790 | m_DomainScripts[instance.AppDomain].Remove(instance.ItemID); | ||
791 | if (m_DomainScripts[instance.AppDomain].Count == 0) | ||
723 | { | 792 | { |
724 | m_DomainScripts[instance.AppDomain].Remove(instance.ItemID); | 793 | m_DomainScripts.Remove(instance.AppDomain); |
725 | if (m_DomainScripts[instance.AppDomain].Count == 0) | 794 | UnloadAppDomain(instance.AppDomain); |
726 | { | ||
727 | m_DomainScripts.Remove(instance.AppDomain); | ||
728 | UnloadAppDomain(instance.AppDomain); | ||
729 | } | ||
730 | } | 795 | } |
731 | } | 796 | } |
732 | 797 | ||
733 | m_Scripts.Clear(); | 798 | // m_Scripts.Clear(); |
734 | m_PrimObjects.Clear(); | 799 | // m_PrimObjects.Clear(); |
735 | m_Assemblies.Clear(); | 800 | // m_Assemblies.Clear(); |
736 | m_DomainScripts.Clear(); | 801 | // m_DomainScripts.Clear(); |
737 | } | 802 | } |
803 | lockScriptsForRead(false); | ||
804 | lockScriptsForWrite(true); | ||
805 | m_Scripts.Clear(); | ||
806 | lockScriptsForWrite(false); | ||
807 | m_PrimObjects.Clear(); | ||
808 | m_Assemblies.Clear(); | ||
809 | m_DomainScripts.Clear(); | ||
810 | |||
738 | lock (m_ScriptEngines) | 811 | lock (m_ScriptEngines) |
739 | { | 812 | { |
740 | m_ScriptEngines.Remove(this); | 813 | m_ScriptEngines.Remove(this); |
@@ -803,22 +876,20 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
803 | 876 | ||
804 | List<IScriptInstance> instances = new List<IScriptInstance>(); | 877 | List<IScriptInstance> instances = new List<IScriptInstance>(); |
805 | 878 | ||
806 | lock (m_Scripts) | 879 | lockScriptsForRead(true); |
807 | { | 880 | foreach (IScriptInstance instance in m_Scripts.Values) |
808 | foreach (IScriptInstance instance in m_Scripts.Values) | ||
809 | instances.Add(instance); | 881 | instances.Add(instance); |
810 | } | 882 | lockScriptsForRead(false); |
811 | 883 | ||
812 | foreach (IScriptInstance i in instances) | 884 | foreach (IScriptInstance i in instances) |
813 | { | 885 | { |
814 | string assembly = String.Empty; | 886 | string assembly = String.Empty; |
815 | 887 | ||
816 | lock (m_Scripts) | 888 | |
817 | { | ||
818 | if (!m_Assemblies.ContainsKey(i.AssetID)) | 889 | if (!m_Assemblies.ContainsKey(i.AssetID)) |
819 | continue; | 890 | continue; |
820 | assembly = m_Assemblies[i.AssetID]; | 891 | assembly = m_Assemblies[i.AssetID]; |
821 | } | 892 | |
822 | 893 | ||
823 | try | 894 | try |
824 | { | 895 | { |
@@ -1219,96 +1290,99 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1219 | } | 1290 | } |
1220 | 1291 | ||
1221 | ScriptInstance instance = null; | 1292 | ScriptInstance instance = null; |
1222 | lock (m_Scripts) | 1293 | // Create the object record |
1294 | lockScriptsForRead(true); | ||
1295 | if ((!m_Scripts.ContainsKey(itemID)) || | ||
1296 | (m_Scripts[itemID].AssetID != assetID)) | ||
1223 | { | 1297 | { |
1224 | // Create the object record | 1298 | lockScriptsForRead(false); |
1225 | if ((!m_Scripts.ContainsKey(itemID)) || | ||
1226 | (m_Scripts[itemID].AssetID != assetID)) | ||
1227 | { | ||
1228 | UUID appDomain = assetID; | ||
1229 | 1299 | ||
1230 | if (part.ParentGroup.IsAttachment) | 1300 | UUID appDomain = assetID; |
1231 | appDomain = part.ParentGroup.RootPart.UUID; | ||
1232 | 1301 | ||
1233 | if (!m_AppDomains.ContainsKey(appDomain)) | 1302 | if (part.ParentGroup.IsAttachment) |
1234 | { | 1303 | appDomain = part.ParentGroup.RootPart.UUID; |
1235 | try | ||
1236 | { | ||
1237 | AppDomainSetup appSetup = new AppDomainSetup(); | ||
1238 | appSetup.PrivateBinPath = Path.Combine( | ||
1239 | m_ScriptEnginesPath, | ||
1240 | m_Scene.RegionInfo.RegionID.ToString()); | ||
1241 | 1304 | ||
1242 | Evidence baseEvidence = AppDomain.CurrentDomain.Evidence; | 1305 | if (!m_AppDomains.ContainsKey(appDomain)) |
1243 | Evidence evidence = new Evidence(baseEvidence); | 1306 | { |
1307 | try | ||
1308 | { | ||
1309 | AppDomainSetup appSetup = new AppDomainSetup(); | ||
1310 | appSetup.PrivateBinPath = Path.Combine( | ||
1311 | m_ScriptEnginesPath, | ||
1312 | m_Scene.RegionInfo.RegionID.ToString()); | ||
1244 | 1313 | ||
1245 | AppDomain sandbox; | 1314 | Evidence baseEvidence = AppDomain.CurrentDomain.Evidence; |
1246 | if (m_AppDomainLoading) | 1315 | Evidence evidence = new Evidence(baseEvidence); |
1247 | { | ||
1248 | sandbox = AppDomain.CreateDomain( | ||
1249 | m_Scene.RegionInfo.RegionID.ToString(), | ||
1250 | evidence, appSetup); | ||
1251 | sandbox.AssemblyResolve += | ||
1252 | new ResolveEventHandler( | ||
1253 | AssemblyResolver.OnAssemblyResolve); | ||
1254 | } | ||
1255 | else | ||
1256 | { | ||
1257 | sandbox = AppDomain.CurrentDomain; | ||
1258 | } | ||
1259 | |||
1260 | //PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel(); | ||
1261 | //AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition(); | ||
1262 | //PermissionSet sandboxPermissionSet = sandboxPolicy.GetNamedPermissionSet("Internet"); | ||
1263 | //PolicyStatement sandboxPolicyStatement = new PolicyStatement(sandboxPermissionSet); | ||
1264 | //CodeGroup sandboxCodeGroup = new UnionCodeGroup(sandboxMembershipCondition, sandboxPolicyStatement); | ||
1265 | //sandboxPolicy.RootCodeGroup = sandboxCodeGroup; | ||
1266 | //sandbox.SetAppDomainPolicy(sandboxPolicy); | ||
1267 | |||
1268 | m_AppDomains[appDomain] = sandbox; | ||
1269 | 1316 | ||
1270 | m_DomainScripts[appDomain] = new List<UUID>(); | 1317 | AppDomain sandbox; |
1318 | if (m_AppDomainLoading) | ||
1319 | { | ||
1320 | sandbox = AppDomain.CreateDomain( | ||
1321 | m_Scene.RegionInfo.RegionID.ToString(), | ||
1322 | evidence, appSetup); | ||
1323 | m_AppDomains[appDomain].AssemblyResolve += | ||
1324 | new ResolveEventHandler( | ||
1325 | AssemblyResolver.OnAssemblyResolve); | ||
1271 | } | 1326 | } |
1272 | catch (Exception e) | 1327 | else |
1273 | { | 1328 | { |
1274 | m_log.ErrorFormat("[XEngine] Exception creating app domain:\n {0}", e.ToString()); | 1329 | sandbox = AppDomain.CurrentDomain; |
1275 | m_ScriptErrorMessage += "Exception creating app domain:\n"; | ||
1276 | m_ScriptFailCount++; | ||
1277 | lock (m_AddingAssemblies) | ||
1278 | { | ||
1279 | m_AddingAssemblies[assembly]--; | ||
1280 | } | ||
1281 | return false; | ||
1282 | } | 1330 | } |
1283 | } | ||
1284 | m_DomainScripts[appDomain].Add(itemID); | ||
1285 | |||
1286 | instance = new ScriptInstance(this, part, | ||
1287 | itemID, assetID, assembly, | ||
1288 | m_AppDomains[appDomain], | ||
1289 | part.ParentGroup.RootPart.Name, | ||
1290 | item.Name, startParam, postOnRez, | ||
1291 | stateSource, m_MaxScriptQueue); | ||
1292 | |||
1293 | // if (DebugLevel >= 1) | ||
1294 | // m_log.DebugFormat( | ||
1295 | // "[XEngine] Loaded script {0}.{1}, item UUID {2}, prim UUID {3} @ {4}.{5}", | ||
1296 | // part.ParentGroup.RootPart.Name, item.Name, itemID, part.UUID, | ||
1297 | // part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName); | ||
1298 | 1331 | ||
1299 | if (presence != null) | 1332 | //PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel(); |
1333 | //AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition(); | ||
1334 | //PermissionSet sandboxPermissionSet = sandboxPolicy.GetNamedPermissionSet("Internet"); | ||
1335 | //PolicyStatement sandboxPolicyStatement = new PolicyStatement(sandboxPermissionSet); | ||
1336 | //CodeGroup sandboxCodeGroup = new UnionCodeGroup(sandboxMembershipCondition, sandboxPolicyStatement); | ||
1337 | //sandboxPolicy.RootCodeGroup = sandboxCodeGroup; | ||
1338 | //sandbox.SetAppDomainPolicy(sandboxPolicy); | ||
1339 | |||
1340 | m_AppDomains[appDomain] = sandbox; | ||
1341 | |||
1342 | m_DomainScripts[appDomain] = new List<UUID>(); | ||
1343 | } | ||
1344 | catch (Exception e) | ||
1300 | { | 1345 | { |
1301 | ShowScriptSaveResponse(item.OwnerID, | 1346 | m_log.ErrorFormat("[XEngine] Exception creating app domain:\n {0}", e.ToString()); |
1302 | assetID, "Compile successful", true); | 1347 | m_ScriptErrorMessage += "Exception creating app domain:\n"; |
1348 | m_ScriptFailCount++; | ||
1349 | lock (m_AddingAssemblies) | ||
1350 | { | ||
1351 | m_AddingAssemblies[assembly]--; | ||
1352 | } | ||
1353 | return false; | ||
1303 | } | 1354 | } |
1355 | } | ||
1356 | m_DomainScripts[appDomain].Add(itemID); | ||
1357 | |||
1358 | instance = new ScriptInstance(this, part, | ||
1359 | itemID, assetID, assembly, | ||
1360 | m_AppDomains[appDomain], | ||
1361 | part.ParentGroup.RootPart.Name, | ||
1362 | item.Name, startParam, postOnRez, | ||
1363 | stateSource, m_MaxScriptQueue); | ||
1364 | |||
1365 | // m_log.DebugFormat( | ||
1366 | // "[XEngine] Loaded script {0}.{1}, script UUID {2}, prim UUID {3} @ {4}.{5}", | ||
1367 | // part.ParentGroup.RootPart.Name, item.Name, assetID, part.UUID, | ||
1368 | // part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName); | ||
1304 | 1369 | ||
1305 | instance.AppDomain = appDomain; | 1370 | if (presence != null) |
1306 | instance.LineMap = linemap; | 1371 | { |
1307 | 1372 | ShowScriptSaveResponse(item.OwnerID, | |
1308 | m_Scripts[itemID] = instance; | 1373 | assetID, "Compile successful", true); |
1309 | } | 1374 | } |
1310 | } | ||
1311 | 1375 | ||
1376 | instance.AppDomain = appDomain; | ||
1377 | instance.LineMap = linemap; | ||
1378 | lockScriptsForWrite(true); | ||
1379 | m_Scripts[itemID] = instance; | ||
1380 | lockScriptsForWrite(false); | ||
1381 | } | ||
1382 | else | ||
1383 | { | ||
1384 | lockScriptsForRead(false); | ||
1385 | } | ||
1312 | lock (m_PrimObjects) | 1386 | lock (m_PrimObjects) |
1313 | { | 1387 | { |
1314 | if (!m_PrimObjects.ContainsKey(localID)) | 1388 | if (!m_PrimObjects.ContainsKey(localID)) |
@@ -1326,7 +1400,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1326 | m_AddingAssemblies[assembly]--; | 1400 | m_AddingAssemblies[assembly]--; |
1327 | } | 1401 | } |
1328 | 1402 | ||
1329 | if (instance != null) | 1403 | if (instance!=null) |
1330 | instance.Init(); | 1404 | instance.Init(); |
1331 | 1405 | ||
1332 | bool runIt; | 1406 | bool runIt; |
@@ -1349,18 +1423,28 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1349 | m_CompileDict.Remove(itemID); | 1423 | m_CompileDict.Remove(itemID); |
1350 | } | 1424 | } |
1351 | 1425 | ||
1352 | IScriptInstance instance = null; | 1426 | lockScriptsForRead(true); |
1353 | 1427 | // Do we even have it? | |
1354 | lock (m_Scripts) | 1428 | if (!m_Scripts.ContainsKey(itemID)) |
1355 | { | 1429 | { |
1356 | // Do we even have it? | 1430 | // Do we even have it? |
1357 | if (!m_Scripts.ContainsKey(itemID)) | 1431 | if (!m_Scripts.ContainsKey(itemID)) |
1358 | return; | 1432 | return; |
1359 | 1433 | ||
1360 | instance = m_Scripts[itemID]; | 1434 | lockScriptsForRead(false); |
1435 | lockScriptsForWrite(true); | ||
1361 | m_Scripts.Remove(itemID); | 1436 | m_Scripts.Remove(itemID); |
1437 | lockScriptsForWrite(false); | ||
1438 | |||
1439 | return; | ||
1362 | } | 1440 | } |
1441 | |||
1363 | 1442 | ||
1443 | IScriptInstance instance=m_Scripts[itemID]; | ||
1444 | lockScriptsForRead(false); | ||
1445 | lockScriptsForWrite(true); | ||
1446 | m_Scripts.Remove(itemID); | ||
1447 | lockScriptsForWrite(false); | ||
1364 | instance.ClearQueue(); | 1448 | instance.ClearQueue(); |
1365 | 1449 | ||
1366 | instance.Stop(m_WaitForEventCompletionOnScriptStop); | 1450 | instance.Stop(m_WaitForEventCompletionOnScriptStop); |
@@ -1397,8 +1481,13 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1397 | 1481 | ||
1398 | ObjectRemoved handlerObjectRemoved = OnObjectRemoved; | 1482 | ObjectRemoved handlerObjectRemoved = OnObjectRemoved; |
1399 | if (handlerObjectRemoved != null) | 1483 | if (handlerObjectRemoved != null) |
1400 | handlerObjectRemoved(instance.ObjectID); | 1484 | { |
1485 | SceneObjectPart part = m_Scene.GetSceneObjectPart(localID); | ||
1486 | handlerObjectRemoved(part.UUID); | ||
1487 | } | ||
1401 | 1488 | ||
1489 | CleanAssemblies(); | ||
1490 | |||
1402 | ScriptRemoved handlerScriptRemoved = OnScriptRemoved; | 1491 | ScriptRemoved handlerScriptRemoved = OnScriptRemoved; |
1403 | if (handlerScriptRemoved != null) | 1492 | if (handlerScriptRemoved != null) |
1404 | handlerScriptRemoved(itemID); | 1493 | handlerScriptRemoved(itemID); |
@@ -1659,12 +1748,14 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1659 | private IScriptInstance GetInstance(UUID itemID) | 1748 | private IScriptInstance GetInstance(UUID itemID) |
1660 | { | 1749 | { |
1661 | IScriptInstance instance; | 1750 | IScriptInstance instance; |
1662 | lock (m_Scripts) | 1751 | lockScriptsForRead(true); |
1752 | if (!m_Scripts.ContainsKey(itemID)) | ||
1663 | { | 1753 | { |
1664 | if (!m_Scripts.ContainsKey(itemID)) | 1754 | lockScriptsForRead(false); |
1665 | return null; | 1755 | return null; |
1666 | instance = m_Scripts[itemID]; | ||
1667 | } | 1756 | } |
1757 | instance = m_Scripts[itemID]; | ||
1758 | lockScriptsForRead(false); | ||
1668 | return instance; | 1759 | return instance; |
1669 | } | 1760 | } |
1670 | 1761 | ||
@@ -1688,6 +1779,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1688 | return false; | 1779 | return false; |
1689 | } | 1780 | } |
1690 | 1781 | ||
1782 | [DebuggerNonUserCode] | ||
1691 | public void ApiResetScript(UUID itemID) | 1783 | public void ApiResetScript(UUID itemID) |
1692 | { | 1784 | { |
1693 | IScriptInstance instance = GetInstance(itemID); | 1785 | IScriptInstance instance = GetInstance(itemID); |
@@ -1744,6 +1836,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1744 | return UUID.Zero; | 1836 | return UUID.Zero; |
1745 | } | 1837 | } |
1746 | 1838 | ||
1839 | [DebuggerNonUserCode] | ||
1747 | public void SetState(UUID itemID, string newState) | 1840 | public void SetState(UUID itemID, string newState) |
1748 | { | 1841 | { |
1749 | IScriptInstance instance = GetInstance(itemID); | 1842 | IScriptInstance instance = GetInstance(itemID); |
@@ -1766,11 +1859,10 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1766 | 1859 | ||
1767 | List<IScriptInstance> instances = new List<IScriptInstance>(); | 1860 | List<IScriptInstance> instances = new List<IScriptInstance>(); |
1768 | 1861 | ||
1769 | lock (m_Scripts) | 1862 | lockScriptsForRead(true); |
1770 | { | 1863 | foreach (IScriptInstance instance in m_Scripts.Values) |
1771 | foreach (IScriptInstance instance in m_Scripts.Values) | ||
1772 | instances.Add(instance); | 1864 | instances.Add(instance); |
1773 | } | 1865 | lockScriptsForRead(false); |
1774 | 1866 | ||
1775 | foreach (IScriptInstance i in instances) | 1867 | foreach (IScriptInstance i in instances) |
1776 | { | 1868 | { |