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 79cec04..05dd7ab 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 | public string ScriptEngineName | 240 | public string ScriptEngineName |
173 | { | 241 | { |
174 | get { return "XEngine"; } | 242 | get { return "XEngine"; } |
@@ -670,64 +738,69 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
670 | { | 738 | { |
671 | if (!m_Enabled) | 739 | if (!m_Enabled) |
672 | return; | 740 | return; |
741 | lockScriptsForRead(true); | ||
673 | 742 | ||
674 | lock (m_Scripts) | 743 | List<IScriptInstance> instancesToDel = new List<IScriptInstance>(m_Scripts.Values); |
675 | { | ||
676 | m_log.InfoFormat( | ||
677 | "[XEngine]: Shutting down {0} scripts in {1}", m_Scripts.Count, m_Scene.RegionInfo.RegionName); | ||
678 | 744 | ||
679 | foreach (IScriptInstance instance in m_Scripts.Values) | 745 | // foreach (IScriptInstance instance in m_Scripts.Values) |
746 | foreach (IScriptInstance instance in instancesToDel) | ||
747 | { | ||
748 | // Force a final state save | ||
749 | // | ||
750 | if (m_Assemblies.ContainsKey(instance.AssetID)) | ||
680 | { | 751 | { |
681 | // Force a final state save | 752 | string assembly = m_Assemblies[instance.AssetID]; |
682 | // | ||
683 | if (m_Assemblies.ContainsKey(instance.AssetID)) | ||
684 | { | ||
685 | string assembly = m_Assemblies[instance.AssetID]; | ||
686 | 753 | ||
687 | try | 754 | try |
688 | { | 755 | { |
689 | instance.SaveState(assembly); | 756 | instance.SaveState(assembly); |
690 | } | ||
691 | catch (Exception e) | ||
692 | { | ||
693 | m_log.Error( | ||
694 | string.Format( | ||
695 | "[XEngine]: Failed final state save for script {0}.{1}, item UUID {2}, prim UUID {3} in {4}. Exception ", | ||
696 | instance.PrimName, instance.ScriptName, instance.ItemID, instance.ObjectID, World.Name) | ||
697 | , e); | ||
698 | } | ||
699 | } | 757 | } |
758 | catch (Exception e) | ||
759 | { | ||
760 | m_log.Error( | ||
761 | string.Format( | ||
762 | "[XEngine]: Failed final state save for script {0}.{1}, item UUID {2}, prim UUID {3} in {4}. Exception ", | ||
763 | instance.PrimName, instance.ScriptName, instance.ItemID, instance.ObjectID, World.Name) | ||
764 | , e); | ||
765 | } | ||
766 | } | ||
700 | 767 | ||
701 | // Clear the event queue and abort the instance thread | 768 | // Clear the event queue and abort the instance thread |
702 | // | 769 | // |
703 | instance.ClearQueue(); | 770 | instance.ClearQueue(); |
704 | instance.Stop(0); | 771 | instance.Stop(0); |
705 | 772 | ||
706 | // Release events, timer, etc | 773 | // Release events, timer, etc |
707 | // | 774 | // |
708 | instance.DestroyScriptInstance(); | 775 | instance.DestroyScriptInstance(); |
709 | 776 | ||
710 | // Unload scripts and app domains. | 777 | // Unload scripts and app domains |
711 | // Must be done explicitly because they have infinite | 778 | // Must be done explicitly because they have infinite |
712 | // lifetime. | 779 | // lifetime |
713 | // However, don't bother to do this if the simulator is shutting | 780 | // |
714 | // down since it takes a long time with many scripts. | 781 | // if (!m_SimulatorShuttingDown) |
715 | if (!m_SimulatorShuttingDown) | 782 | { |
783 | m_DomainScripts[instance.AppDomain].Remove(instance.ItemID); | ||
784 | if (m_DomainScripts[instance.AppDomain].Count == 0) | ||
716 | { | 785 | { |
717 | m_DomainScripts[instance.AppDomain].Remove(instance.ItemID); | 786 | m_DomainScripts.Remove(instance.AppDomain); |
718 | if (m_DomainScripts[instance.AppDomain].Count == 0) | 787 | UnloadAppDomain(instance.AppDomain); |
719 | { | ||
720 | m_DomainScripts.Remove(instance.AppDomain); | ||
721 | UnloadAppDomain(instance.AppDomain); | ||
722 | } | ||
723 | } | 788 | } |
724 | } | 789 | } |
725 | 790 | ||
726 | m_Scripts.Clear(); | 791 | // m_Scripts.Clear(); |
727 | m_PrimObjects.Clear(); | 792 | // m_PrimObjects.Clear(); |
728 | m_Assemblies.Clear(); | 793 | // m_Assemblies.Clear(); |
729 | m_DomainScripts.Clear(); | 794 | // m_DomainScripts.Clear(); |
730 | } | 795 | } |
796 | lockScriptsForRead(false); | ||
797 | lockScriptsForWrite(true); | ||
798 | m_Scripts.Clear(); | ||
799 | lockScriptsForWrite(false); | ||
800 | m_PrimObjects.Clear(); | ||
801 | m_Assemblies.Clear(); | ||
802 | m_DomainScripts.Clear(); | ||
803 | |||
731 | lock (m_ScriptEngines) | 804 | lock (m_ScriptEngines) |
732 | { | 805 | { |
733 | m_ScriptEngines.Remove(this); | 806 | m_ScriptEngines.Remove(this); |
@@ -796,22 +869,20 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
796 | 869 | ||
797 | List<IScriptInstance> instances = new List<IScriptInstance>(); | 870 | List<IScriptInstance> instances = new List<IScriptInstance>(); |
798 | 871 | ||
799 | lock (m_Scripts) | 872 | lockScriptsForRead(true); |
800 | { | 873 | foreach (IScriptInstance instance in m_Scripts.Values) |
801 | foreach (IScriptInstance instance in m_Scripts.Values) | ||
802 | instances.Add(instance); | 874 | instances.Add(instance); |
803 | } | 875 | lockScriptsForRead(false); |
804 | 876 | ||
805 | foreach (IScriptInstance i in instances) | 877 | foreach (IScriptInstance i in instances) |
806 | { | 878 | { |
807 | string assembly = String.Empty; | 879 | string assembly = String.Empty; |
808 | 880 | ||
809 | lock (m_Scripts) | 881 | |
810 | { | ||
811 | if (!m_Assemblies.ContainsKey(i.AssetID)) | 882 | if (!m_Assemblies.ContainsKey(i.AssetID)) |
812 | continue; | 883 | continue; |
813 | assembly = m_Assemblies[i.AssetID]; | 884 | assembly = m_Assemblies[i.AssetID]; |
814 | } | 885 | |
815 | 886 | ||
816 | try | 887 | try |
817 | { | 888 | { |
@@ -1212,96 +1283,99 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1212 | } | 1283 | } |
1213 | 1284 | ||
1214 | ScriptInstance instance = null; | 1285 | ScriptInstance instance = null; |
1215 | lock (m_Scripts) | 1286 | // Create the object record |
1287 | lockScriptsForRead(true); | ||
1288 | if ((!m_Scripts.ContainsKey(itemID)) || | ||
1289 | (m_Scripts[itemID].AssetID != assetID)) | ||
1216 | { | 1290 | { |
1217 | // Create the object record | 1291 | lockScriptsForRead(false); |
1218 | if ((!m_Scripts.ContainsKey(itemID)) || | ||
1219 | (m_Scripts[itemID].AssetID != assetID)) | ||
1220 | { | ||
1221 | UUID appDomain = assetID; | ||
1222 | 1292 | ||
1223 | if (part.ParentGroup.IsAttachment) | 1293 | UUID appDomain = assetID; |
1224 | appDomain = part.ParentGroup.RootPart.UUID; | ||
1225 | 1294 | ||
1226 | if (!m_AppDomains.ContainsKey(appDomain)) | 1295 | if (part.ParentGroup.IsAttachment) |
1227 | { | 1296 | appDomain = part.ParentGroup.RootPart.UUID; |
1228 | try | ||
1229 | { | ||
1230 | AppDomainSetup appSetup = new AppDomainSetup(); | ||
1231 | appSetup.PrivateBinPath = Path.Combine( | ||
1232 | m_ScriptEnginesPath, | ||
1233 | m_Scene.RegionInfo.RegionID.ToString()); | ||
1234 | 1297 | ||
1235 | Evidence baseEvidence = AppDomain.CurrentDomain.Evidence; | 1298 | if (!m_AppDomains.ContainsKey(appDomain)) |
1236 | Evidence evidence = new Evidence(baseEvidence); | 1299 | { |
1300 | try | ||
1301 | { | ||
1302 | AppDomainSetup appSetup = new AppDomainSetup(); | ||
1303 | appSetup.PrivateBinPath = Path.Combine( | ||
1304 | m_ScriptEnginesPath, | ||
1305 | m_Scene.RegionInfo.RegionID.ToString()); | ||
1237 | 1306 | ||
1238 | AppDomain sandbox; | 1307 | Evidence baseEvidence = AppDomain.CurrentDomain.Evidence; |
1239 | if (m_AppDomainLoading) | 1308 | Evidence evidence = new Evidence(baseEvidence); |
1240 | { | ||
1241 | sandbox = AppDomain.CreateDomain( | ||
1242 | m_Scene.RegionInfo.RegionID.ToString(), | ||
1243 | evidence, appSetup); | ||
1244 | sandbox.AssemblyResolve += | ||
1245 | new ResolveEventHandler( | ||
1246 | AssemblyResolver.OnAssemblyResolve); | ||
1247 | } | ||
1248 | else | ||
1249 | { | ||
1250 | sandbox = AppDomain.CurrentDomain; | ||
1251 | } | ||
1252 | |||
1253 | //PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel(); | ||
1254 | //AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition(); | ||
1255 | //PermissionSet sandboxPermissionSet = sandboxPolicy.GetNamedPermissionSet("Internet"); | ||
1256 | //PolicyStatement sandboxPolicyStatement = new PolicyStatement(sandboxPermissionSet); | ||
1257 | //CodeGroup sandboxCodeGroup = new UnionCodeGroup(sandboxMembershipCondition, sandboxPolicyStatement); | ||
1258 | //sandboxPolicy.RootCodeGroup = sandboxCodeGroup; | ||
1259 | //sandbox.SetAppDomainPolicy(sandboxPolicy); | ||
1260 | |||
1261 | m_AppDomains[appDomain] = sandbox; | ||
1262 | 1309 | ||
1263 | m_DomainScripts[appDomain] = new List<UUID>(); | 1310 | AppDomain sandbox; |
1311 | if (m_AppDomainLoading) | ||
1312 | { | ||
1313 | sandbox = AppDomain.CreateDomain( | ||
1314 | m_Scene.RegionInfo.RegionID.ToString(), | ||
1315 | evidence, appSetup); | ||
1316 | m_AppDomains[appDomain].AssemblyResolve += | ||
1317 | new ResolveEventHandler( | ||
1318 | AssemblyResolver.OnAssemblyResolve); | ||
1264 | } | 1319 | } |
1265 | catch (Exception e) | 1320 | else |
1266 | { | 1321 | { |
1267 | m_log.ErrorFormat("[XEngine] Exception creating app domain:\n {0}", e.ToString()); | 1322 | sandbox = AppDomain.CurrentDomain; |
1268 | m_ScriptErrorMessage += "Exception creating app domain:\n"; | ||
1269 | m_ScriptFailCount++; | ||
1270 | lock (m_AddingAssemblies) | ||
1271 | { | ||
1272 | m_AddingAssemblies[assembly]--; | ||
1273 | } | ||
1274 | return false; | ||
1275 | } | 1323 | } |
1276 | } | ||
1277 | m_DomainScripts[appDomain].Add(itemID); | ||
1278 | |||
1279 | instance = new ScriptInstance(this, part, | ||
1280 | itemID, assetID, assembly, | ||
1281 | m_AppDomains[appDomain], | ||
1282 | part.ParentGroup.RootPart.Name, | ||
1283 | item.Name, startParam, postOnRez, | ||
1284 | stateSource, m_MaxScriptQueue); | ||
1285 | |||
1286 | // if (DebugLevel >= 1) | ||
1287 | // m_log.DebugFormat( | ||
1288 | // "[XEngine] Loaded script {0}.{1}, item UUID {2}, prim UUID {3} @ {4}.{5}", | ||
1289 | // part.ParentGroup.RootPart.Name, item.Name, itemID, part.UUID, | ||
1290 | // part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName); | ||
1291 | 1324 | ||
1292 | if (presence != null) | 1325 | //PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel(); |
1326 | //AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition(); | ||
1327 | //PermissionSet sandboxPermissionSet = sandboxPolicy.GetNamedPermissionSet("Internet"); | ||
1328 | //PolicyStatement sandboxPolicyStatement = new PolicyStatement(sandboxPermissionSet); | ||
1329 | //CodeGroup sandboxCodeGroup = new UnionCodeGroup(sandboxMembershipCondition, sandboxPolicyStatement); | ||
1330 | //sandboxPolicy.RootCodeGroup = sandboxCodeGroup; | ||
1331 | //sandbox.SetAppDomainPolicy(sandboxPolicy); | ||
1332 | |||
1333 | m_AppDomains[appDomain] = sandbox; | ||
1334 | |||
1335 | m_DomainScripts[appDomain] = new List<UUID>(); | ||
1336 | } | ||
1337 | catch (Exception e) | ||
1293 | { | 1338 | { |
1294 | ShowScriptSaveResponse(item.OwnerID, | 1339 | m_log.ErrorFormat("[XEngine] Exception creating app domain:\n {0}", e.ToString()); |
1295 | assetID, "Compile successful", true); | 1340 | m_ScriptErrorMessage += "Exception creating app domain:\n"; |
1341 | m_ScriptFailCount++; | ||
1342 | lock (m_AddingAssemblies) | ||
1343 | { | ||
1344 | m_AddingAssemblies[assembly]--; | ||
1345 | } | ||
1346 | return false; | ||
1296 | } | 1347 | } |
1348 | } | ||
1349 | m_DomainScripts[appDomain].Add(itemID); | ||
1350 | |||
1351 | instance = new ScriptInstance(this, part, | ||
1352 | itemID, assetID, assembly, | ||
1353 | m_AppDomains[appDomain], | ||
1354 | part.ParentGroup.RootPart.Name, | ||
1355 | item.Name, startParam, postOnRez, | ||
1356 | stateSource, m_MaxScriptQueue); | ||
1357 | |||
1358 | // m_log.DebugFormat( | ||
1359 | // "[XEngine] Loaded script {0}.{1}, script UUID {2}, prim UUID {3} @ {4}.{5}", | ||
1360 | // part.ParentGroup.RootPart.Name, item.Name, assetID, part.UUID, | ||
1361 | // part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName); | ||
1297 | 1362 | ||
1298 | instance.AppDomain = appDomain; | 1363 | if (presence != null) |
1299 | instance.LineMap = linemap; | 1364 | { |
1300 | 1365 | ShowScriptSaveResponse(item.OwnerID, | |
1301 | m_Scripts[itemID] = instance; | 1366 | assetID, "Compile successful", true); |
1302 | } | 1367 | } |
1303 | } | ||
1304 | 1368 | ||
1369 | instance.AppDomain = appDomain; | ||
1370 | instance.LineMap = linemap; | ||
1371 | lockScriptsForWrite(true); | ||
1372 | m_Scripts[itemID] = instance; | ||
1373 | lockScriptsForWrite(false); | ||
1374 | } | ||
1375 | else | ||
1376 | { | ||
1377 | lockScriptsForRead(false); | ||
1378 | } | ||
1305 | lock (m_PrimObjects) | 1379 | lock (m_PrimObjects) |
1306 | { | 1380 | { |
1307 | if (!m_PrimObjects.ContainsKey(localID)) | 1381 | if (!m_PrimObjects.ContainsKey(localID)) |
@@ -1319,7 +1393,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1319 | m_AddingAssemblies[assembly]--; | 1393 | m_AddingAssemblies[assembly]--; |
1320 | } | 1394 | } |
1321 | 1395 | ||
1322 | if (instance != null) | 1396 | if (instance!=null) |
1323 | instance.Init(); | 1397 | instance.Init(); |
1324 | 1398 | ||
1325 | bool runIt; | 1399 | bool runIt; |
@@ -1342,18 +1416,28 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1342 | m_CompileDict.Remove(itemID); | 1416 | m_CompileDict.Remove(itemID); |
1343 | } | 1417 | } |
1344 | 1418 | ||
1345 | IScriptInstance instance = null; | 1419 | lockScriptsForRead(true); |
1346 | 1420 | // Do we even have it? | |
1347 | lock (m_Scripts) | 1421 | if (!m_Scripts.ContainsKey(itemID)) |
1348 | { | 1422 | { |
1349 | // Do we even have it? | 1423 | // Do we even have it? |
1350 | if (!m_Scripts.ContainsKey(itemID)) | 1424 | if (!m_Scripts.ContainsKey(itemID)) |
1351 | return; | 1425 | return; |
1352 | 1426 | ||
1353 | instance = m_Scripts[itemID]; | 1427 | lockScriptsForRead(false); |
1428 | lockScriptsForWrite(true); | ||
1354 | m_Scripts.Remove(itemID); | 1429 | m_Scripts.Remove(itemID); |
1430 | lockScriptsForWrite(false); | ||
1431 | |||
1432 | return; | ||
1355 | } | 1433 | } |
1434 | |||
1356 | 1435 | ||
1436 | IScriptInstance instance=m_Scripts[itemID]; | ||
1437 | lockScriptsForRead(false); | ||
1438 | lockScriptsForWrite(true); | ||
1439 | m_Scripts.Remove(itemID); | ||
1440 | lockScriptsForWrite(false); | ||
1357 | instance.ClearQueue(); | 1441 | instance.ClearQueue(); |
1358 | 1442 | ||
1359 | instance.Stop(m_WaitForEventCompletionOnScriptStop); | 1443 | instance.Stop(m_WaitForEventCompletionOnScriptStop); |
@@ -1390,8 +1474,13 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1390 | 1474 | ||
1391 | ObjectRemoved handlerObjectRemoved = OnObjectRemoved; | 1475 | ObjectRemoved handlerObjectRemoved = OnObjectRemoved; |
1392 | if (handlerObjectRemoved != null) | 1476 | if (handlerObjectRemoved != null) |
1393 | handlerObjectRemoved(instance.ObjectID); | 1477 | { |
1478 | SceneObjectPart part = m_Scene.GetSceneObjectPart(localID); | ||
1479 | handlerObjectRemoved(part.UUID); | ||
1480 | } | ||
1394 | 1481 | ||
1482 | CleanAssemblies(); | ||
1483 | |||
1395 | ScriptRemoved handlerScriptRemoved = OnScriptRemoved; | 1484 | ScriptRemoved handlerScriptRemoved = OnScriptRemoved; |
1396 | if (handlerScriptRemoved != null) | 1485 | if (handlerScriptRemoved != null) |
1397 | handlerScriptRemoved(itemID); | 1486 | handlerScriptRemoved(itemID); |
@@ -1652,12 +1741,14 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1652 | private IScriptInstance GetInstance(UUID itemID) | 1741 | private IScriptInstance GetInstance(UUID itemID) |
1653 | { | 1742 | { |
1654 | IScriptInstance instance; | 1743 | IScriptInstance instance; |
1655 | lock (m_Scripts) | 1744 | lockScriptsForRead(true); |
1745 | if (!m_Scripts.ContainsKey(itemID)) | ||
1656 | { | 1746 | { |
1657 | if (!m_Scripts.ContainsKey(itemID)) | 1747 | lockScriptsForRead(false); |
1658 | return null; | 1748 | return null; |
1659 | instance = m_Scripts[itemID]; | ||
1660 | } | 1749 | } |
1750 | instance = m_Scripts[itemID]; | ||
1751 | lockScriptsForRead(false); | ||
1661 | return instance; | 1752 | return instance; |
1662 | } | 1753 | } |
1663 | 1754 | ||
@@ -1681,6 +1772,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1681 | return false; | 1772 | return false; |
1682 | } | 1773 | } |
1683 | 1774 | ||
1775 | [DebuggerNonUserCode] | ||
1684 | public void ApiResetScript(UUID itemID) | 1776 | public void ApiResetScript(UUID itemID) |
1685 | { | 1777 | { |
1686 | IScriptInstance instance = GetInstance(itemID); | 1778 | IScriptInstance instance = GetInstance(itemID); |
@@ -1737,6 +1829,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1737 | return UUID.Zero; | 1829 | return UUID.Zero; |
1738 | } | 1830 | } |
1739 | 1831 | ||
1832 | [DebuggerNonUserCode] | ||
1740 | public void SetState(UUID itemID, string newState) | 1833 | public void SetState(UUID itemID, string newState) |
1741 | { | 1834 | { |
1742 | IScriptInstance instance = GetInstance(itemID); | 1835 | IScriptInstance instance = GetInstance(itemID); |
@@ -1759,11 +1852,10 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1759 | 1852 | ||
1760 | List<IScriptInstance> instances = new List<IScriptInstance>(); | 1853 | List<IScriptInstance> instances = new List<IScriptInstance>(); |
1761 | 1854 | ||
1762 | lock (m_Scripts) | 1855 | lockScriptsForRead(true); |
1763 | { | 1856 | foreach (IScriptInstance instance in m_Scripts.Values) |
1764 | foreach (IScriptInstance instance in m_Scripts.Values) | ||
1765 | instances.Add(instance); | 1857 | instances.Add(instance); |
1766 | } | 1858 | lockScriptsForRead(false); |
1767 | 1859 | ||
1768 | foreach (IScriptInstance i in instances) | 1860 | foreach (IScriptInstance i in instances) |
1769 | { | 1861 | { |