diff options
Diffstat (limited to '')
-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 965101a..05ba890 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; |
@@ -129,6 +130,8 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
129 | private Dictionary<UUID, IScriptInstance> m_Scripts = | 130 | private Dictionary<UUID, IScriptInstance> m_Scripts = |
130 | new Dictionary<UUID, IScriptInstance>(); | 131 | new Dictionary<UUID, IScriptInstance>(); |
131 | 132 | ||
133 | private OpenMetaverse.ReaderWriterLockSlim m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim(); | ||
134 | |||
132 | // Maps the asset ID to the assembly | 135 | // Maps the asset ID to the assembly |
133 | 136 | ||
134 | private Dictionary<UUID, string> m_Assemblies = | 137 | private Dictionary<UUID, string> m_Assemblies = |
@@ -151,6 +154,71 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
151 | IWorkItemResult m_CurrentCompile = null; | 154 | IWorkItemResult m_CurrentCompile = null; |
152 | private Dictionary<UUID, int> m_CompileDict = new Dictionary<UUID, int>(); | 155 | private Dictionary<UUID, int> m_CompileDict = new Dictionary<UUID, int>(); |
153 | 156 | ||
157 | private void lockScriptsForRead(bool locked) | ||
158 | { | ||
159 | if (locked) | ||
160 | { | ||
161 | if (m_scriptsLock.RecursiveReadCount > 0) | ||
162 | { | ||
163 | 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."); | ||
164 | m_scriptsLock.ExitReadLock(); | ||
165 | } | ||
166 | if (m_scriptsLock.RecursiveWriteCount > 0) | ||
167 | { | ||
168 | m_log.Error("[XEngine.m_Scripts] Recursive write lock requested. This should not happen and means something needs to be fixed."); | ||
169 | m_scriptsLock.ExitWriteLock(); | ||
170 | } | ||
171 | |||
172 | while (!m_scriptsLock.TryEnterReadLock(60000)) | ||
173 | { | ||
174 | 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."); | ||
175 | if (m_scriptsLock.IsWriteLockHeld) | ||
176 | { | ||
177 | m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim(); | ||
178 | } | ||
179 | } | ||
180 | } | ||
181 | else | ||
182 | { | ||
183 | if (m_scriptsLock.RecursiveReadCount > 0) | ||
184 | { | ||
185 | m_scriptsLock.ExitReadLock(); | ||
186 | } | ||
187 | } | ||
188 | } | ||
189 | private void lockScriptsForWrite(bool locked) | ||
190 | { | ||
191 | if (locked) | ||
192 | { | ||
193 | if (m_scriptsLock.RecursiveReadCount > 0) | ||
194 | { | ||
195 | 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."); | ||
196 | m_scriptsLock.ExitReadLock(); | ||
197 | } | ||
198 | if (m_scriptsLock.RecursiveWriteCount > 0) | ||
199 | { | ||
200 | m_log.Error("[XEngine.m_Scripts] Recursive write lock requested. This should not happen and means something needs to be fixed."); | ||
201 | m_scriptsLock.ExitWriteLock(); | ||
202 | } | ||
203 | |||
204 | while (!m_scriptsLock.TryEnterWriteLock(60000)) | ||
205 | { | ||
206 | 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."); | ||
207 | if (m_scriptsLock.IsWriteLockHeld) | ||
208 | { | ||
209 | m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim(); | ||
210 | } | ||
211 | } | ||
212 | } | ||
213 | else | ||
214 | { | ||
215 | if (m_scriptsLock.RecursiveWriteCount > 0) | ||
216 | { | ||
217 | m_scriptsLock.ExitWriteLock(); | ||
218 | } | ||
219 | } | ||
220 | } | ||
221 | |||
154 | public string ScriptEngineName | 222 | public string ScriptEngineName |
155 | { | 223 | { |
156 | get { return "XEngine"; } | 224 | get { return "XEngine"; } |
@@ -605,64 +673,69 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
605 | { | 673 | { |
606 | if (!m_Enabled) | 674 | if (!m_Enabled) |
607 | return; | 675 | return; |
676 | lockScriptsForRead(true); | ||
608 | 677 | ||
609 | lock (m_Scripts) | 678 | List<IScriptInstance> instancesToDel = new List<IScriptInstance>(m_Scripts.Values); |
610 | { | ||
611 | m_log.InfoFormat( | ||
612 | "[XEngine]: Shutting down {0} scripts in {1}", m_Scripts.Count, m_Scene.RegionInfo.RegionName); | ||
613 | 679 | ||
614 | foreach (IScriptInstance instance in m_Scripts.Values) | 680 | // foreach (IScriptInstance instance in m_Scripts.Values) |
681 | foreach (IScriptInstance instance in instancesToDel) | ||
682 | { | ||
683 | // Force a final state save | ||
684 | // | ||
685 | if (m_Assemblies.ContainsKey(instance.AssetID)) | ||
615 | { | 686 | { |
616 | // Force a final state save | 687 | string assembly = m_Assemblies[instance.AssetID]; |
617 | // | ||
618 | if (m_Assemblies.ContainsKey(instance.AssetID)) | ||
619 | { | ||
620 | string assembly = m_Assemblies[instance.AssetID]; | ||
621 | 688 | ||
622 | try | 689 | try |
623 | { | 690 | { |
624 | instance.SaveState(assembly); | 691 | instance.SaveState(assembly); |
625 | } | ||
626 | catch (Exception e) | ||
627 | { | ||
628 | m_log.Error( | ||
629 | string.Format( | ||
630 | "[XEngine]: Failed final state save for script {0}.{1}, item UUID {2}, prim UUID {3} in {4}. Exception ", | ||
631 | instance.PrimName, instance.ScriptName, instance.ItemID, instance.ObjectID, World.Name) | ||
632 | , e); | ||
633 | } | ||
634 | } | 692 | } |
693 | catch (Exception e) | ||
694 | { | ||
695 | m_log.Error( | ||
696 | string.Format( | ||
697 | "[XEngine]: Failed final state save for script {0}.{1}, item UUID {2}, prim UUID {3} in {4}. Exception ", | ||
698 | instance.PrimName, instance.ScriptName, instance.ItemID, instance.ObjectID, World.Name) | ||
699 | , e); | ||
700 | } | ||
701 | } | ||
635 | 702 | ||
636 | // Clear the event queue and abort the instance thread | 703 | // Clear the event queue and abort the instance thread |
637 | // | 704 | // |
638 | instance.ClearQueue(); | 705 | instance.ClearQueue(); |
639 | instance.Stop(0); | 706 | instance.Stop(0); |
640 | 707 | ||
641 | // Release events, timer, etc | 708 | // Release events, timer, etc |
642 | // | 709 | // |
643 | instance.DestroyScriptInstance(); | 710 | instance.DestroyScriptInstance(); |
644 | 711 | ||
645 | // Unload scripts and app domains. | 712 | // Unload scripts and app domains |
646 | // Must be done explicitly because they have infinite | 713 | // Must be done explicitly because they have infinite |
647 | // lifetime. | 714 | // lifetime |
648 | // However, don't bother to do this if the simulator is shutting | 715 | // |
649 | // down since it takes a long time with many scripts. | 716 | // if (!m_SimulatorShuttingDown) |
650 | if (!m_SimulatorShuttingDown) | 717 | { |
718 | m_DomainScripts[instance.AppDomain].Remove(instance.ItemID); | ||
719 | if (m_DomainScripts[instance.AppDomain].Count == 0) | ||
651 | { | 720 | { |
652 | m_DomainScripts[instance.AppDomain].Remove(instance.ItemID); | 721 | m_DomainScripts.Remove(instance.AppDomain); |
653 | if (m_DomainScripts[instance.AppDomain].Count == 0) | 722 | UnloadAppDomain(instance.AppDomain); |
654 | { | ||
655 | m_DomainScripts.Remove(instance.AppDomain); | ||
656 | UnloadAppDomain(instance.AppDomain); | ||
657 | } | ||
658 | } | 723 | } |
659 | } | 724 | } |
660 | 725 | ||
661 | m_Scripts.Clear(); | 726 | // m_Scripts.Clear(); |
662 | m_PrimObjects.Clear(); | 727 | // m_PrimObjects.Clear(); |
663 | m_Assemblies.Clear(); | 728 | // m_Assemblies.Clear(); |
664 | m_DomainScripts.Clear(); | 729 | // m_DomainScripts.Clear(); |
665 | } | 730 | } |
731 | lockScriptsForRead(false); | ||
732 | lockScriptsForWrite(true); | ||
733 | m_Scripts.Clear(); | ||
734 | lockScriptsForWrite(false); | ||
735 | m_PrimObjects.Clear(); | ||
736 | m_Assemblies.Clear(); | ||
737 | m_DomainScripts.Clear(); | ||
738 | |||
666 | lock (m_ScriptEngines) | 739 | lock (m_ScriptEngines) |
667 | { | 740 | { |
668 | m_ScriptEngines.Remove(this); | 741 | m_ScriptEngines.Remove(this); |
@@ -731,22 +804,20 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
731 | 804 | ||
732 | List<IScriptInstance> instances = new List<IScriptInstance>(); | 805 | List<IScriptInstance> instances = new List<IScriptInstance>(); |
733 | 806 | ||
734 | lock (m_Scripts) | 807 | lockScriptsForRead(true); |
735 | { | 808 | foreach (IScriptInstance instance in m_Scripts.Values) |
736 | foreach (IScriptInstance instance in m_Scripts.Values) | ||
737 | instances.Add(instance); | 809 | instances.Add(instance); |
738 | } | 810 | lockScriptsForRead(false); |
739 | 811 | ||
740 | foreach (IScriptInstance i in instances) | 812 | foreach (IScriptInstance i in instances) |
741 | { | 813 | { |
742 | string assembly = String.Empty; | 814 | string assembly = String.Empty; |
743 | 815 | ||
744 | lock (m_Scripts) | 816 | |
745 | { | ||
746 | if (!m_Assemblies.ContainsKey(i.AssetID)) | 817 | if (!m_Assemblies.ContainsKey(i.AssetID)) |
747 | continue; | 818 | continue; |
748 | assembly = m_Assemblies[i.AssetID]; | 819 | assembly = m_Assemblies[i.AssetID]; |
749 | } | 820 | |
750 | 821 | ||
751 | try | 822 | try |
752 | { | 823 | { |
@@ -1147,96 +1218,99 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1147 | } | 1218 | } |
1148 | 1219 | ||
1149 | ScriptInstance instance = null; | 1220 | ScriptInstance instance = null; |
1150 | lock (m_Scripts) | 1221 | // Create the object record |
1222 | lockScriptsForRead(true); | ||
1223 | if ((!m_Scripts.ContainsKey(itemID)) || | ||
1224 | (m_Scripts[itemID].AssetID != assetID)) | ||
1151 | { | 1225 | { |
1152 | // Create the object record | 1226 | lockScriptsForRead(false); |
1153 | if ((!m_Scripts.ContainsKey(itemID)) || | ||
1154 | (m_Scripts[itemID].AssetID != assetID)) | ||
1155 | { | ||
1156 | UUID appDomain = assetID; | ||
1157 | 1227 | ||
1158 | if (part.ParentGroup.IsAttachment) | 1228 | UUID appDomain = assetID; |
1159 | appDomain = part.ParentGroup.RootPart.UUID; | ||
1160 | 1229 | ||
1161 | if (!m_AppDomains.ContainsKey(appDomain)) | 1230 | if (part.ParentGroup.IsAttachment) |
1162 | { | 1231 | appDomain = part.ParentGroup.RootPart.UUID; |
1163 | try | ||
1164 | { | ||
1165 | AppDomainSetup appSetup = new AppDomainSetup(); | ||
1166 | appSetup.PrivateBinPath = Path.Combine( | ||
1167 | m_ScriptEnginesPath, | ||
1168 | m_Scene.RegionInfo.RegionID.ToString()); | ||
1169 | 1232 | ||
1170 | Evidence baseEvidence = AppDomain.CurrentDomain.Evidence; | 1233 | if (!m_AppDomains.ContainsKey(appDomain)) |
1171 | Evidence evidence = new Evidence(baseEvidence); | 1234 | { |
1235 | try | ||
1236 | { | ||
1237 | AppDomainSetup appSetup = new AppDomainSetup(); | ||
1238 | appSetup.PrivateBinPath = Path.Combine( | ||
1239 | m_ScriptEnginesPath, | ||
1240 | m_Scene.RegionInfo.RegionID.ToString()); | ||
1172 | 1241 | ||
1173 | AppDomain sandbox; | 1242 | Evidence baseEvidence = AppDomain.CurrentDomain.Evidence; |
1174 | if (m_AppDomainLoading) | 1243 | Evidence evidence = new Evidence(baseEvidence); |
1175 | { | ||
1176 | sandbox = AppDomain.CreateDomain( | ||
1177 | m_Scene.RegionInfo.RegionID.ToString(), | ||
1178 | evidence, appSetup); | ||
1179 | sandbox.AssemblyResolve += | ||
1180 | new ResolveEventHandler( | ||
1181 | AssemblyResolver.OnAssemblyResolve); | ||
1182 | } | ||
1183 | else | ||
1184 | { | ||
1185 | sandbox = AppDomain.CurrentDomain; | ||
1186 | } | ||
1187 | |||
1188 | //PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel(); | ||
1189 | //AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition(); | ||
1190 | //PermissionSet sandboxPermissionSet = sandboxPolicy.GetNamedPermissionSet("Internet"); | ||
1191 | //PolicyStatement sandboxPolicyStatement = new PolicyStatement(sandboxPermissionSet); | ||
1192 | //CodeGroup sandboxCodeGroup = new UnionCodeGroup(sandboxMembershipCondition, sandboxPolicyStatement); | ||
1193 | //sandboxPolicy.RootCodeGroup = sandboxCodeGroup; | ||
1194 | //sandbox.SetAppDomainPolicy(sandboxPolicy); | ||
1195 | |||
1196 | m_AppDomains[appDomain] = sandbox; | ||
1197 | 1244 | ||
1198 | m_DomainScripts[appDomain] = new List<UUID>(); | 1245 | AppDomain sandbox; |
1246 | if (m_AppDomainLoading) | ||
1247 | { | ||
1248 | sandbox = AppDomain.CreateDomain( | ||
1249 | m_Scene.RegionInfo.RegionID.ToString(), | ||
1250 | evidence, appSetup); | ||
1251 | m_AppDomains[appDomain].AssemblyResolve += | ||
1252 | new ResolveEventHandler( | ||
1253 | AssemblyResolver.OnAssemblyResolve); | ||
1199 | } | 1254 | } |
1200 | catch (Exception e) | 1255 | else |
1201 | { | 1256 | { |
1202 | m_log.ErrorFormat("[XEngine] Exception creating app domain:\n {0}", e.ToString()); | 1257 | sandbox = AppDomain.CurrentDomain; |
1203 | m_ScriptErrorMessage += "Exception creating app domain:\n"; | ||
1204 | m_ScriptFailCount++; | ||
1205 | lock (m_AddingAssemblies) | ||
1206 | { | ||
1207 | m_AddingAssemblies[assembly]--; | ||
1208 | } | ||
1209 | return false; | ||
1210 | } | 1258 | } |
1211 | } | ||
1212 | m_DomainScripts[appDomain].Add(itemID); | ||
1213 | |||
1214 | instance = new ScriptInstance(this, part, | ||
1215 | itemID, assetID, assembly, | ||
1216 | m_AppDomains[appDomain], | ||
1217 | part.ParentGroup.RootPart.Name, | ||
1218 | item.Name, startParam, postOnRez, | ||
1219 | stateSource, m_MaxScriptQueue); | ||
1220 | |||
1221 | // if (DebugLevel >= 1) | ||
1222 | // m_log.DebugFormat( | ||
1223 | // "[XEngine] Loaded script {0}.{1}, item UUID {2}, prim UUID {3} @ {4}.{5}", | ||
1224 | // part.ParentGroup.RootPart.Name, item.Name, itemID, part.UUID, | ||
1225 | // part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName); | ||
1226 | 1259 | ||
1227 | if (presence != null) | 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 | |||
1270 | m_DomainScripts[appDomain] = new List<UUID>(); | ||
1271 | } | ||
1272 | catch (Exception e) | ||
1228 | { | 1273 | { |
1229 | ShowScriptSaveResponse(item.OwnerID, | 1274 | m_log.ErrorFormat("[XEngine] Exception creating app domain:\n {0}", e.ToString()); |
1230 | assetID, "Compile successful", true); | 1275 | m_ScriptErrorMessage += "Exception creating app domain:\n"; |
1276 | m_ScriptFailCount++; | ||
1277 | lock (m_AddingAssemblies) | ||
1278 | { | ||
1279 | m_AddingAssemblies[assembly]--; | ||
1280 | } | ||
1281 | return false; | ||
1231 | } | 1282 | } |
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 | // m_log.DebugFormat( | ||
1294 | // "[XEngine] Loaded script {0}.{1}, script UUID {2}, prim UUID {3} @ {4}.{5}", | ||
1295 | // part.ParentGroup.RootPart.Name, item.Name, assetID, part.UUID, | ||
1296 | // part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName); | ||
1232 | 1297 | ||
1233 | instance.AppDomain = appDomain; | 1298 | if (presence != null) |
1234 | instance.LineMap = linemap; | 1299 | { |
1235 | 1300 | ShowScriptSaveResponse(item.OwnerID, | |
1236 | m_Scripts[itemID] = instance; | 1301 | assetID, "Compile successful", true); |
1237 | } | 1302 | } |
1238 | } | ||
1239 | 1303 | ||
1304 | instance.AppDomain = appDomain; | ||
1305 | instance.LineMap = linemap; | ||
1306 | lockScriptsForWrite(true); | ||
1307 | m_Scripts[itemID] = instance; | ||
1308 | lockScriptsForWrite(false); | ||
1309 | } | ||
1310 | else | ||
1311 | { | ||
1312 | lockScriptsForRead(false); | ||
1313 | } | ||
1240 | lock (m_PrimObjects) | 1314 | lock (m_PrimObjects) |
1241 | { | 1315 | { |
1242 | if (!m_PrimObjects.ContainsKey(localID)) | 1316 | if (!m_PrimObjects.ContainsKey(localID)) |
@@ -1254,7 +1328,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1254 | m_AddingAssemblies[assembly]--; | 1328 | m_AddingAssemblies[assembly]--; |
1255 | } | 1329 | } |
1256 | 1330 | ||
1257 | if (instance != null) | 1331 | if (instance!=null) |
1258 | instance.Init(); | 1332 | instance.Init(); |
1259 | 1333 | ||
1260 | bool runIt; | 1334 | bool runIt; |
@@ -1277,18 +1351,28 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1277 | m_CompileDict.Remove(itemID); | 1351 | m_CompileDict.Remove(itemID); |
1278 | } | 1352 | } |
1279 | 1353 | ||
1280 | IScriptInstance instance = null; | 1354 | lockScriptsForRead(true); |
1281 | 1355 | // Do we even have it? | |
1282 | lock (m_Scripts) | 1356 | if (!m_Scripts.ContainsKey(itemID)) |
1283 | { | 1357 | { |
1284 | // Do we even have it? | 1358 | // Do we even have it? |
1285 | if (!m_Scripts.ContainsKey(itemID)) | 1359 | if (!m_Scripts.ContainsKey(itemID)) |
1286 | return; | 1360 | return; |
1287 | 1361 | ||
1288 | instance = m_Scripts[itemID]; | 1362 | lockScriptsForRead(false); |
1363 | lockScriptsForWrite(true); | ||
1289 | m_Scripts.Remove(itemID); | 1364 | m_Scripts.Remove(itemID); |
1365 | lockScriptsForWrite(false); | ||
1366 | |||
1367 | return; | ||
1290 | } | 1368 | } |
1369 | |||
1291 | 1370 | ||
1371 | IScriptInstance instance=m_Scripts[itemID]; | ||
1372 | lockScriptsForRead(false); | ||
1373 | lockScriptsForWrite(true); | ||
1374 | m_Scripts.Remove(itemID); | ||
1375 | lockScriptsForWrite(false); | ||
1292 | instance.ClearQueue(); | 1376 | instance.ClearQueue(); |
1293 | 1377 | ||
1294 | // Give the script some time to finish processing its last event. Simply aborting the script thread can | 1378 | // Give the script some time to finish processing its last event. Simply aborting the script thread can |
@@ -1327,8 +1411,13 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1327 | 1411 | ||
1328 | ObjectRemoved handlerObjectRemoved = OnObjectRemoved; | 1412 | ObjectRemoved handlerObjectRemoved = OnObjectRemoved; |
1329 | if (handlerObjectRemoved != null) | 1413 | if (handlerObjectRemoved != null) |
1330 | handlerObjectRemoved(instance.ObjectID); | 1414 | { |
1415 | SceneObjectPart part = m_Scene.GetSceneObjectPart(localID); | ||
1416 | handlerObjectRemoved(part.UUID); | ||
1417 | } | ||
1331 | 1418 | ||
1419 | CleanAssemblies(); | ||
1420 | |||
1332 | ScriptRemoved handlerScriptRemoved = OnScriptRemoved; | 1421 | ScriptRemoved handlerScriptRemoved = OnScriptRemoved; |
1333 | if (handlerScriptRemoved != null) | 1422 | if (handlerScriptRemoved != null) |
1334 | handlerScriptRemoved(itemID); | 1423 | handlerScriptRemoved(itemID); |
@@ -1588,12 +1677,14 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1588 | private IScriptInstance GetInstance(UUID itemID) | 1677 | private IScriptInstance GetInstance(UUID itemID) |
1589 | { | 1678 | { |
1590 | IScriptInstance instance; | 1679 | IScriptInstance instance; |
1591 | lock (m_Scripts) | 1680 | lockScriptsForRead(true); |
1681 | if (!m_Scripts.ContainsKey(itemID)) | ||
1592 | { | 1682 | { |
1593 | if (!m_Scripts.ContainsKey(itemID)) | 1683 | lockScriptsForRead(false); |
1594 | return null; | 1684 | return null; |
1595 | instance = m_Scripts[itemID]; | ||
1596 | } | 1685 | } |
1686 | instance = m_Scripts[itemID]; | ||
1687 | lockScriptsForRead(false); | ||
1597 | return instance; | 1688 | return instance; |
1598 | } | 1689 | } |
1599 | 1690 | ||
@@ -1617,6 +1708,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1617 | return false; | 1708 | return false; |
1618 | } | 1709 | } |
1619 | 1710 | ||
1711 | [DebuggerNonUserCode] | ||
1620 | public void ApiResetScript(UUID itemID) | 1712 | public void ApiResetScript(UUID itemID) |
1621 | { | 1713 | { |
1622 | IScriptInstance instance = GetInstance(itemID); | 1714 | IScriptInstance instance = GetInstance(itemID); |
@@ -1678,6 +1770,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1678 | return UUID.Zero; | 1770 | return UUID.Zero; |
1679 | } | 1771 | } |
1680 | 1772 | ||
1773 | [DebuggerNonUserCode] | ||
1681 | public void SetState(UUID itemID, string newState) | 1774 | public void SetState(UUID itemID, string newState) |
1682 | { | 1775 | { |
1683 | IScriptInstance instance = GetInstance(itemID); | 1776 | IScriptInstance instance = GetInstance(itemID); |
@@ -1700,11 +1793,10 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1700 | 1793 | ||
1701 | List<IScriptInstance> instances = new List<IScriptInstance>(); | 1794 | List<IScriptInstance> instances = new List<IScriptInstance>(); |
1702 | 1795 | ||
1703 | lock (m_Scripts) | 1796 | lockScriptsForRead(true); |
1704 | { | 1797 | foreach (IScriptInstance instance in m_Scripts.Values) |
1705 | foreach (IScriptInstance instance in m_Scripts.Values) | ||
1706 | instances.Add(instance); | 1798 | instances.Add(instance); |
1707 | } | 1799 | lockScriptsForRead(false); |
1708 | 1800 | ||
1709 | foreach (IScriptInstance i in instances) | 1801 | foreach (IScriptInstance i in instances) |
1710 | { | 1802 | { |