diff options
Diffstat (limited to 'OpenSim/Region/ScriptEngine/XEngine')
-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 5a3f002..2d17977 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 | { |
@@ -1117,96 +1188,99 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1117 | } | 1188 | } |
1118 | 1189 | ||
1119 | ScriptInstance instance = null; | 1190 | ScriptInstance instance = null; |
1120 | lock (m_Scripts) | 1191 | // Create the object record |
1192 | lockScriptsForRead(true); | ||
1193 | if ((!m_Scripts.ContainsKey(itemID)) || | ||
1194 | (m_Scripts[itemID].AssetID != assetID)) | ||
1121 | { | 1195 | { |
1122 | // Create the object record | 1196 | lockScriptsForRead(false); |
1123 | if ((!m_Scripts.ContainsKey(itemID)) || | ||
1124 | (m_Scripts[itemID].AssetID != assetID)) | ||
1125 | { | ||
1126 | UUID appDomain = assetID; | ||
1127 | 1197 | ||
1128 | if (part.ParentGroup.IsAttachment) | 1198 | UUID appDomain = assetID; |
1129 | appDomain = part.ParentGroup.RootPart.UUID; | ||
1130 | 1199 | ||
1131 | if (!m_AppDomains.ContainsKey(appDomain)) | 1200 | if (part.ParentGroup.IsAttachment) |
1132 | { | 1201 | appDomain = part.ParentGroup.RootPart.UUID; |
1133 | try | ||
1134 | { | ||
1135 | AppDomainSetup appSetup = new AppDomainSetup(); | ||
1136 | appSetup.PrivateBinPath = Path.Combine( | ||
1137 | m_ScriptEnginesPath, | ||
1138 | m_Scene.RegionInfo.RegionID.ToString()); | ||
1139 | 1202 | ||
1140 | Evidence baseEvidence = AppDomain.CurrentDomain.Evidence; | 1203 | if (!m_AppDomains.ContainsKey(appDomain)) |
1141 | Evidence evidence = new Evidence(baseEvidence); | 1204 | { |
1205 | try | ||
1206 | { | ||
1207 | AppDomainSetup appSetup = new AppDomainSetup(); | ||
1208 | appSetup.PrivateBinPath = Path.Combine( | ||
1209 | m_ScriptEnginesPath, | ||
1210 | m_Scene.RegionInfo.RegionID.ToString()); | ||
1142 | 1211 | ||
1143 | AppDomain sandbox; | 1212 | Evidence baseEvidence = AppDomain.CurrentDomain.Evidence; |
1144 | if (m_AppDomainLoading) | 1213 | Evidence evidence = new Evidence(baseEvidence); |
1145 | { | ||
1146 | sandbox = AppDomain.CreateDomain( | ||
1147 | m_Scene.RegionInfo.RegionID.ToString(), | ||
1148 | evidence, appSetup); | ||
1149 | sandbox.AssemblyResolve += | ||
1150 | new ResolveEventHandler( | ||
1151 | AssemblyResolver.OnAssemblyResolve); | ||
1152 | } | ||
1153 | else | ||
1154 | { | ||
1155 | sandbox = AppDomain.CurrentDomain; | ||
1156 | } | ||
1157 | |||
1158 | //PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel(); | ||
1159 | //AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition(); | ||
1160 | //PermissionSet sandboxPermissionSet = sandboxPolicy.GetNamedPermissionSet("Internet"); | ||
1161 | //PolicyStatement sandboxPolicyStatement = new PolicyStatement(sandboxPermissionSet); | ||
1162 | //CodeGroup sandboxCodeGroup = new UnionCodeGroup(sandboxMembershipCondition, sandboxPolicyStatement); | ||
1163 | //sandboxPolicy.RootCodeGroup = sandboxCodeGroup; | ||
1164 | //sandbox.SetAppDomainPolicy(sandboxPolicy); | ||
1165 | |||
1166 | m_AppDomains[appDomain] = sandbox; | ||
1167 | 1214 | ||
1168 | m_DomainScripts[appDomain] = new List<UUID>(); | 1215 | AppDomain sandbox; |
1216 | if (m_AppDomainLoading) | ||
1217 | { | ||
1218 | sandbox = AppDomain.CreateDomain( | ||
1219 | m_Scene.RegionInfo.RegionID.ToString(), | ||
1220 | evidence, appSetup); | ||
1221 | m_AppDomains[appDomain].AssemblyResolve += | ||
1222 | new ResolveEventHandler( | ||
1223 | AssemblyResolver.OnAssemblyResolve); | ||
1169 | } | 1224 | } |
1170 | catch (Exception e) | 1225 | else |
1171 | { | 1226 | { |
1172 | m_log.ErrorFormat("[XEngine] Exception creating app domain:\n {0}", e.ToString()); | 1227 | sandbox = AppDomain.CurrentDomain; |
1173 | m_ScriptErrorMessage += "Exception creating app domain:\n"; | ||
1174 | m_ScriptFailCount++; | ||
1175 | lock (m_AddingAssemblies) | ||
1176 | { | ||
1177 | m_AddingAssemblies[assembly]--; | ||
1178 | } | ||
1179 | return false; | ||
1180 | } | 1228 | } |
1181 | } | ||
1182 | m_DomainScripts[appDomain].Add(itemID); | ||
1183 | |||
1184 | instance = new ScriptInstance(this, part, | ||
1185 | itemID, assetID, assembly, | ||
1186 | m_AppDomains[appDomain], | ||
1187 | part.ParentGroup.RootPart.Name, | ||
1188 | item.Name, startParam, postOnRez, | ||
1189 | stateSource, m_MaxScriptQueue); | ||
1190 | |||
1191 | // if (DebugLevel >= 1) | ||
1192 | // m_log.DebugFormat( | ||
1193 | // "[XEngine] Loaded script {0}.{1}, item UUID {2}, prim UUID {3} @ {4}.{5}", | ||
1194 | // part.ParentGroup.RootPart.Name, item.Name, itemID, part.UUID, | ||
1195 | // part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName); | ||
1196 | 1229 | ||
1197 | if (presence != null) | 1230 | //PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel(); |
1231 | //AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition(); | ||
1232 | //PermissionSet sandboxPermissionSet = sandboxPolicy.GetNamedPermissionSet("Internet"); | ||
1233 | //PolicyStatement sandboxPolicyStatement = new PolicyStatement(sandboxPermissionSet); | ||
1234 | //CodeGroup sandboxCodeGroup = new UnionCodeGroup(sandboxMembershipCondition, sandboxPolicyStatement); | ||
1235 | //sandboxPolicy.RootCodeGroup = sandboxCodeGroup; | ||
1236 | //sandbox.SetAppDomainPolicy(sandboxPolicy); | ||
1237 | |||
1238 | m_AppDomains[appDomain] = sandbox; | ||
1239 | |||
1240 | m_DomainScripts[appDomain] = new List<UUID>(); | ||
1241 | } | ||
1242 | catch (Exception e) | ||
1198 | { | 1243 | { |
1199 | ShowScriptSaveResponse(item.OwnerID, | 1244 | m_log.ErrorFormat("[XEngine] Exception creating app domain:\n {0}", e.ToString()); |
1200 | assetID, "Compile successful", true); | 1245 | m_ScriptErrorMessage += "Exception creating app domain:\n"; |
1246 | m_ScriptFailCount++; | ||
1247 | lock (m_AddingAssemblies) | ||
1248 | { | ||
1249 | m_AddingAssemblies[assembly]--; | ||
1250 | } | ||
1251 | return false; | ||
1201 | } | 1252 | } |
1253 | } | ||
1254 | m_DomainScripts[appDomain].Add(itemID); | ||
1255 | |||
1256 | instance = new ScriptInstance(this, part, | ||
1257 | itemID, assetID, assembly, | ||
1258 | m_AppDomains[appDomain], | ||
1259 | part.ParentGroup.RootPart.Name, | ||
1260 | item.Name, startParam, postOnRez, | ||
1261 | stateSource, m_MaxScriptQueue); | ||
1262 | |||
1263 | // m_log.DebugFormat( | ||
1264 | // "[XEngine] Loaded script {0}.{1}, script UUID {2}, prim UUID {3} @ {4}.{5}", | ||
1265 | // part.ParentGroup.RootPart.Name, item.Name, assetID, part.UUID, | ||
1266 | // part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName); | ||
1202 | 1267 | ||
1203 | instance.AppDomain = appDomain; | 1268 | if (presence != null) |
1204 | instance.LineMap = linemap; | 1269 | { |
1205 | 1270 | ShowScriptSaveResponse(item.OwnerID, | |
1206 | m_Scripts[itemID] = instance; | 1271 | assetID, "Compile successful", true); |
1207 | } | 1272 | } |
1208 | } | ||
1209 | 1273 | ||
1274 | instance.AppDomain = appDomain; | ||
1275 | instance.LineMap = linemap; | ||
1276 | lockScriptsForWrite(true); | ||
1277 | m_Scripts[itemID] = instance; | ||
1278 | lockScriptsForWrite(false); | ||
1279 | } | ||
1280 | else | ||
1281 | { | ||
1282 | lockScriptsForRead(false); | ||
1283 | } | ||
1210 | lock (m_PrimObjects) | 1284 | lock (m_PrimObjects) |
1211 | { | 1285 | { |
1212 | if (!m_PrimObjects.ContainsKey(localID)) | 1286 | if (!m_PrimObjects.ContainsKey(localID)) |
@@ -1224,7 +1298,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1224 | m_AddingAssemblies[assembly]--; | 1298 | m_AddingAssemblies[assembly]--; |
1225 | } | 1299 | } |
1226 | 1300 | ||
1227 | if (instance != null) | 1301 | if (instance!=null) |
1228 | instance.Init(); | 1302 | instance.Init(); |
1229 | 1303 | ||
1230 | bool runIt; | 1304 | bool runIt; |
@@ -1247,18 +1321,28 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1247 | m_CompileDict.Remove(itemID); | 1321 | m_CompileDict.Remove(itemID); |
1248 | } | 1322 | } |
1249 | 1323 | ||
1250 | IScriptInstance instance = null; | 1324 | lockScriptsForRead(true); |
1251 | 1325 | // Do we even have it? | |
1252 | lock (m_Scripts) | 1326 | if (!m_Scripts.ContainsKey(itemID)) |
1253 | { | 1327 | { |
1254 | // Do we even have it? | 1328 | // Do we even have it? |
1255 | if (!m_Scripts.ContainsKey(itemID)) | 1329 | if (!m_Scripts.ContainsKey(itemID)) |
1256 | return; | 1330 | return; |
1257 | 1331 | ||
1258 | instance = m_Scripts[itemID]; | 1332 | lockScriptsForRead(false); |
1333 | lockScriptsForWrite(true); | ||
1259 | m_Scripts.Remove(itemID); | 1334 | m_Scripts.Remove(itemID); |
1335 | lockScriptsForWrite(false); | ||
1336 | |||
1337 | return; | ||
1260 | } | 1338 | } |
1339 | |||
1261 | 1340 | ||
1341 | IScriptInstance instance=m_Scripts[itemID]; | ||
1342 | lockScriptsForRead(false); | ||
1343 | lockScriptsForWrite(true); | ||
1344 | m_Scripts.Remove(itemID); | ||
1345 | lockScriptsForWrite(false); | ||
1262 | instance.ClearQueue(); | 1346 | instance.ClearQueue(); |
1263 | 1347 | ||
1264 | // Give the script some time to finish processing its last event. Simply aborting the script thread can | 1348 | // Give the script some time to finish processing its last event. Simply aborting the script thread can |
@@ -1297,8 +1381,13 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1297 | 1381 | ||
1298 | ObjectRemoved handlerObjectRemoved = OnObjectRemoved; | 1382 | ObjectRemoved handlerObjectRemoved = OnObjectRemoved; |
1299 | if (handlerObjectRemoved != null) | 1383 | if (handlerObjectRemoved != null) |
1300 | handlerObjectRemoved(instance.ObjectID); | 1384 | { |
1385 | SceneObjectPart part = m_Scene.GetSceneObjectPart(localID); | ||
1386 | handlerObjectRemoved(part.UUID); | ||
1387 | } | ||
1301 | 1388 | ||
1389 | CleanAssemblies(); | ||
1390 | |||
1302 | ScriptRemoved handlerScriptRemoved = OnScriptRemoved; | 1391 | ScriptRemoved handlerScriptRemoved = OnScriptRemoved; |
1303 | if (handlerScriptRemoved != null) | 1392 | if (handlerScriptRemoved != null) |
1304 | handlerScriptRemoved(itemID); | 1393 | handlerScriptRemoved(itemID); |
@@ -1559,12 +1648,14 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1559 | private IScriptInstance GetInstance(UUID itemID) | 1648 | private IScriptInstance GetInstance(UUID itemID) |
1560 | { | 1649 | { |
1561 | IScriptInstance instance; | 1650 | IScriptInstance instance; |
1562 | lock (m_Scripts) | 1651 | lockScriptsForRead(true); |
1652 | if (!m_Scripts.ContainsKey(itemID)) | ||
1563 | { | 1653 | { |
1564 | if (!m_Scripts.ContainsKey(itemID)) | 1654 | lockScriptsForRead(false); |
1565 | return null; | 1655 | return null; |
1566 | instance = m_Scripts[itemID]; | ||
1567 | } | 1656 | } |
1657 | instance = m_Scripts[itemID]; | ||
1658 | lockScriptsForRead(false); | ||
1568 | return instance; | 1659 | return instance; |
1569 | } | 1660 | } |
1570 | 1661 | ||
@@ -1588,6 +1679,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1588 | return false; | 1679 | return false; |
1589 | } | 1680 | } |
1590 | 1681 | ||
1682 | [DebuggerNonUserCode] | ||
1591 | public void ApiResetScript(UUID itemID) | 1683 | public void ApiResetScript(UUID itemID) |
1592 | { | 1684 | { |
1593 | IScriptInstance instance = GetInstance(itemID); | 1685 | IScriptInstance instance = GetInstance(itemID); |
@@ -1649,6 +1741,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1649 | return UUID.Zero; | 1741 | return UUID.Zero; |
1650 | } | 1742 | } |
1651 | 1743 | ||
1744 | [DebuggerNonUserCode] | ||
1652 | public void SetState(UUID itemID, string newState) | 1745 | public void SetState(UUID itemID, string newState) |
1653 | { | 1746 | { |
1654 | IScriptInstance instance = GetInstance(itemID); | 1747 | IScriptInstance instance = GetInstance(itemID); |
@@ -1671,11 +1764,10 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1671 | 1764 | ||
1672 | List<IScriptInstance> instances = new List<IScriptInstance>(); | 1765 | List<IScriptInstance> instances = new List<IScriptInstance>(); |
1673 | 1766 | ||
1674 | lock (m_Scripts) | 1767 | lockScriptsForRead(true); |
1675 | { | 1768 | foreach (IScriptInstance instance in m_Scripts.Values) |
1676 | foreach (IScriptInstance instance in m_Scripts.Values) | ||
1677 | instances.Add(instance); | 1769 | instances.Add(instance); |
1678 | } | 1770 | lockScriptsForRead(false); |
1679 | 1771 | ||
1680 | foreach (IScriptInstance i in instances) | 1772 | foreach (IScriptInstance i in instances) |
1681 | { | 1773 | { |