diff options
Diffstat (limited to 'OpenSim/Region/ScriptEngine/XEngine/XEngine.cs')
-rw-r--r-- | OpenSim/Region/ScriptEngine/XEngine/XEngine.cs | 385 |
1 files changed, 252 insertions, 133 deletions
diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs index b261b9f..2713080 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,126 @@ 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 |
1248 | { | 1319 | UUID appDomain = assetID; |
1249 | // Create the object record | 1320 | |
1250 | if ((!m_Scripts.ContainsKey(itemID)) || | 1321 | |
1251 | (m_Scripts[itemID].AssetID != assetID)) | 1322 | |
1323 | lockScriptsForRead(true); | ||
1324 | if ((!m_Scripts.ContainsKey(itemID)) || | ||
1325 | (m_Scripts[itemID].AssetID != assetID)) | ||
1326 | { | ||
1327 | lockScriptsForRead(false); | ||
1328 | instance = new ScriptInstance(this, part, | ||
1329 | item, | ||
1330 | startParam, postOnRez, | ||
1331 | m_MaxScriptQueue); | ||
1332 | |||
1333 | |||
1334 | |||
1335 | if (part.ParentGroup.IsAttachment) | ||
1336 | appDomain = part.ParentGroup.RootPart.UUID; | ||
1337 | |||
1338 | if (!m_AppDomains.ContainsKey(appDomain)) | ||
1252 | { | 1339 | { |
1253 | UUID appDomain = assetID; | 1340 | try |
1254 | |||
1255 | if (part.ParentGroup.IsAttachment) | ||
1256 | appDomain = part.ParentGroup.RootPart.UUID; | ||
1257 | |||
1258 | if (!m_AppDomains.ContainsKey(appDomain)) | ||
1259 | { | 1341 | { |
1260 | try | 1342 | AppDomainSetup appSetup = new AppDomainSetup(); |
1261 | { | 1343 | appSetup.PrivateBinPath = Path.Combine( |
1262 | AppDomainSetup appSetup = new AppDomainSetup(); | 1344 | m_ScriptEnginesPath, |
1263 | appSetup.PrivateBinPath = Path.Combine( | 1345 | m_Scene.RegionInfo.RegionID.ToString()); |
1264 | m_ScriptEnginesPath, | ||
1265 | m_Scene.RegionInfo.RegionID.ToString()); | ||
1266 | 1346 | ||
1267 | Evidence baseEvidence = AppDomain.CurrentDomain.Evidence; | 1347 | Evidence baseEvidence = AppDomain.CurrentDomain.Evidence; |
1268 | Evidence evidence = new Evidence(baseEvidence); | 1348 | Evidence evidence = new Evidence(baseEvidence); |
1269 | 1349 | ||
1270 | AppDomain sandbox; | 1350 | AppDomain sandbox; |
1271 | if (m_AppDomainLoading) | 1351 | if (m_AppDomainLoading) |
1352 | { | ||
1353 | sandbox = AppDomain.CreateDomain( | ||
1354 | m_Scene.RegionInfo.RegionID.ToString(), | ||
1355 | evidence, appSetup); | ||
1356 | if (m_AppDomains.ContainsKey(appDomain)) | ||
1272 | { | 1357 | { |
1273 | sandbox = AppDomain.CreateDomain( | 1358 | m_AppDomains[appDomain].AssemblyResolve += |
1274 | m_Scene.RegionInfo.RegionID.ToString(), | ||
1275 | evidence, appSetup); | ||
1276 | sandbox.AssemblyResolve += | ||
1277 | new ResolveEventHandler( | 1359 | new ResolveEventHandler( |
1278 | AssemblyResolver.OnAssemblyResolve); | 1360 | AssemblyResolver.OnAssemblyResolve); |
1361 | if (m_DomainScripts.ContainsKey(appDomain)) | ||
1362 | { | ||
1363 | m_DomainScripts[appDomain].Add(itemID); | ||
1364 | } | ||
1365 | else | ||
1366 | { | ||
1367 | m_DomainScripts.Add(appDomain, new List<UUID>()); | ||
1368 | m_DomainScripts[appDomain].Add(itemID); | ||
1369 | } | ||
1279 | } | 1370 | } |
1280 | else | 1371 | else |
1281 | { | 1372 | { |
1282 | sandbox = AppDomain.CurrentDomain; | 1373 | m_AppDomains.Add(appDomain, sandbox); |
1374 | m_AppDomains[appDomain].AssemblyResolve += | ||
1375 | new ResolveEventHandler( | ||
1376 | AssemblyResolver.OnAssemblyResolve); | ||
1377 | if (m_DomainScripts.ContainsKey(appDomain)) | ||
1378 | { | ||
1379 | m_DomainScripts[appDomain].Add(itemID); | ||
1380 | } | ||
1381 | else | ||
1382 | { | ||
1383 | m_DomainScripts.Add(appDomain, new List<UUID>()); | ||
1384 | m_DomainScripts[appDomain].Add(itemID); | ||
1385 | } | ||
1386 | |||
1283 | } | 1387 | } |
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 | 1388 | ||
1295 | m_DomainScripts[appDomain] = new List<UUID>(); | ||
1296 | } | 1389 | } |
1297 | catch (Exception e) | 1390 | else |
1298 | { | 1391 | { |
1299 | m_log.ErrorFormat("[XEngine] Exception creating app domain:\n {0}", e.ToString()); | 1392 | 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 | } | 1393 | } |
1308 | } | ||
1309 | m_DomainScripts[appDomain].Add(itemID); | ||
1310 | |||
1311 | instance = new ScriptInstance(this, part, | ||
1312 | item, | ||
1313 | startParam, postOnRez, | ||
1314 | m_MaxScriptQueue); | ||
1315 | 1394 | ||
1316 | if (!instance.Load(m_AppDomains[appDomain], assembly, stateSource)) | 1395 | if (!instance.Load(m_AppDomains[appDomain], assembly, stateSource)) |
1317 | return false; | 1396 | return false; |
1318 | 1397 | ||
1319 | // if (DebugLevel >= 1) | 1398 | 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 | 1399 | ||
1325 | if (presence != null) | 1400 | m_DomainScripts[appDomain] = new List<UUID>(); |
1401 | } | ||
1402 | catch (Exception e) | ||
1326 | { | 1403 | { |
1327 | ShowScriptSaveResponse(item.OwnerID, | 1404 | m_log.ErrorFormat("[XEngine] Exception creating app domain:\n {0}", e.ToString()); |
1328 | assetID, "Compile successful", true); | 1405 | m_ScriptErrorMessage += "Exception creating app domain:\n"; |
1406 | m_ScriptFailCount++; | ||
1407 | lock (m_AddingAssemblies) | ||
1408 | { | ||
1409 | m_AddingAssemblies[assembly]--; | ||
1410 | } | ||
1411 | return false; | ||
1329 | } | 1412 | } |
1413 | } | ||
1414 | |||
1330 | 1415 | ||
1331 | instance.AppDomain = appDomain; | 1416 | instance.Load(m_AppDomains[appDomain], assembly, stateSource); |
1332 | instance.LineMap = linemap; | 1417 | // m_log.DebugFormat( |
1418 | // "[XEngine] Loaded script {0}.{1}, script UUID {2}, prim UUID {3} @ {4}.{5}", | ||
1419 | // part.ParentGroup.RootPart.Name, item.Name, assetID, part.UUID, | ||
1420 | // part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName); | ||
1333 | 1421 | ||
1334 | m_Scripts[itemID] = instance; | 1422 | if (presence != null) |
1423 | { | ||
1424 | ShowScriptSaveResponse(item.OwnerID, | ||
1425 | assetID, "Compile successful", true); | ||
1335 | } | 1426 | } |
1336 | } | ||
1337 | 1427 | ||
1428 | instance.AppDomain = appDomain; | ||
1429 | instance.LineMap = linemap; | ||
1430 | lockScriptsForWrite(true); | ||
1431 | m_Scripts[itemID] = instance; | ||
1432 | lockScriptsForWrite(false); | ||
1433 | } | ||
1434 | else | ||
1435 | { | ||
1436 | lockScriptsForRead(false); | ||
1437 | } | ||
1338 | lock (m_PrimObjects) | 1438 | lock (m_PrimObjects) |
1339 | { | 1439 | { |
1340 | if (!m_PrimObjects.ContainsKey(localID)) | 1440 | if (!m_PrimObjects.ContainsKey(localID)) |
@@ -1352,7 +1452,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1352 | m_AddingAssemblies[assembly]--; | 1452 | m_AddingAssemblies[assembly]--; |
1353 | } | 1453 | } |
1354 | 1454 | ||
1355 | if (instance != null) | 1455 | if (instance!=null) |
1356 | instance.Init(); | 1456 | instance.Init(); |
1357 | 1457 | ||
1358 | bool runIt; | 1458 | bool runIt; |
@@ -1375,18 +1475,28 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1375 | m_CompileDict.Remove(itemID); | 1475 | m_CompileDict.Remove(itemID); |
1376 | } | 1476 | } |
1377 | 1477 | ||
1378 | IScriptInstance instance = null; | 1478 | lockScriptsForRead(true); |
1379 | 1479 | // Do we even have it? | |
1380 | lock (m_Scripts) | 1480 | if (!m_Scripts.ContainsKey(itemID)) |
1381 | { | 1481 | { |
1382 | // Do we even have it? | 1482 | // Do we even have it? |
1383 | if (!m_Scripts.ContainsKey(itemID)) | 1483 | if (!m_Scripts.ContainsKey(itemID)) |
1384 | return; | 1484 | return; |
1385 | 1485 | ||
1386 | instance = m_Scripts[itemID]; | 1486 | lockScriptsForRead(false); |
1487 | lockScriptsForWrite(true); | ||
1387 | m_Scripts.Remove(itemID); | 1488 | m_Scripts.Remove(itemID); |
1489 | lockScriptsForWrite(false); | ||
1490 | |||
1491 | return; | ||
1388 | } | 1492 | } |
1493 | |||
1389 | 1494 | ||
1495 | IScriptInstance instance=m_Scripts[itemID]; | ||
1496 | lockScriptsForRead(false); | ||
1497 | lockScriptsForWrite(true); | ||
1498 | m_Scripts.Remove(itemID); | ||
1499 | lockScriptsForWrite(false); | ||
1390 | instance.ClearQueue(); | 1500 | instance.ClearQueue(); |
1391 | 1501 | ||
1392 | instance.Stop(m_WaitForEventCompletionOnScriptStop); | 1502 | instance.Stop(m_WaitForEventCompletionOnScriptStop); |
@@ -1423,8 +1533,14 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1423 | 1533 | ||
1424 | ObjectRemoved handlerObjectRemoved = OnObjectRemoved; | 1534 | ObjectRemoved handlerObjectRemoved = OnObjectRemoved; |
1425 | if (handlerObjectRemoved != null) | 1535 | if (handlerObjectRemoved != null) |
1426 | handlerObjectRemoved(instance.ObjectID); | 1536 | { |
1537 | SceneObjectPart part = m_Scene.GetSceneObjectPart(localID); | ||
1538 | if (part != null) | ||
1539 | handlerObjectRemoved(part.UUID); | ||
1540 | } | ||
1427 | 1541 | ||
1542 | CleanAssemblies(); | ||
1543 | |||
1428 | ScriptRemoved handlerScriptRemoved = OnScriptRemoved; | 1544 | ScriptRemoved handlerScriptRemoved = OnScriptRemoved; |
1429 | if (handlerScriptRemoved != null) | 1545 | if (handlerScriptRemoved != null) |
1430 | handlerScriptRemoved(itemID); | 1546 | handlerScriptRemoved(itemID); |
@@ -1685,12 +1801,14 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1685 | private IScriptInstance GetInstance(UUID itemID) | 1801 | private IScriptInstance GetInstance(UUID itemID) |
1686 | { | 1802 | { |
1687 | IScriptInstance instance; | 1803 | IScriptInstance instance; |
1688 | lock (m_Scripts) | 1804 | lockScriptsForRead(true); |
1805 | if (!m_Scripts.ContainsKey(itemID)) | ||
1689 | { | 1806 | { |
1690 | if (!m_Scripts.ContainsKey(itemID)) | 1807 | lockScriptsForRead(false); |
1691 | return null; | 1808 | return null; |
1692 | instance = m_Scripts[itemID]; | ||
1693 | } | 1809 | } |
1810 | instance = m_Scripts[itemID]; | ||
1811 | lockScriptsForRead(false); | ||
1694 | return instance; | 1812 | return instance; |
1695 | } | 1813 | } |
1696 | 1814 | ||
@@ -1712,6 +1830,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1712 | return instance != null && instance.Running; | 1830 | return instance != null && instance.Running; |
1713 | } | 1831 | } |
1714 | 1832 | ||
1833 | [DebuggerNonUserCode] | ||
1715 | public void ApiResetScript(UUID itemID) | 1834 | public void ApiResetScript(UUID itemID) |
1716 | { | 1835 | { |
1717 | IScriptInstance instance = GetInstance(itemID); | 1836 | IScriptInstance instance = GetInstance(itemID); |
@@ -1769,6 +1888,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1769 | return instance != null ? instance.GetDetectID(idx) : UUID.Zero; | 1888 | return instance != null ? instance.GetDetectID(idx) : UUID.Zero; |
1770 | } | 1889 | } |
1771 | 1890 | ||
1891 | [DebuggerNonUserCode] | ||
1772 | public void SetState(UUID itemID, string newState) | 1892 | public void SetState(UUID itemID, string newState) |
1773 | { | 1893 | { |
1774 | IScriptInstance instance = GetInstance(itemID); | 1894 | IScriptInstance instance = GetInstance(itemID); |
@@ -1789,11 +1909,10 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1789 | 1909 | ||
1790 | List<IScriptInstance> instances = new List<IScriptInstance>(); | 1910 | List<IScriptInstance> instances = new List<IScriptInstance>(); |
1791 | 1911 | ||
1792 | lock (m_Scripts) | 1912 | lockScriptsForRead(true); |
1793 | { | 1913 | foreach (IScriptInstance instance in m_Scripts.Values) |
1794 | foreach (IScriptInstance instance in m_Scripts.Values) | ||
1795 | instances.Add(instance); | 1914 | instances.Add(instance); |
1796 | } | 1915 | lockScriptsForRead(false); |
1797 | 1916 | ||
1798 | foreach (IScriptInstance i in instances) | 1917 | foreach (IScriptInstance i in instances) |
1799 | { | 1918 | { |