aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/ScriptEngine/XEngine/XEngine.cs418
1 files changed, 247 insertions, 171 deletions
diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
index 9030a5c..49c69ab 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;
@@ -100,6 +101,8 @@ namespace OpenSim.Region.ScriptEngine.XEngine
100 private Dictionary<UUID, IScriptInstance> m_Scripts = 101 private Dictionary<UUID, IScriptInstance> m_Scripts =
101 new Dictionary<UUID, IScriptInstance>(); 102 new Dictionary<UUID, IScriptInstance>();
102 103
104 private OpenMetaverse.ReaderWriterLockSlim m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim();
105
103 // Maps the asset ID to the assembly 106 // Maps the asset ID to the assembly
104 107
105 private Dictionary<UUID, string> m_Assemblies = 108 private Dictionary<UUID, string> m_Assemblies =
@@ -121,6 +124,65 @@ namespace OpenSim.Region.ScriptEngine.XEngine
121 private ScriptCompileQueue m_CompileQueue = new ScriptCompileQueue(); 124 private ScriptCompileQueue m_CompileQueue = new ScriptCompileQueue();
122 IWorkItemResult m_CurrentCompile = null; 125 IWorkItemResult m_CurrentCompile = null;
123 126
127 private void lockScriptsForRead(bool locked)
128 {
129 if (locked)
130 {
131 if (m_scriptsLock.RecursiveReadCount > 0)
132 {
133 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.");
134 m_scriptsLock.ExitReadLock();
135 }
136 if (m_scriptsLock.RecursiveWriteCount > 0)
137 {
138 m_log.Error("[XEngine.m_Scripts] Recursive write lock requested. This should not happen and means something needs to be fixed.");
139 m_scriptsLock.ExitWriteLock();
140 }
141
142 while (!m_scriptsLock.TryEnterReadLock(60000))
143 {
144 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.");
145 if (m_scriptsLock.IsWriteLockHeld)
146 {
147 m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim();
148 }
149 }
150 }
151 else
152 {
153 m_scriptsLock.ExitReadLock();
154 }
155 }
156 private void lockScriptsForWrite(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.TryEnterWriteLock(60000))
172 {
173 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.");
174 if (m_scriptsLock.IsWriteLockHeld)
175 {
176 m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim();
177 }
178 }
179 }
180 else
181 {
182 m_scriptsLock.ExitWriteLock();
183 }
184 }
185
124 public string ScriptEngineName 186 public string ScriptEngineName
125 { 187 {
126 get { return "XEngine"; } 188 get { return "XEngine"; }
@@ -260,43 +322,45 @@ namespace OpenSim.Region.ScriptEngine.XEngine
260 322
261 public void RemoveRegion(Scene scene) 323 public void RemoveRegion(Scene scene)
262 { 324 {
263 lock (m_Scripts) 325 lockScriptsForRead(true);
326 foreach (IScriptInstance instance in m_Scripts.Values)
264 { 327 {
265 foreach (IScriptInstance instance in m_Scripts.Values) 328 // Force a final state save
329 //
330 if (m_Assemblies.ContainsKey(instance.AssetID))
266 { 331 {
267 // Force a final state save 332 string assembly = m_Assemblies[instance.AssetID];
268 // 333 instance.SaveState(assembly);
269 if (m_Assemblies.ContainsKey(instance.AssetID)) 334 }
270 {
271 string assembly = m_Assemblies[instance.AssetID];
272 instance.SaveState(assembly);
273 }
274 335
275 // Clear the event queue and abort the instance thread 336 // Clear the event queue and abort the instance thread
276 // 337 //
277 instance.ClearQueue(); 338 instance.ClearQueue();
278 instance.Stop(0); 339 instance.Stop(0);
279 340
280 // Release events, timer, etc 341 // Release events, timer, etc
281 // 342 //
282 instance.DestroyScriptInstance(); 343 instance.DestroyScriptInstance();
283 344
284 // Unload scripts and app domains 345 // Unload scripts and app domains
285 // Must be done explicitly because they have infinite 346 // Must be done explicitly because they have infinite
286 // lifetime 347 // lifetime
287 // 348 //
288 m_DomainScripts[instance.AppDomain].Remove(instance.ItemID); 349 m_DomainScripts[instance.AppDomain].Remove(instance.ItemID);
289 if (m_DomainScripts[instance.AppDomain].Count == 0) 350 if (m_DomainScripts[instance.AppDomain].Count == 0)
290 { 351 {
291 m_DomainScripts.Remove(instance.AppDomain); 352 m_DomainScripts.Remove(instance.AppDomain);
292 UnloadAppDomain(instance.AppDomain); 353 UnloadAppDomain(instance.AppDomain);
293 }
294 } 354 }
295 m_Scripts.Clear();
296 m_PrimObjects.Clear();
297 m_Assemblies.Clear();
298 m_DomainScripts.Clear();
299 } 355 }
356 lockScriptsForRead(false);
357 lockScriptsForWrite(true);
358 m_Scripts.Clear();
359 lockScriptsForWrite(false);
360 m_PrimObjects.Clear();
361 m_Assemblies.Clear();
362 m_DomainScripts.Clear();
363
300 lock (m_ScriptEngines) 364 lock (m_ScriptEngines)
301 { 365 {
302 m_ScriptEngines.Remove(this); 366 m_ScriptEngines.Remove(this);
@@ -355,22 +419,20 @@ namespace OpenSim.Region.ScriptEngine.XEngine
355 419
356 List<IScriptInstance> instances = new List<IScriptInstance>(); 420 List<IScriptInstance> instances = new List<IScriptInstance>();
357 421
358 lock (m_Scripts) 422 lockScriptsForRead(true);
359 { 423 foreach (IScriptInstance instance in m_Scripts.Values)
360 foreach (IScriptInstance instance in m_Scripts.Values)
361 instances.Add(instance); 424 instances.Add(instance);
362 } 425 lockScriptsForRead(false);
363 426
364 foreach (IScriptInstance i in instances) 427 foreach (IScriptInstance i in instances)
365 { 428 {
366 string assembly = String.Empty; 429 string assembly = String.Empty;
367 430
368 lock (m_Scripts) 431
369 {
370 if (!m_Assemblies.ContainsKey(i.AssetID)) 432 if (!m_Assemblies.ContainsKey(i.AssetID))
371 continue; 433 continue;
372 assembly = m_Assemblies[i.AssetID]; 434 assembly = m_Assemblies[i.AssetID];
373 } 435
374 436
375 i.SaveState(assembly); 437 i.SaveState(assembly);
376 } 438 }
@@ -672,172 +734,183 @@ namespace OpenSim.Region.ScriptEngine.XEngine
672 return false; 734 return false;
673 } 735 }
674 736
675 lock (m_Scripts) 737
738
739 ScriptInstance instance = null;
740 // Create the object record
741 lockScriptsForRead(true);
742 if ((!m_Scripts.ContainsKey(itemID)) ||
743 (m_Scripts[itemID].AssetID != assetID))
676 { 744 {
677 ScriptInstance instance = null; 745 lockScriptsForRead(false);
678 // Create the object record
679 746
680 if ((!m_Scripts.ContainsKey(itemID)) || 747 UUID appDomain = assetID;
681 (m_Scripts[itemID].AssetID != assetID))
682 {
683 UUID appDomain = assetID;
684 748
685 if (part.ParentGroup.IsAttachment) 749 if (part.ParentGroup.IsAttachment)
686 appDomain = part.ParentGroup.RootPart.UUID; 750 appDomain = part.ParentGroup.RootPart.UUID;
687 751
688 if (!m_AppDomains.ContainsKey(appDomain)) 752 if (!m_AppDomains.ContainsKey(appDomain))
753 {
754 try
689 { 755 {
690 try 756 AppDomainSetup appSetup = new AppDomainSetup();
691 { 757 // appSetup.ApplicationBase = Path.Combine(
692 AppDomainSetup appSetup = new AppDomainSetup(); 758 // "ScriptEngines",
693// appSetup.ApplicationBase = Path.Combine( 759 // m_Scene.RegionInfo.RegionID.ToString());
694// "ScriptEngines", 760
695// m_Scene.RegionInfo.RegionID.ToString()); 761 Evidence baseEvidence = AppDomain.CurrentDomain.Evidence;
696 762 Evidence evidence = new Evidence(baseEvidence);
697 Evidence baseEvidence = AppDomain.CurrentDomain.Evidence; 763
698 Evidence evidence = new Evidence(baseEvidence); 764 AppDomain sandbox;
699 765 if (m_AppDomainLoading)
700 AppDomain sandbox; 766 sandbox = AppDomain.CreateDomain(
701 if (m_AppDomainLoading) 767 m_Scene.RegionInfo.RegionID.ToString(),
702 sandbox = AppDomain.CreateDomain( 768 evidence, appSetup);
703 m_Scene.RegionInfo.RegionID.ToString(), 769 else
704 evidence, appSetup); 770 sandbox = AppDomain.CurrentDomain;
705 else 771
706 sandbox = AppDomain.CurrentDomain; 772 //PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel();
707 773 //AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition();
708 //PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel(); 774 //PermissionSet sandboxPermissionSet = sandboxPolicy.GetNamedPermissionSet("Internet");
709 //AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition(); 775 //PolicyStatement sandboxPolicyStatement = new PolicyStatement(sandboxPermissionSet);
710 //PermissionSet sandboxPermissionSet = sandboxPolicy.GetNamedPermissionSet("Internet"); 776 //CodeGroup sandboxCodeGroup = new UnionCodeGroup(sandboxMembershipCondition, sandboxPolicyStatement);
711 //PolicyStatement sandboxPolicyStatement = new PolicyStatement(sandboxPermissionSet); 777 //sandboxPolicy.RootCodeGroup = sandboxCodeGroup;
712 //CodeGroup sandboxCodeGroup = new UnionCodeGroup(sandboxMembershipCondition, sandboxPolicyStatement); 778 //sandbox.SetAppDomainPolicy(sandboxPolicy);
713 //sandboxPolicy.RootCodeGroup = sandboxCodeGroup; 779
714 //sandbox.SetAppDomainPolicy(sandboxPolicy); 780 m_AppDomains[appDomain] = sandbox;
715 781
716 m_AppDomains[appDomain] = sandbox; 782 m_AppDomains[appDomain].AssemblyResolve +=
717 783 new ResolveEventHandler(
718 m_AppDomains[appDomain].AssemblyResolve += 784 AssemblyResolver.OnAssemblyResolve);
719 new ResolveEventHandler( 785 m_DomainScripts[appDomain] = new List<UUID>();
720 AssemblyResolver.OnAssemblyResolve);
721 m_DomainScripts[appDomain] = new List<UUID>();
722 }
723 catch (Exception e)
724 {
725 m_log.ErrorFormat("[XEngine] Exception creating app domain:\n {0}", e.ToString());
726 m_ScriptErrorMessage += "Exception creating app domain:\n";
727 m_ScriptFailCount++;
728 lock (m_AddingAssemblies)
729 {
730 m_AddingAssemblies[assembly]--;
731 }
732 return false;
733 }
734 } 786 }
735 m_DomainScripts[appDomain].Add(itemID); 787 catch (Exception e)
736
737 instance = new ScriptInstance(this, part,
738 itemID, assetID, assembly,
739 m_AppDomains[appDomain],
740 part.ParentGroup.RootPart.Name,
741 item.Name, startParam, postOnRez,
742 stateSource, m_MaxScriptQueue);
743
744 m_log.DebugFormat("[XEngine] Loaded script {0}.{1}, script UUID {2}, prim UUID {3} @ {4}",
745 part.ParentGroup.RootPart.Name, item.Name, assetID, part.UUID, part.ParentGroup.RootPart.AbsolutePosition.ToString());
746
747 if (presence != null)
748 { 788 {
749 ShowScriptSaveResponse(item.OwnerID, 789 m_log.ErrorFormat("[XEngine] Exception creating app domain:\n {0}", e.ToString());
750 assetID, "Compile successful", true); 790 m_ScriptErrorMessage += "Exception creating app domain:\n";
791 m_ScriptFailCount++;
792 lock (m_AddingAssemblies)
793 {
794 m_AddingAssemblies[assembly]--;
795 }
796 return false;
751 } 797 }
798 }
799 m_DomainScripts[appDomain].Add(itemID);
752 800
753 instance.AppDomain = appDomain; 801 instance = new ScriptInstance(this, part,
754 instance.LineMap = linemap; 802 itemID, assetID, assembly,
803 m_AppDomains[appDomain],
804 part.ParentGroup.RootPart.Name,
805 item.Name, startParam, postOnRez,
806 stateSource, m_MaxScriptQueue);
755 807
756 m_Scripts[itemID] = instance; 808 m_log.DebugFormat("[XEngine] Loaded script {0}.{1}, script UUID {2}, prim UUID {3} @ {4}",
757 } 809 part.ParentGroup.RootPart.Name, item.Name, assetID, part.UUID, part.ParentGroup.RootPart.AbsolutePosition.ToString());
758 810
759 lock (m_PrimObjects) 811 if (presence != null)
760 { 812 {
761 if (!m_PrimObjects.ContainsKey(localID)) 813 ShowScriptSaveResponse(item.OwnerID,
762 m_PrimObjects[localID] = new List<UUID>(); 814 assetID, "Compile successful", true);
815 }
763 816
764 if (!m_PrimObjects[localID].Contains(itemID)) 817 instance.AppDomain = appDomain;
765 m_PrimObjects[localID].Add(itemID); 818 instance.LineMap = linemap;
819 lockScriptsForWrite(true);
820 m_Scripts[itemID] = instance;
821 lockScriptsForWrite(false);
822 }
823 else
824 {
825 lockScriptsForRead(false);
826 }
827 lock (m_PrimObjects)
828 {
829 if (!m_PrimObjects.ContainsKey(localID))
830 m_PrimObjects[localID] = new List<UUID>();
766 831
767 } 832 if (!m_PrimObjects[localID].Contains(itemID))
833 m_PrimObjects[localID].Add(itemID);
768 834
769 if (!m_Assemblies.ContainsKey(assetID)) 835 }
770 m_Assemblies[assetID] = assembly;
771 836
772 lock (m_AddingAssemblies) 837 if (!m_Assemblies.ContainsKey(assetID))
773 { 838 m_Assemblies[assetID] = assembly;
774 m_AddingAssemblies[assembly]--;
775 }
776 839
777 if (instance!=null) 840 lock (m_AddingAssemblies)
778 instance.Init(); 841 {
842 m_AddingAssemblies[assembly]--;
779 } 843 }
844
845 if (instance!=null)
846 instance.Init();
847
780 return true; 848 return true;
781 } 849 }
782 850
783 public void OnRemoveScript(uint localID, UUID itemID) 851 public void OnRemoveScript(uint localID, UUID itemID)
784 { 852 {
785 lock (m_Scripts) 853 lockScriptsForRead(true);
854 // Do we even have it?
855 if (!m_Scripts.ContainsKey(itemID))
786 { 856 {
787 // Do we even have it? 857 lockScriptsForRead(false);
788 if (!m_Scripts.ContainsKey(itemID)) 858 return;
789 return; 859 }
860
790 861
791 IScriptInstance instance=m_Scripts[itemID]; 862 IScriptInstance instance=m_Scripts[itemID];
792 m_Scripts.Remove(itemID); 863 lockScriptsForRead(false);
864 lockScriptsForWrite(true);
865 m_Scripts.Remove(itemID);
866 lockScriptsForWrite(false);
867 instance.ClearQueue();
868 instance.Stop(0);
793 869
794 instance.ClearQueue(); 870 SceneObjectPart part =
795 instance.Stop(0); 871 m_Scene.GetSceneObjectPart(localID);
796 872
797 SceneObjectPart part = 873 if (part != null)
798 m_Scene.GetSceneObjectPart(localID); 874 part.RemoveScriptEvents(itemID);
799
800 if (part != null)
801 part.RemoveScriptEvents(itemID);
802 875
803// bool objectRemoved = false; 876// bool objectRemoved = false;
804 877
805 lock (m_PrimObjects) 878 lock (m_PrimObjects)
879 {
880 // Remove the script from it's prim
881 if (m_PrimObjects.ContainsKey(localID))
806 { 882 {
807 // Remove the script from it's prim 883 // Remove inventory item record
808 if (m_PrimObjects.ContainsKey(localID)) 884 if (m_PrimObjects[localID].Contains(itemID))
809 { 885 m_PrimObjects[localID].Remove(itemID);
810 // Remove inventory item record
811 if (m_PrimObjects[localID].Contains(itemID))
812 m_PrimObjects[localID].Remove(itemID);
813 886
814 // If there are no more scripts, remove prim 887 // If there are no more scripts, remove prim
815 if (m_PrimObjects[localID].Count == 0) 888 if (m_PrimObjects[localID].Count == 0)
816 { 889 {
817 m_PrimObjects.Remove(localID); 890 m_PrimObjects.Remove(localID);
818// objectRemoved = true; 891// objectRemoved = true;
819 }
820 } 892 }
821 } 893 }
894 }
822 895
823 instance.RemoveState(); 896 instance.RemoveState();
824 instance.DestroyScriptInstance(); 897 instance.DestroyScriptInstance();
825 898
826 m_DomainScripts[instance.AppDomain].Remove(instance.ItemID); 899 m_DomainScripts[instance.AppDomain].Remove(instance.ItemID);
827 if (m_DomainScripts[instance.AppDomain].Count == 0) 900 if (m_DomainScripts[instance.AppDomain].Count == 0)
828 { 901 {
829 m_DomainScripts.Remove(instance.AppDomain); 902 m_DomainScripts.Remove(instance.AppDomain);
830 UnloadAppDomain(instance.AppDomain); 903 UnloadAppDomain(instance.AppDomain);
831 } 904 }
832 905
833 instance = null; 906 instance = null;
834 907
835 ObjectRemoved handlerObjectRemoved = OnObjectRemoved; 908 ObjectRemoved handlerObjectRemoved = OnObjectRemoved;
836 if (handlerObjectRemoved != null) 909 if (handlerObjectRemoved != null)
837 handlerObjectRemoved(part.UUID); 910 handlerObjectRemoved(part.UUID);
838 911
839 CleanAssemblies(); 912 CleanAssemblies();
840 } 913
841 914
842 ScriptRemoved handlerScriptRemoved = OnScriptRemoved; 915 ScriptRemoved handlerScriptRemoved = OnScriptRemoved;
843 if (handlerScriptRemoved != null) 916 if (handlerScriptRemoved != null)
@@ -1090,12 +1163,14 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1090 private IScriptInstance GetInstance(UUID itemID) 1163 private IScriptInstance GetInstance(UUID itemID)
1091 { 1164 {
1092 IScriptInstance instance; 1165 IScriptInstance instance;
1093 lock (m_Scripts) 1166 lockScriptsForRead(true);
1167 if (!m_Scripts.ContainsKey(itemID))
1094 { 1168 {
1095 if (!m_Scripts.ContainsKey(itemID)) 1169 lockScriptsForRead(false);
1096 return null; 1170 return null;
1097 instance = m_Scripts[itemID];
1098 } 1171 }
1172 instance = m_Scripts[itemID];
1173 lockScriptsForRead(false);
1099 return instance; 1174 return instance;
1100 } 1175 }
1101 1176
@@ -1119,6 +1194,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1119 return false; 1194 return false;
1120 } 1195 }
1121 1196
1197 [DebuggerNonUserCode]
1122 public void ApiResetScript(UUID itemID) 1198 public void ApiResetScript(UUID itemID)
1123 { 1199 {
1124 IScriptInstance instance = GetInstance(itemID); 1200 IScriptInstance instance = GetInstance(itemID);
@@ -1170,6 +1246,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1170 return UUID.Zero; 1246 return UUID.Zero;
1171 } 1247 }
1172 1248
1249 [DebuggerNonUserCode]
1173 public void SetState(UUID itemID, string newState) 1250 public void SetState(UUID itemID, string newState)
1174 { 1251 {
1175 IScriptInstance instance = GetInstance(itemID); 1252 IScriptInstance instance = GetInstance(itemID);
@@ -1197,11 +1274,10 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1197 { 1274 {
1198 List<IScriptInstance> instances = new List<IScriptInstance>(); 1275 List<IScriptInstance> instances = new List<IScriptInstance>();
1199 1276
1200 lock (m_Scripts) 1277 lockScriptsForRead(true);
1201 { 1278 foreach (IScriptInstance instance in m_Scripts.Values)
1202 foreach (IScriptInstance instance in m_Scripts.Values)
1203 instances.Add(instance); 1279 instances.Add(instance);
1204 } 1280 lockScriptsForRead(false);
1205 1281
1206 foreach (IScriptInstance i in instances) 1282 foreach (IScriptInstance i in instances)
1207 { 1283 {