aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ScriptEngine/XEngine/XEngine.cs')
-rw-r--r--OpenSim/Region/ScriptEngine/XEngine/XEngine.cs424
1 files changed, 253 insertions, 171 deletions
diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
index bc5df11..a6ab5e9 100644
--- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
+++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
@@ -30,6 +30,7 @@ using System.IO;
30using System.Threading; 30using System.Threading;
31using System.Collections; 31using System.Collections;
32using System.Collections.Generic; 32using System.Collections.Generic;
33using System.Diagnostics; //for [DebuggerNonUserCode]
33using System.Security; 34using System.Security;
34using System.Security.Policy; 35using System.Security.Policy;
35using System.Reflection; 36using System.Reflection;
@@ -102,6 +103,8 @@ namespace OpenSim.Region.ScriptEngine.XEngine
102 private Dictionary<UUID, IScriptInstance> m_Scripts = 103 private Dictionary<UUID, IScriptInstance> m_Scripts =
103 new Dictionary<UUID, IScriptInstance>(); 104 new Dictionary<UUID, IScriptInstance>();
104 105
106 private OpenMetaverse.ReaderWriterLockSlim m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim();
107
105 // Maps the asset ID to the assembly 108 // Maps the asset ID to the assembly
106 109
107 private Dictionary<UUID, string> m_Assemblies = 110 private Dictionary<UUID, string> m_Assemblies =
@@ -124,6 +127,71 @@ namespace OpenSim.Region.ScriptEngine.XEngine
124 IWorkItemResult m_CurrentCompile = null; 127 IWorkItemResult m_CurrentCompile = null;
125 private Dictionary<UUID, int> m_CompileDict = new Dictionary<UUID, int>(); 128 private Dictionary<UUID, int> m_CompileDict = new Dictionary<UUID, int>();
126 129
130 private void lockScriptsForRead(bool locked)
131 {
132 if (locked)
133 {
134 if (m_scriptsLock.RecursiveReadCount > 0)
135 {
136 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.");
137 m_scriptsLock.ExitReadLock();
138 }
139 if (m_scriptsLock.RecursiveWriteCount > 0)
140 {
141 m_log.Error("[XEngine.m_Scripts] Recursive write lock requested. This should not happen and means something needs to be fixed.");
142 m_scriptsLock.ExitWriteLock();
143 }
144
145 while (!m_scriptsLock.TryEnterReadLock(60000))
146 {
147 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.");
148 if (m_scriptsLock.IsWriteLockHeld)
149 {
150 m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim();
151 }
152 }
153 }
154 else
155 {
156 if (m_scriptsLock.RecursiveReadCount > 0)
157 {
158 m_scriptsLock.ExitReadLock();
159 }
160 }
161 }
162 private void lockScriptsForWrite(bool locked)
163 {
164 if (locked)
165 {
166 if (m_scriptsLock.RecursiveReadCount > 0)
167 {
168 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.");
169 m_scriptsLock.ExitReadLock();
170 }
171 if (m_scriptsLock.RecursiveWriteCount > 0)
172 {
173 m_log.Error("[XEngine.m_Scripts] Recursive write lock requested. This should not happen and means something needs to be fixed.");
174 m_scriptsLock.ExitWriteLock();
175 }
176
177 while (!m_scriptsLock.TryEnterWriteLock(60000))
178 {
179 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.");
180 if (m_scriptsLock.IsWriteLockHeld)
181 {
182 m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim();
183 }
184 }
185 }
186 else
187 {
188 if (m_scriptsLock.RecursiveWriteCount > 0)
189 {
190 m_scriptsLock.ExitWriteLock();
191 }
192 }
193 }
194
127 public string ScriptEngineName 195 public string ScriptEngineName
128 { 196 {
129 get { return "XEngine"; } 197 get { return "XEngine"; }
@@ -263,43 +331,45 @@ namespace OpenSim.Region.ScriptEngine.XEngine
263 331
264 public void RemoveRegion(Scene scene) 332 public void RemoveRegion(Scene scene)
265 { 333 {
266 lock (m_Scripts) 334 lockScriptsForRead(true);
335 foreach (IScriptInstance instance in m_Scripts.Values)
267 { 336 {
268 foreach (IScriptInstance instance in m_Scripts.Values) 337 // Force a final state save
338 //
339 if (m_Assemblies.ContainsKey(instance.AssetID))
269 { 340 {
270 // Force a final state save 341 string assembly = m_Assemblies[instance.AssetID];
271 // 342 instance.SaveState(assembly);
272 if (m_Assemblies.ContainsKey(instance.AssetID)) 343 }
273 {
274 string assembly = m_Assemblies[instance.AssetID];
275 instance.SaveState(assembly);
276 }
277 344
278 // Clear the event queue and abort the instance thread 345 // Clear the event queue and abort the instance thread
279 // 346 //
280 instance.ClearQueue(); 347 instance.ClearQueue();
281 instance.Stop(0); 348 instance.Stop(0);
282 349
283 // Release events, timer, etc 350 // Release events, timer, etc
284 // 351 //
285 instance.DestroyScriptInstance(); 352 instance.DestroyScriptInstance();
286 353
287 // Unload scripts and app domains 354 // Unload scripts and app domains
288 // Must be done explicitly because they have infinite 355 // Must be done explicitly because they have infinite
289 // lifetime 356 // lifetime
290 // 357 //
291 m_DomainScripts[instance.AppDomain].Remove(instance.ItemID); 358 m_DomainScripts[instance.AppDomain].Remove(instance.ItemID);
292 if (m_DomainScripts[instance.AppDomain].Count == 0) 359 if (m_DomainScripts[instance.AppDomain].Count == 0)
293 { 360 {
294 m_DomainScripts.Remove(instance.AppDomain); 361 m_DomainScripts.Remove(instance.AppDomain);
295 UnloadAppDomain(instance.AppDomain); 362 UnloadAppDomain(instance.AppDomain);
296 }
297 } 363 }
298 m_Scripts.Clear();
299 m_PrimObjects.Clear();
300 m_Assemblies.Clear();
301 m_DomainScripts.Clear();
302 } 364 }
365 lockScriptsForRead(false);
366 lockScriptsForWrite(true);
367 m_Scripts.Clear();
368 lockScriptsForWrite(false);
369 m_PrimObjects.Clear();
370 m_Assemblies.Clear();
371 m_DomainScripts.Clear();
372
303 lock (m_ScriptEngines) 373 lock (m_ScriptEngines)
304 { 374 {
305 m_ScriptEngines.Remove(this); 375 m_ScriptEngines.Remove(this);
@@ -358,22 +428,20 @@ namespace OpenSim.Region.ScriptEngine.XEngine
358 428
359 List<IScriptInstance> instances = new List<IScriptInstance>(); 429 List<IScriptInstance> instances = new List<IScriptInstance>();
360 430
361 lock (m_Scripts) 431 lockScriptsForRead(true);
362 { 432 foreach (IScriptInstance instance in m_Scripts.Values)
363 foreach (IScriptInstance instance in m_Scripts.Values)
364 instances.Add(instance); 433 instances.Add(instance);
365 } 434 lockScriptsForRead(false);
366 435
367 foreach (IScriptInstance i in instances) 436 foreach (IScriptInstance i in instances)
368 { 437 {
369 string assembly = String.Empty; 438 string assembly = String.Empty;
370 439
371 lock (m_Scripts) 440
372 {
373 if (!m_Assemblies.ContainsKey(i.AssetID)) 441 if (!m_Assemblies.ContainsKey(i.AssetID))
374 continue; 442 continue;
375 assembly = m_Assemblies[i.AssetID]; 443 assembly = m_Assemblies[i.AssetID];
376 } 444
377 445
378 i.SaveState(assembly); 446 i.SaveState(assembly);
379 } 447 }
@@ -701,113 +769,119 @@ namespace OpenSim.Region.ScriptEngine.XEngine
701 } 769 }
702 } 770 }
703 771
704 lock (m_Scripts) 772
773
774 ScriptInstance instance = null;
775 // Create the object record
776 lockScriptsForRead(true);
777 if ((!m_Scripts.ContainsKey(itemID)) ||
778 (m_Scripts[itemID].AssetID != assetID))
705 { 779 {
706 ScriptInstance instance = null; 780 lockScriptsForRead(false);
707 // Create the object record
708 781
709 if ((!m_Scripts.ContainsKey(itemID)) || 782 UUID appDomain = assetID;
710 (m_Scripts[itemID].AssetID != assetID))
711 {
712 UUID appDomain = assetID;
713 783
714 if (part.ParentGroup.IsAttachment) 784 if (part.ParentGroup.IsAttachment)
715 appDomain = part.ParentGroup.RootPart.UUID; 785 appDomain = part.ParentGroup.RootPart.UUID;
716 786
717 if (!m_AppDomains.ContainsKey(appDomain)) 787 if (!m_AppDomains.ContainsKey(appDomain))
788 {
789 try
718 { 790 {
719 try 791 AppDomainSetup appSetup = new AppDomainSetup();
720 { 792 // appSetup.ApplicationBase = Path.Combine(
721 AppDomainSetup appSetup = new AppDomainSetup(); 793 // "ScriptEngines",
722// appSetup.ApplicationBase = Path.Combine( 794 // m_Scene.RegionInfo.RegionID.ToString());
723// "ScriptEngines", 795
724// m_Scene.RegionInfo.RegionID.ToString()); 796 Evidence baseEvidence = AppDomain.CurrentDomain.Evidence;
725 797 Evidence evidence = new Evidence(baseEvidence);
726 Evidence baseEvidence = AppDomain.CurrentDomain.Evidence; 798
727 Evidence evidence = new Evidence(baseEvidence); 799 AppDomain sandbox;
728 800 if (m_AppDomainLoading)
729 AppDomain sandbox; 801 sandbox = AppDomain.CreateDomain(
730 if (m_AppDomainLoading) 802 m_Scene.RegionInfo.RegionID.ToString(),
731 sandbox = AppDomain.CreateDomain( 803 evidence, appSetup);
732 m_Scene.RegionInfo.RegionID.ToString(), 804 else
733 evidence, appSetup); 805 sandbox = AppDomain.CurrentDomain;
734 else 806
735 sandbox = AppDomain.CurrentDomain; 807 //PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel();
736 808 //AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition();
737 //PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel(); 809 //PermissionSet sandboxPermissionSet = sandboxPolicy.GetNamedPermissionSet("Internet");
738 //AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition(); 810 //PolicyStatement sandboxPolicyStatement = new PolicyStatement(sandboxPermissionSet);
739 //PermissionSet sandboxPermissionSet = sandboxPolicy.GetNamedPermissionSet("Internet"); 811 //CodeGroup sandboxCodeGroup = new UnionCodeGroup(sandboxMembershipCondition, sandboxPolicyStatement);
740 //PolicyStatement sandboxPolicyStatement = new PolicyStatement(sandboxPermissionSet); 812 //sandboxPolicy.RootCodeGroup = sandboxCodeGroup;
741 //CodeGroup sandboxCodeGroup = new UnionCodeGroup(sandboxMembershipCondition, sandboxPolicyStatement); 813 //sandbox.SetAppDomainPolicy(sandboxPolicy);
742 //sandboxPolicy.RootCodeGroup = sandboxCodeGroup; 814
743 //sandbox.SetAppDomainPolicy(sandboxPolicy); 815 m_AppDomains[appDomain] = sandbox;
744 816
745 m_AppDomains[appDomain] = sandbox; 817 m_AppDomains[appDomain].AssemblyResolve +=
746 818 new ResolveEventHandler(
747 m_AppDomains[appDomain].AssemblyResolve += 819 AssemblyResolver.OnAssemblyResolve);
748 new ResolveEventHandler( 820 m_DomainScripts[appDomain] = new List<UUID>();
749 AssemblyResolver.OnAssemblyResolve); 821 }
750 m_DomainScripts[appDomain] = new List<UUID>(); 822 catch (Exception e)
751 } 823 {
752 catch (Exception e) 824 m_log.ErrorFormat("[XEngine] Exception creating app domain:\n {0}", e.ToString());
825 m_ScriptErrorMessage += "Exception creating app domain:\n";
826 m_ScriptFailCount++;
827 lock (m_AddingAssemblies)
753 { 828 {
754 m_log.ErrorFormat("[XEngine] Exception creating app domain:\n {0}", e.ToString()); 829 m_AddingAssemblies[assembly]--;
755 m_ScriptErrorMessage += "Exception creating app domain:\n";
756 m_ScriptFailCount++;
757 lock (m_AddingAssemblies)
758 {
759 m_AddingAssemblies[assembly]--;
760 }
761 return false;
762 } 830 }
831 return false;
763 } 832 }
764 m_DomainScripts[appDomain].Add(itemID); 833 }
765 834 m_DomainScripts[appDomain].Add(itemID);
766 instance = new ScriptInstance(this, part, 835
767 itemID, assetID, assembly, 836 instance = new ScriptInstance(this, part,
768 m_AppDomains[appDomain], 837 itemID, assetID, assembly,
769 part.ParentGroup.RootPart.Name, 838 m_AppDomains[appDomain],
770 item.Name, startParam, postOnRez, 839 part.ParentGroup.RootPart.Name,
771 stateSource, m_MaxScriptQueue); 840 item.Name, startParam, postOnRez,
772 841 stateSource, m_MaxScriptQueue);
773 m_log.DebugFormat( 842
843 m_log.DebugFormat(
774 "[XEngine] Loaded script {0}.{1}, script UUID {2}, prim UUID {3} @ {4}.{5}", 844 "[XEngine] Loaded script {0}.{1}, script UUID {2}, prim UUID {3} @ {4}.{5}",
775 part.ParentGroup.RootPart.Name, item.Name, assetID, part.UUID, 845 part.ParentGroup.RootPart.Name, item.Name, assetID, part.UUID,
776 part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName); 846 part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName);
777 847
778 if (presence != null) 848 if (presence != null)
779 {
780 ShowScriptSaveResponse(item.OwnerID,
781 assetID, "Compile successful", true);
782 }
783
784 instance.AppDomain = appDomain;
785 instance.LineMap = linemap;
786
787 m_Scripts[itemID] = instance;
788 }
789
790 lock (m_PrimObjects)
791 { 849 {
792 if (!m_PrimObjects.ContainsKey(localID)) 850 ShowScriptSaveResponse(item.OwnerID,
793 m_PrimObjects[localID] = new List<UUID>(); 851 assetID, "Compile successful", true);
852 }
794 853
795 if (!m_PrimObjects[localID].Contains(itemID)) 854 instance.AppDomain = appDomain;
796 m_PrimObjects[localID].Add(itemID); 855 instance.LineMap = linemap;
856 lockScriptsForWrite(true);
857 m_Scripts[itemID] = instance;
858 lockScriptsForWrite(false);
859 }
860 else
861 {
862 lockScriptsForRead(false);
863 }
864 lock (m_PrimObjects)
865 {
866 if (!m_PrimObjects.ContainsKey(localID))
867 m_PrimObjects[localID] = new List<UUID>();
797 868
798 } 869 if (!m_PrimObjects[localID].Contains(itemID))
870 m_PrimObjects[localID].Add(itemID);
799 871
800 if (!m_Assemblies.ContainsKey(assetID)) 872 }
801 m_Assemblies[assetID] = assembly;
802 873
803 lock (m_AddingAssemblies) 874 if (!m_Assemblies.ContainsKey(assetID))
804 { 875 m_Assemblies[assetID] = assembly;
805 m_AddingAssemblies[assembly]--;
806 }
807 876
808 if (instance!=null) 877 lock (m_AddingAssemblies)
809 instance.Init(); 878 {
879 m_AddingAssemblies[assembly]--;
810 } 880 }
881
882 if (instance!=null)
883 instance.Init();
884
811 return true; 885 return true;
812 } 886 }
813 887
@@ -820,60 +894,65 @@ namespace OpenSim.Region.ScriptEngine.XEngine
820 m_CompileDict.Remove(itemID); 894 m_CompileDict.Remove(itemID);
821 } 895 }
822 896
823 lock (m_Scripts) 897 lockScriptsForRead(true);
898 // Do we even have it?
899 if (!m_Scripts.ContainsKey(itemID))
824 { 900 {
825 // Do we even have it? 901 lockScriptsForRead(false);
826 if (!m_Scripts.ContainsKey(itemID)) 902 return;
827 return; 903 }
828 904
829 IScriptInstance instance=m_Scripts[itemID];
830 m_Scripts.Remove(itemID);
831 905
832 instance.ClearQueue(); 906 IScriptInstance instance=m_Scripts[itemID];
833 instance.Stop(0); 907 lockScriptsForRead(false);
908 lockScriptsForWrite(true);
909 m_Scripts.Remove(itemID);
910 lockScriptsForWrite(false);
911 instance.ClearQueue();
912 instance.Stop(0);
834 913
835// bool objectRemoved = false; 914// bool objectRemoved = false;
836 915
837 lock (m_PrimObjects) 916 lock (m_PrimObjects)
917 {
918 // Remove the script from it's prim
919 if (m_PrimObjects.ContainsKey(localID))
838 { 920 {
839 // Remove the script from it's prim 921 // Remove inventory item record
840 if (m_PrimObjects.ContainsKey(localID)) 922 if (m_PrimObjects[localID].Contains(itemID))
841 { 923 m_PrimObjects[localID].Remove(itemID);
842 // Remove inventory item record
843 if (m_PrimObjects[localID].Contains(itemID))
844 m_PrimObjects[localID].Remove(itemID);
845 924
846 // If there are no more scripts, remove prim 925 // If there are no more scripts, remove prim
847 if (m_PrimObjects[localID].Count == 0) 926 if (m_PrimObjects[localID].Count == 0)
848 { 927 {
849 m_PrimObjects.Remove(localID); 928 m_PrimObjects.Remove(localID);
850// objectRemoved = true; 929// objectRemoved = true;
851 }
852 } 930 }
853 } 931 }
932 }
854 933
855 instance.RemoveState(); 934 instance.RemoveState();
856 instance.DestroyScriptInstance(); 935 instance.DestroyScriptInstance();
857 936
858 m_DomainScripts[instance.AppDomain].Remove(instance.ItemID); 937 m_DomainScripts[instance.AppDomain].Remove(instance.ItemID);
859 if (m_DomainScripts[instance.AppDomain].Count == 0) 938 if (m_DomainScripts[instance.AppDomain].Count == 0)
860 { 939 {
861 m_DomainScripts.Remove(instance.AppDomain); 940 m_DomainScripts.Remove(instance.AppDomain);
862 UnloadAppDomain(instance.AppDomain); 941 UnloadAppDomain(instance.AppDomain);
863 } 942 }
864
865 instance = null;
866 943
867 ObjectRemoved handlerObjectRemoved = OnObjectRemoved; 944 instance = null;
868 if (handlerObjectRemoved != null)
869 {
870 SceneObjectPart part = m_Scene.GetSceneObjectPart(localID);
871 handlerObjectRemoved(part.UUID);
872 }
873 945
874 CleanAssemblies(); 946 ObjectRemoved handlerObjectRemoved = OnObjectRemoved;
947 if (handlerObjectRemoved != null)
948 {
949 SceneObjectPart part = m_Scene.GetSceneObjectPart(localID);
950 handlerObjectRemoved(part.UUID);
875 } 951 }
876 952
953 CleanAssemblies();
954
955
877 ScriptRemoved handlerScriptRemoved = OnScriptRemoved; 956 ScriptRemoved handlerScriptRemoved = OnScriptRemoved;
878 if (handlerScriptRemoved != null) 957 if (handlerScriptRemoved != null)
879 handlerScriptRemoved(itemID); 958 handlerScriptRemoved(itemID);
@@ -1125,12 +1204,14 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1125 private IScriptInstance GetInstance(UUID itemID) 1204 private IScriptInstance GetInstance(UUID itemID)
1126 { 1205 {
1127 IScriptInstance instance; 1206 IScriptInstance instance;
1128 lock (m_Scripts) 1207 lockScriptsForRead(true);
1208 if (!m_Scripts.ContainsKey(itemID))
1129 { 1209 {
1130 if (!m_Scripts.ContainsKey(itemID)) 1210 lockScriptsForRead(false);
1131 return null; 1211 return null;
1132 instance = m_Scripts[itemID];
1133 } 1212 }
1213 instance = m_Scripts[itemID];
1214 lockScriptsForRead(false);
1134 return instance; 1215 return instance;
1135 } 1216 }
1136 1217
@@ -1154,6 +1235,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1154 return false; 1235 return false;
1155 } 1236 }
1156 1237
1238 [DebuggerNonUserCode]
1157 public void ApiResetScript(UUID itemID) 1239 public void ApiResetScript(UUID itemID)
1158 { 1240 {
1159 IScriptInstance instance = GetInstance(itemID); 1241 IScriptInstance instance = GetInstance(itemID);
@@ -1205,6 +1287,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1205 return UUID.Zero; 1287 return UUID.Zero;
1206 } 1288 }
1207 1289
1290 [DebuggerNonUserCode]
1208 public void SetState(UUID itemID, string newState) 1291 public void SetState(UUID itemID, string newState)
1209 { 1292 {
1210 IScriptInstance instance = GetInstance(itemID); 1293 IScriptInstance instance = GetInstance(itemID);
@@ -1225,11 +1308,10 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1225 { 1308 {
1226 List<IScriptInstance> instances = new List<IScriptInstance>(); 1309 List<IScriptInstance> instances = new List<IScriptInstance>();
1227 1310
1228 lock (m_Scripts) 1311 lockScriptsForRead(true);
1229 { 1312 foreach (IScriptInstance instance in m_Scripts.Values)
1230 foreach (IScriptInstance instance in m_Scripts.Values)
1231 instances.Add(instance); 1313 instances.Add(instance);
1232 } 1314 lockScriptsForRead(false);
1233 1315
1234 foreach (IScriptInstance i in instances) 1316 foreach (IScriptInstance i in instances)
1235 { 1317 {