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 0460f22..9f05666 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.Reflection; | 34 | using System.Reflection; |
@@ -128,6 +129,8 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
128 | private Dictionary<UUID, IScriptInstance> m_Scripts = | 129 | private Dictionary<UUID, IScriptInstance> m_Scripts = |
129 | new Dictionary<UUID, IScriptInstance>(); | 130 | new Dictionary<UUID, IScriptInstance>(); |
130 | 131 | ||
132 | private OpenMetaverse.ReaderWriterLockSlim m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim(); | ||
133 | |||
131 | // Maps the asset ID to the assembly | 134 | // Maps the asset ID to the assembly |
132 | 135 | ||
133 | private Dictionary<UUID, string> m_Assemblies = | 136 | private Dictionary<UUID, string> m_Assemblies = |
@@ -150,6 +153,71 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
150 | IWorkItemResult m_CurrentCompile = null; | 153 | IWorkItemResult m_CurrentCompile = null; |
151 | private Dictionary<UUID, int> m_CompileDict = new Dictionary<UUID, int>(); | 154 | private Dictionary<UUID, int> m_CompileDict = new Dictionary<UUID, int>(); |
152 | 155 | ||
156 | private void lockScriptsForRead(bool locked) | ||
157 | { | ||
158 | if (locked) | ||
159 | { | ||
160 | if (m_scriptsLock.RecursiveReadCount > 0) | ||
161 | { | ||
162 | 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."); | ||
163 | m_scriptsLock.ExitReadLock(); | ||
164 | } | ||
165 | if (m_scriptsLock.RecursiveWriteCount > 0) | ||
166 | { | ||
167 | m_log.Error("[XEngine.m_Scripts] Recursive write lock requested. This should not happen and means something needs to be fixed."); | ||
168 | m_scriptsLock.ExitWriteLock(); | ||
169 | } | ||
170 | |||
171 | while (!m_scriptsLock.TryEnterReadLock(60000)) | ||
172 | { | ||
173 | 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."); | ||
174 | if (m_scriptsLock.IsWriteLockHeld) | ||
175 | { | ||
176 | m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim(); | ||
177 | } | ||
178 | } | ||
179 | } | ||
180 | else | ||
181 | { | ||
182 | if (m_scriptsLock.RecursiveReadCount > 0) | ||
183 | { | ||
184 | m_scriptsLock.ExitReadLock(); | ||
185 | } | ||
186 | } | ||
187 | } | ||
188 | private void lockScriptsForWrite(bool locked) | ||
189 | { | ||
190 | if (locked) | ||
191 | { | ||
192 | if (m_scriptsLock.RecursiveReadCount > 0) | ||
193 | { | ||
194 | 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."); | ||
195 | m_scriptsLock.ExitReadLock(); | ||
196 | } | ||
197 | if (m_scriptsLock.RecursiveWriteCount > 0) | ||
198 | { | ||
199 | m_log.Error("[XEngine.m_Scripts] Recursive write lock requested. This should not happen and means something needs to be fixed."); | ||
200 | m_scriptsLock.ExitWriteLock(); | ||
201 | } | ||
202 | |||
203 | while (!m_scriptsLock.TryEnterWriteLock(60000)) | ||
204 | { | ||
205 | 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."); | ||
206 | if (m_scriptsLock.IsWriteLockHeld) | ||
207 | { | ||
208 | m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim(); | ||
209 | } | ||
210 | } | ||
211 | } | ||
212 | else | ||
213 | { | ||
214 | if (m_scriptsLock.RecursiveWriteCount > 0) | ||
215 | { | ||
216 | m_scriptsLock.ExitWriteLock(); | ||
217 | } | ||
218 | } | ||
219 | } | ||
220 | |||
153 | public string ScriptEngineName | 221 | public string ScriptEngineName |
154 | { | 222 | { |
155 | get { return "XEngine"; } | 223 | get { return "XEngine"; } |
@@ -576,64 +644,69 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
576 | { | 644 | { |
577 | if (!m_Enabled) | 645 | if (!m_Enabled) |
578 | return; | 646 | return; |
647 | lockScriptsForRead(true); | ||
579 | 648 | ||
580 | lock (m_Scripts) | 649 | List<IScriptInstance> instancesToDel = new List<IScriptInstance>(m_Scripts.Values); |
581 | { | ||
582 | m_log.InfoFormat( | ||
583 | "[XEngine]: Shutting down {0} scripts in {1}", m_Scripts.Count, m_Scene.RegionInfo.RegionName); | ||
584 | 650 | ||
585 | foreach (IScriptInstance instance in m_Scripts.Values) | 651 | // foreach (IScriptInstance instance in m_Scripts.Values) |
652 | foreach (IScriptInstance instance in instancesToDel) | ||
653 | { | ||
654 | // Force a final state save | ||
655 | // | ||
656 | if (m_Assemblies.ContainsKey(instance.AssetID)) | ||
586 | { | 657 | { |
587 | // Force a final state save | 658 | string assembly = m_Assemblies[instance.AssetID]; |
588 | // | ||
589 | if (m_Assemblies.ContainsKey(instance.AssetID)) | ||
590 | { | ||
591 | string assembly = m_Assemblies[instance.AssetID]; | ||
592 | 659 | ||
593 | try | 660 | try |
594 | { | 661 | { |
595 | instance.SaveState(assembly); | 662 | instance.SaveState(assembly); |
596 | } | ||
597 | catch (Exception e) | ||
598 | { | ||
599 | m_log.Error( | ||
600 | string.Format( | ||
601 | "[XEngine]: Failed final state save for script {0}.{1}, item UUID {2}, prim UUID {3} in {4}. Exception ", | ||
602 | instance.PrimName, instance.ScriptName, instance.ItemID, instance.ObjectID, World.Name) | ||
603 | , e); | ||
604 | } | ||
605 | } | 663 | } |
664 | catch (Exception e) | ||
665 | { | ||
666 | m_log.Error( | ||
667 | string.Format( | ||
668 | "[XEngine]: Failed final state save for script {0}.{1}, item UUID {2}, prim UUID {3} in {4}. Exception ", | ||
669 | instance.PrimName, instance.ScriptName, instance.ItemID, instance.ObjectID, World.Name) | ||
670 | , e); | ||
671 | } | ||
672 | } | ||
606 | 673 | ||
607 | // Clear the event queue and abort the instance thread | 674 | // Clear the event queue and abort the instance thread |
608 | // | 675 | // |
609 | instance.ClearQueue(); | 676 | instance.ClearQueue(); |
610 | instance.Stop(0); | 677 | instance.Stop(0); |
611 | 678 | ||
612 | // Release events, timer, etc | 679 | // Release events, timer, etc |
613 | // | 680 | // |
614 | instance.DestroyScriptInstance(); | 681 | instance.DestroyScriptInstance(); |
615 | 682 | ||
616 | // Unload scripts and app domains. | 683 | // Unload scripts and app domains |
617 | // Must be done explicitly because they have infinite | 684 | // Must be done explicitly because they have infinite |
618 | // lifetime. | 685 | // lifetime |
619 | // However, don't bother to do this if the simulator is shutting | 686 | // |
620 | // down since it takes a long time with many scripts. | 687 | // if (!m_SimulatorShuttingDown) |
621 | if (!m_SimulatorShuttingDown) | 688 | { |
689 | m_DomainScripts[instance.AppDomain].Remove(instance.ItemID); | ||
690 | if (m_DomainScripts[instance.AppDomain].Count == 0) | ||
622 | { | 691 | { |
623 | m_DomainScripts[instance.AppDomain].Remove(instance.ItemID); | 692 | m_DomainScripts.Remove(instance.AppDomain); |
624 | if (m_DomainScripts[instance.AppDomain].Count == 0) | 693 | UnloadAppDomain(instance.AppDomain); |
625 | { | ||
626 | m_DomainScripts.Remove(instance.AppDomain); | ||
627 | UnloadAppDomain(instance.AppDomain); | ||
628 | } | ||
629 | } | 694 | } |
630 | } | 695 | } |
631 | 696 | ||
632 | m_Scripts.Clear(); | 697 | // m_Scripts.Clear(); |
633 | m_PrimObjects.Clear(); | 698 | // m_PrimObjects.Clear(); |
634 | m_Assemblies.Clear(); | 699 | // m_Assemblies.Clear(); |
635 | m_DomainScripts.Clear(); | 700 | // m_DomainScripts.Clear(); |
636 | } | 701 | } |
702 | lockScriptsForRead(false); | ||
703 | lockScriptsForWrite(true); | ||
704 | m_Scripts.Clear(); | ||
705 | lockScriptsForWrite(false); | ||
706 | m_PrimObjects.Clear(); | ||
707 | m_Assemblies.Clear(); | ||
708 | m_DomainScripts.Clear(); | ||
709 | |||
637 | lock (m_ScriptEngines) | 710 | lock (m_ScriptEngines) |
638 | { | 711 | { |
639 | m_ScriptEngines.Remove(this); | 712 | m_ScriptEngines.Remove(this); |
@@ -702,22 +775,20 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
702 | 775 | ||
703 | List<IScriptInstance> instances = new List<IScriptInstance>(); | 776 | List<IScriptInstance> instances = new List<IScriptInstance>(); |
704 | 777 | ||
705 | lock (m_Scripts) | 778 | lockScriptsForRead(true); |
706 | { | 779 | foreach (IScriptInstance instance in m_Scripts.Values) |
707 | foreach (IScriptInstance instance in m_Scripts.Values) | ||
708 | instances.Add(instance); | 780 | instances.Add(instance); |
709 | } | 781 | lockScriptsForRead(false); |
710 | 782 | ||
711 | foreach (IScriptInstance i in instances) | 783 | foreach (IScriptInstance i in instances) |
712 | { | 784 | { |
713 | string assembly = String.Empty; | 785 | string assembly = String.Empty; |
714 | 786 | ||
715 | lock (m_Scripts) | 787 | |
716 | { | ||
717 | if (!m_Assemblies.ContainsKey(i.AssetID)) | 788 | if (!m_Assemblies.ContainsKey(i.AssetID)) |
718 | continue; | 789 | continue; |
719 | assembly = m_Assemblies[i.AssetID]; | 790 | assembly = m_Assemblies[i.AssetID]; |
720 | } | 791 | |
721 | 792 | ||
722 | try | 793 | try |
723 | { | 794 | { |
@@ -1119,96 +1190,99 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1119 | } | 1190 | } |
1120 | 1191 | ||
1121 | ScriptInstance instance = null; | 1192 | ScriptInstance instance = null; |
1122 | lock (m_Scripts) | 1193 | // Create the object record |
1194 | lockScriptsForRead(true); | ||
1195 | if ((!m_Scripts.ContainsKey(itemID)) || | ||
1196 | (m_Scripts[itemID].AssetID != assetID)) | ||
1123 | { | 1197 | { |
1124 | // Create the object record | 1198 | lockScriptsForRead(false); |
1125 | if ((!m_Scripts.ContainsKey(itemID)) || | ||
1126 | (m_Scripts[itemID].AssetID != assetID)) | ||
1127 | { | ||
1128 | UUID appDomain = assetID; | ||
1129 | 1199 | ||
1130 | if (part.ParentGroup.IsAttachment) | 1200 | UUID appDomain = assetID; |
1131 | appDomain = part.ParentGroup.RootPart.UUID; | ||
1132 | 1201 | ||
1133 | if (!m_AppDomains.ContainsKey(appDomain)) | 1202 | if (part.ParentGroup.IsAttachment) |
1134 | { | 1203 | appDomain = part.ParentGroup.RootPart.UUID; |
1135 | try | ||
1136 | { | ||
1137 | AppDomainSetup appSetup = new AppDomainSetup(); | ||
1138 | appSetup.PrivateBinPath = Path.Combine( | ||
1139 | m_ScriptEnginesPath, | ||
1140 | m_Scene.RegionInfo.RegionID.ToString()); | ||
1141 | 1204 | ||
1142 | Evidence baseEvidence = AppDomain.CurrentDomain.Evidence; | 1205 | if (!m_AppDomains.ContainsKey(appDomain)) |
1143 | Evidence evidence = new Evidence(baseEvidence); | 1206 | { |
1207 | try | ||
1208 | { | ||
1209 | AppDomainSetup appSetup = new AppDomainSetup(); | ||
1210 | appSetup.PrivateBinPath = Path.Combine( | ||
1211 | m_ScriptEnginesPath, | ||
1212 | m_Scene.RegionInfo.RegionID.ToString()); | ||
1144 | 1213 | ||
1145 | AppDomain sandbox; | 1214 | Evidence baseEvidence = AppDomain.CurrentDomain.Evidence; |
1146 | if (m_AppDomainLoading) | 1215 | Evidence evidence = new Evidence(baseEvidence); |
1147 | { | ||
1148 | sandbox = AppDomain.CreateDomain( | ||
1149 | m_Scene.RegionInfo.RegionID.ToString(), | ||
1150 | evidence, appSetup); | ||
1151 | sandbox.AssemblyResolve += | ||
1152 | new ResolveEventHandler( | ||
1153 | AssemblyResolver.OnAssemblyResolve); | ||
1154 | } | ||
1155 | else | ||
1156 | { | ||
1157 | sandbox = AppDomain.CurrentDomain; | ||
1158 | } | ||
1159 | |||
1160 | //PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel(); | ||
1161 | //AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition(); | ||
1162 | //PermissionSet sandboxPermissionSet = sandboxPolicy.GetNamedPermissionSet("Internet"); | ||
1163 | //PolicyStatement sandboxPolicyStatement = new PolicyStatement(sandboxPermissionSet); | ||
1164 | //CodeGroup sandboxCodeGroup = new UnionCodeGroup(sandboxMembershipCondition, sandboxPolicyStatement); | ||
1165 | //sandboxPolicy.RootCodeGroup = sandboxCodeGroup; | ||
1166 | //sandbox.SetAppDomainPolicy(sandboxPolicy); | ||
1167 | |||
1168 | m_AppDomains[appDomain] = sandbox; | ||
1169 | 1216 | ||
1170 | m_DomainScripts[appDomain] = new List<UUID>(); | 1217 | AppDomain sandbox; |
1218 | if (m_AppDomainLoading) | ||
1219 | { | ||
1220 | sandbox = AppDomain.CreateDomain( | ||
1221 | m_Scene.RegionInfo.RegionID.ToString(), | ||
1222 | evidence, appSetup); | ||
1223 | m_AppDomains[appDomain].AssemblyResolve += | ||
1224 | new ResolveEventHandler( | ||
1225 | AssemblyResolver.OnAssemblyResolve); | ||
1171 | } | 1226 | } |
1172 | catch (Exception e) | 1227 | else |
1173 | { | 1228 | { |
1174 | m_log.ErrorFormat("[XEngine] Exception creating app domain:\n {0}", e.ToString()); | 1229 | sandbox = AppDomain.CurrentDomain; |
1175 | m_ScriptErrorMessage += "Exception creating app domain:\n"; | ||
1176 | m_ScriptFailCount++; | ||
1177 | lock (m_AddingAssemblies) | ||
1178 | { | ||
1179 | m_AddingAssemblies[assembly]--; | ||
1180 | } | ||
1181 | return false; | ||
1182 | } | 1230 | } |
1183 | } | ||
1184 | m_DomainScripts[appDomain].Add(itemID); | ||
1185 | |||
1186 | instance = new ScriptInstance(this, part, | ||
1187 | itemID, assetID, assembly, | ||
1188 | m_AppDomains[appDomain], | ||
1189 | part.ParentGroup.RootPart.Name, | ||
1190 | item.Name, startParam, postOnRez, | ||
1191 | stateSource, m_MaxScriptQueue); | ||
1192 | |||
1193 | // if (DebugLevel >= 1) | ||
1194 | // m_log.DebugFormat( | ||
1195 | // "[XEngine] Loaded script {0}.{1}, item UUID {2}, prim UUID {3} @ {4}.{5}", | ||
1196 | // part.ParentGroup.RootPart.Name, item.Name, itemID, part.UUID, | ||
1197 | // part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName); | ||
1198 | 1231 | ||
1199 | if (presence != null) | 1232 | //PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel(); |
1233 | //AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition(); | ||
1234 | //PermissionSet sandboxPermissionSet = sandboxPolicy.GetNamedPermissionSet("Internet"); | ||
1235 | //PolicyStatement sandboxPolicyStatement = new PolicyStatement(sandboxPermissionSet); | ||
1236 | //CodeGroup sandboxCodeGroup = new UnionCodeGroup(sandboxMembershipCondition, sandboxPolicyStatement); | ||
1237 | //sandboxPolicy.RootCodeGroup = sandboxCodeGroup; | ||
1238 | //sandbox.SetAppDomainPolicy(sandboxPolicy); | ||
1239 | |||
1240 | m_AppDomains[appDomain] = sandbox; | ||
1241 | |||
1242 | m_DomainScripts[appDomain] = new List<UUID>(); | ||
1243 | } | ||
1244 | catch (Exception e) | ||
1200 | { | 1245 | { |
1201 | ShowScriptSaveResponse(item.OwnerID, | 1246 | m_log.ErrorFormat("[XEngine] Exception creating app domain:\n {0}", e.ToString()); |
1202 | assetID, "Compile successful", true); | 1247 | m_ScriptErrorMessage += "Exception creating app domain:\n"; |
1248 | m_ScriptFailCount++; | ||
1249 | lock (m_AddingAssemblies) | ||
1250 | { | ||
1251 | m_AddingAssemblies[assembly]--; | ||
1252 | } | ||
1253 | return false; | ||
1203 | } | 1254 | } |
1255 | } | ||
1256 | m_DomainScripts[appDomain].Add(itemID); | ||
1257 | |||
1258 | instance = new ScriptInstance(this, part, | ||
1259 | itemID, assetID, assembly, | ||
1260 | m_AppDomains[appDomain], | ||
1261 | part.ParentGroup.RootPart.Name, | ||
1262 | item.Name, startParam, postOnRez, | ||
1263 | stateSource, m_MaxScriptQueue); | ||
1264 | |||
1265 | // m_log.DebugFormat( | ||
1266 | // "[XEngine] Loaded script {0}.{1}, script UUID {2}, prim UUID {3} @ {4}.{5}", | ||
1267 | // part.ParentGroup.RootPart.Name, item.Name, assetID, part.UUID, | ||
1268 | // part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName); | ||
1204 | 1269 | ||
1205 | instance.AppDomain = appDomain; | 1270 | if (presence != null) |
1206 | instance.LineMap = linemap; | 1271 | { |
1207 | 1272 | ShowScriptSaveResponse(item.OwnerID, | |
1208 | m_Scripts[itemID] = instance; | 1273 | assetID, "Compile successful", true); |
1209 | } | 1274 | } |
1210 | } | ||
1211 | 1275 | ||
1276 | instance.AppDomain = appDomain; | ||
1277 | instance.LineMap = linemap; | ||
1278 | lockScriptsForWrite(true); | ||
1279 | m_Scripts[itemID] = instance; | ||
1280 | lockScriptsForWrite(false); | ||
1281 | } | ||
1282 | else | ||
1283 | { | ||
1284 | lockScriptsForRead(false); | ||
1285 | } | ||
1212 | lock (m_PrimObjects) | 1286 | lock (m_PrimObjects) |
1213 | { | 1287 | { |
1214 | if (!m_PrimObjects.ContainsKey(localID)) | 1288 | if (!m_PrimObjects.ContainsKey(localID)) |
@@ -1226,7 +1300,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1226 | m_AddingAssemblies[assembly]--; | 1300 | m_AddingAssemblies[assembly]--; |
1227 | } | 1301 | } |
1228 | 1302 | ||
1229 | if (instance != null) | 1303 | if (instance!=null) |
1230 | instance.Init(); | 1304 | instance.Init(); |
1231 | 1305 | ||
1232 | bool runIt; | 1306 | bool runIt; |
@@ -1249,18 +1323,28 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1249 | m_CompileDict.Remove(itemID); | 1323 | m_CompileDict.Remove(itemID); |
1250 | } | 1324 | } |
1251 | 1325 | ||
1252 | IScriptInstance instance = null; | 1326 | lockScriptsForRead(true); |
1253 | 1327 | // Do we even have it? | |
1254 | lock (m_Scripts) | 1328 | if (!m_Scripts.ContainsKey(itemID)) |
1255 | { | 1329 | { |
1256 | // Do we even have it? | 1330 | // Do we even have it? |
1257 | if (!m_Scripts.ContainsKey(itemID)) | 1331 | if (!m_Scripts.ContainsKey(itemID)) |
1258 | return; | 1332 | return; |
1259 | 1333 | ||
1260 | instance = m_Scripts[itemID]; | 1334 | lockScriptsForRead(false); |
1335 | lockScriptsForWrite(true); | ||
1261 | m_Scripts.Remove(itemID); | 1336 | m_Scripts.Remove(itemID); |
1337 | lockScriptsForWrite(false); | ||
1338 | |||
1339 | return; | ||
1262 | } | 1340 | } |
1341 | |||
1263 | 1342 | ||
1343 | IScriptInstance instance=m_Scripts[itemID]; | ||
1344 | lockScriptsForRead(false); | ||
1345 | lockScriptsForWrite(true); | ||
1346 | m_Scripts.Remove(itemID); | ||
1347 | lockScriptsForWrite(false); | ||
1264 | instance.ClearQueue(); | 1348 | instance.ClearQueue(); |
1265 | 1349 | ||
1266 | // Give the script some time to finish processing its last event. Simply aborting the script thread can | 1350 | // Give the script some time to finish processing its last event. Simply aborting the script thread can |
@@ -1299,8 +1383,13 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1299 | 1383 | ||
1300 | ObjectRemoved handlerObjectRemoved = OnObjectRemoved; | 1384 | ObjectRemoved handlerObjectRemoved = OnObjectRemoved; |
1301 | if (handlerObjectRemoved != null) | 1385 | if (handlerObjectRemoved != null) |
1302 | handlerObjectRemoved(instance.ObjectID); | 1386 | { |
1387 | SceneObjectPart part = m_Scene.GetSceneObjectPart(localID); | ||
1388 | handlerObjectRemoved(part.UUID); | ||
1389 | } | ||
1303 | 1390 | ||
1391 | CleanAssemblies(); | ||
1392 | |||
1304 | ScriptRemoved handlerScriptRemoved = OnScriptRemoved; | 1393 | ScriptRemoved handlerScriptRemoved = OnScriptRemoved; |
1305 | if (handlerScriptRemoved != null) | 1394 | if (handlerScriptRemoved != null) |
1306 | handlerScriptRemoved(itemID); | 1395 | handlerScriptRemoved(itemID); |
@@ -1561,12 +1650,14 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1561 | private IScriptInstance GetInstance(UUID itemID) | 1650 | private IScriptInstance GetInstance(UUID itemID) |
1562 | { | 1651 | { |
1563 | IScriptInstance instance; | 1652 | IScriptInstance instance; |
1564 | lock (m_Scripts) | 1653 | lockScriptsForRead(true); |
1654 | if (!m_Scripts.ContainsKey(itemID)) | ||
1565 | { | 1655 | { |
1566 | if (!m_Scripts.ContainsKey(itemID)) | 1656 | lockScriptsForRead(false); |
1567 | return null; | 1657 | return null; |
1568 | instance = m_Scripts[itemID]; | ||
1569 | } | 1658 | } |
1659 | instance = m_Scripts[itemID]; | ||
1660 | lockScriptsForRead(false); | ||
1570 | return instance; | 1661 | return instance; |
1571 | } | 1662 | } |
1572 | 1663 | ||
@@ -1590,6 +1681,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1590 | return false; | 1681 | return false; |
1591 | } | 1682 | } |
1592 | 1683 | ||
1684 | [DebuggerNonUserCode] | ||
1593 | public void ApiResetScript(UUID itemID) | 1685 | public void ApiResetScript(UUID itemID) |
1594 | { | 1686 | { |
1595 | IScriptInstance instance = GetInstance(itemID); | 1687 | IScriptInstance instance = GetInstance(itemID); |
@@ -1651,6 +1743,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1651 | return UUID.Zero; | 1743 | return UUID.Zero; |
1652 | } | 1744 | } |
1653 | 1745 | ||
1746 | [DebuggerNonUserCode] | ||
1654 | public void SetState(UUID itemID, string newState) | 1747 | public void SetState(UUID itemID, string newState) |
1655 | { | 1748 | { |
1656 | IScriptInstance instance = GetInstance(itemID); | 1749 | IScriptInstance instance = GetInstance(itemID); |
@@ -1673,11 +1766,10 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1673 | 1766 | ||
1674 | List<IScriptInstance> instances = new List<IScriptInstance>(); | 1767 | List<IScriptInstance> instances = new List<IScriptInstance>(); |
1675 | 1768 | ||
1676 | lock (m_Scripts) | 1769 | lockScriptsForRead(true); |
1677 | { | 1770 | foreach (IScriptInstance instance in m_Scripts.Values) |
1678 | foreach (IScriptInstance instance in m_Scripts.Values) | ||
1679 | instances.Add(instance); | 1771 | instances.Add(instance); |
1680 | } | 1772 | lockScriptsForRead(false); |
1681 | 1773 | ||
1682 | foreach (IScriptInstance i in instances) | 1774 | foreach (IScriptInstance i in instances) |
1683 | { | 1775 | { |