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.cs423
1 files changed, 251 insertions, 172 deletions
diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
index 2fc2ea1..184af19 100644
--- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
+++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
@@ -101,6 +101,8 @@ namespace OpenSim.Region.ScriptEngine.XEngine
101 private Dictionary<UUID, IScriptInstance> m_Scripts = 101 private Dictionary<UUID, IScriptInstance> m_Scripts =
102 new Dictionary<UUID, IScriptInstance>(); 102 new Dictionary<UUID, IScriptInstance>();
103 103
104 private OpenMetaverse.ReaderWriterLockSlim m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim();
105
104 // Maps the asset ID to the assembly 106 // Maps the asset ID to the assembly
105 107
106 private Dictionary<UUID, string> m_Assemblies = 108 private Dictionary<UUID, string> m_Assemblies =
@@ -122,6 +124,71 @@ namespace OpenSim.Region.ScriptEngine.XEngine
122 private ScriptCompileQueue m_CompileQueue = new ScriptCompileQueue(); 124 private ScriptCompileQueue m_CompileQueue = new ScriptCompileQueue();
123 IWorkItemResult m_CurrentCompile = null; 125 IWorkItemResult m_CurrentCompile = null;
124 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 if (m_scriptsLock.RecursiveReadCount > 0)
154 {
155 m_scriptsLock.ExitReadLock();
156 }
157 }
158 }
159 private void lockScriptsForWrite(bool locked)
160 {
161 if (locked)
162 {
163 if (m_scriptsLock.RecursiveReadCount > 0)
164 {
165 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.");
166 m_scriptsLock.ExitReadLock();
167 }
168 if (m_scriptsLock.RecursiveWriteCount > 0)
169 {
170 m_log.Error("[XEngine.m_Scripts] Recursive write lock requested. This should not happen and means something needs to be fixed.");
171 m_scriptsLock.ExitWriteLock();
172 }
173
174 while (!m_scriptsLock.TryEnterWriteLock(60000))
175 {
176 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.");
177 if (m_scriptsLock.IsWriteLockHeld)
178 {
179 m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim();
180 }
181 }
182 }
183 else
184 {
185 if (m_scriptsLock.RecursiveWriteCount > 0)
186 {
187 m_scriptsLock.ExitWriteLock();
188 }
189 }
190 }
191
125 public string ScriptEngineName 192 public string ScriptEngineName
126 { 193 {
127 get { return "XEngine"; } 194 get { return "XEngine"; }
@@ -261,43 +328,45 @@ namespace OpenSim.Region.ScriptEngine.XEngine
261 328
262 public void RemoveRegion(Scene scene) 329 public void RemoveRegion(Scene scene)
263 { 330 {
264 lock (m_Scripts) 331 lockScriptsForRead(true);
332 foreach (IScriptInstance instance in m_Scripts.Values)
265 { 333 {
266 foreach (IScriptInstance instance in m_Scripts.Values) 334 // Force a final state save
335 //
336 if (m_Assemblies.ContainsKey(instance.AssetID))
267 { 337 {
268 // Force a final state save 338 string assembly = m_Assemblies[instance.AssetID];
269 // 339 instance.SaveState(assembly);
270 if (m_Assemblies.ContainsKey(instance.AssetID)) 340 }
271 {
272 string assembly = m_Assemblies[instance.AssetID];
273 instance.SaveState(assembly);
274 }
275 341
276 // Clear the event queue and abort the instance thread 342 // Clear the event queue and abort the instance thread
277 // 343 //
278 instance.ClearQueue(); 344 instance.ClearQueue();
279 instance.Stop(0); 345 instance.Stop(0);
280 346
281 // Release events, timer, etc 347 // Release events, timer, etc
282 // 348 //
283 instance.DestroyScriptInstance(); 349 instance.DestroyScriptInstance();
284 350
285 // Unload scripts and app domains 351 // Unload scripts and app domains
286 // Must be done explicitly because they have infinite 352 // Must be done explicitly because they have infinite
287 // lifetime 353 // lifetime
288 // 354 //
289 m_DomainScripts[instance.AppDomain].Remove(instance.ItemID); 355 m_DomainScripts[instance.AppDomain].Remove(instance.ItemID);
290 if (m_DomainScripts[instance.AppDomain].Count == 0) 356 if (m_DomainScripts[instance.AppDomain].Count == 0)
291 { 357 {
292 m_DomainScripts.Remove(instance.AppDomain); 358 m_DomainScripts.Remove(instance.AppDomain);
293 UnloadAppDomain(instance.AppDomain); 359 UnloadAppDomain(instance.AppDomain);
294 }
295 } 360 }
296 m_Scripts.Clear();
297 m_PrimObjects.Clear();
298 m_Assemblies.Clear();
299 m_DomainScripts.Clear();
300 } 361 }
362 lockScriptsForRead(false);
363 lockScriptsForWrite(true);
364 m_Scripts.Clear();
365 lockScriptsForWrite(false);
366 m_PrimObjects.Clear();
367 m_Assemblies.Clear();
368 m_DomainScripts.Clear();
369
301 lock (m_ScriptEngines) 370 lock (m_ScriptEngines)
302 { 371 {
303 m_ScriptEngines.Remove(this); 372 m_ScriptEngines.Remove(this);
@@ -356,22 +425,20 @@ namespace OpenSim.Region.ScriptEngine.XEngine
356 425
357 List<IScriptInstance> instances = new List<IScriptInstance>(); 426 List<IScriptInstance> instances = new List<IScriptInstance>();
358 427
359 lock (m_Scripts) 428 lockScriptsForRead(true);
360 { 429 foreach (IScriptInstance instance in m_Scripts.Values)
361 foreach (IScriptInstance instance in m_Scripts.Values)
362 instances.Add(instance); 430 instances.Add(instance);
363 } 431 lockScriptsForRead(false);
364 432
365 foreach (IScriptInstance i in instances) 433 foreach (IScriptInstance i in instances)
366 { 434 {
367 string assembly = String.Empty; 435 string assembly = String.Empty;
368 436
369 lock (m_Scripts) 437
370 {
371 if (!m_Assemblies.ContainsKey(i.AssetID)) 438 if (!m_Assemblies.ContainsKey(i.AssetID))
372 continue; 439 continue;
373 assembly = m_Assemblies[i.AssetID]; 440 assembly = m_Assemblies[i.AssetID];
374 } 441
375 442
376 i.SaveState(assembly); 443 i.SaveState(assembly);
377 } 444 }
@@ -673,172 +740,183 @@ namespace OpenSim.Region.ScriptEngine.XEngine
673 return false; 740 return false;
674 } 741 }
675 742
676 lock (m_Scripts) 743
744
745 ScriptInstance instance = null;
746 // Create the object record
747 lockScriptsForRead(true);
748 if ((!m_Scripts.ContainsKey(itemID)) ||
749 (m_Scripts[itemID].AssetID != assetID))
677 { 750 {
678 ScriptInstance instance = null; 751 lockScriptsForRead(false);
679 // Create the object record
680 752
681 if ((!m_Scripts.ContainsKey(itemID)) || 753 UUID appDomain = assetID;
682 (m_Scripts[itemID].AssetID != assetID))
683 {
684 UUID appDomain = assetID;
685 754
686 if (part.ParentGroup.IsAttachment) 755 if (part.ParentGroup.IsAttachment)
687 appDomain = part.ParentGroup.RootPart.UUID; 756 appDomain = part.ParentGroup.RootPart.UUID;
688 757
689 if (!m_AppDomains.ContainsKey(appDomain)) 758 if (!m_AppDomains.ContainsKey(appDomain))
759 {
760 try
690 { 761 {
691 try 762 AppDomainSetup appSetup = new AppDomainSetup();
692 { 763 // appSetup.ApplicationBase = Path.Combine(
693 AppDomainSetup appSetup = new AppDomainSetup(); 764 // "ScriptEngines",
694// appSetup.ApplicationBase = Path.Combine( 765 // m_Scene.RegionInfo.RegionID.ToString());
695// "ScriptEngines", 766
696// m_Scene.RegionInfo.RegionID.ToString()); 767 Evidence baseEvidence = AppDomain.CurrentDomain.Evidence;
697 768 Evidence evidence = new Evidence(baseEvidence);
698 Evidence baseEvidence = AppDomain.CurrentDomain.Evidence; 769
699 Evidence evidence = new Evidence(baseEvidence); 770 AppDomain sandbox;
700 771 if (m_AppDomainLoading)
701 AppDomain sandbox; 772 sandbox = AppDomain.CreateDomain(
702 if (m_AppDomainLoading) 773 m_Scene.RegionInfo.RegionID.ToString(),
703 sandbox = AppDomain.CreateDomain( 774 evidence, appSetup);
704 m_Scene.RegionInfo.RegionID.ToString(), 775 else
705 evidence, appSetup); 776 sandbox = AppDomain.CurrentDomain;
706 else 777
707 sandbox = AppDomain.CurrentDomain; 778 //PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel();
708 779 //AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition();
709 //PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel(); 780 //PermissionSet sandboxPermissionSet = sandboxPolicy.GetNamedPermissionSet("Internet");
710 //AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition(); 781 //PolicyStatement sandboxPolicyStatement = new PolicyStatement(sandboxPermissionSet);
711 //PermissionSet sandboxPermissionSet = sandboxPolicy.GetNamedPermissionSet("Internet"); 782 //CodeGroup sandboxCodeGroup = new UnionCodeGroup(sandboxMembershipCondition, sandboxPolicyStatement);
712 //PolicyStatement sandboxPolicyStatement = new PolicyStatement(sandboxPermissionSet); 783 //sandboxPolicy.RootCodeGroup = sandboxCodeGroup;
713 //CodeGroup sandboxCodeGroup = new UnionCodeGroup(sandboxMembershipCondition, sandboxPolicyStatement); 784 //sandbox.SetAppDomainPolicy(sandboxPolicy);
714 //sandboxPolicy.RootCodeGroup = sandboxCodeGroup; 785
715 //sandbox.SetAppDomainPolicy(sandboxPolicy); 786 m_AppDomains[appDomain] = sandbox;
716 787
717 m_AppDomains[appDomain] = sandbox; 788 m_AppDomains[appDomain].AssemblyResolve +=
718 789 new ResolveEventHandler(
719 m_AppDomains[appDomain].AssemblyResolve += 790 AssemblyResolver.OnAssemblyResolve);
720 new ResolveEventHandler( 791 m_DomainScripts[appDomain] = new List<UUID>();
721 AssemblyResolver.OnAssemblyResolve);
722 m_DomainScripts[appDomain] = new List<UUID>();
723 }
724 catch (Exception e)
725 {
726 m_log.ErrorFormat("[XEngine] Exception creating app domain:\n {0}", e.ToString());
727 m_ScriptErrorMessage += "Exception creating app domain:\n";
728 m_ScriptFailCount++;
729 lock (m_AddingAssemblies)
730 {
731 m_AddingAssemblies[assembly]--;
732 }
733 return false;
734 }
735 } 792 }
736 m_DomainScripts[appDomain].Add(itemID); 793 catch (Exception e)
737
738 instance = new ScriptInstance(this, part,
739 itemID, assetID, assembly,
740 m_AppDomains[appDomain],
741 part.ParentGroup.RootPart.Name,
742 item.Name, startParam, postOnRez,
743 stateSource, m_MaxScriptQueue);
744
745 m_log.DebugFormat("[XEngine] Loaded script {0}.{1}, script UUID {2}, prim UUID {3} @ {4}",
746 part.ParentGroup.RootPart.Name, item.Name, assetID, part.UUID, part.ParentGroup.RootPart.AbsolutePosition.ToString());
747
748 if (presence != null)
749 { 794 {
750 ShowScriptSaveResponse(item.OwnerID, 795 m_log.ErrorFormat("[XEngine] Exception creating app domain:\n {0}", e.ToString());
751 assetID, "Compile successful", true); 796 m_ScriptErrorMessage += "Exception creating app domain:\n";
797 m_ScriptFailCount++;
798 lock (m_AddingAssemblies)
799 {
800 m_AddingAssemblies[assembly]--;
801 }
802 return false;
752 } 803 }
804 }
805 m_DomainScripts[appDomain].Add(itemID);
753 806
754 instance.AppDomain = appDomain; 807 instance = new ScriptInstance(this, part,
755 instance.LineMap = linemap; 808 itemID, assetID, assembly,
809 m_AppDomains[appDomain],
810 part.ParentGroup.RootPart.Name,
811 item.Name, startParam, postOnRez,
812 stateSource, m_MaxScriptQueue);
756 813
757 m_Scripts[itemID] = instance; 814 m_log.DebugFormat("[XEngine] Loaded script {0}.{1}, script UUID {2}, prim UUID {3} @ {4}",
758 } 815 part.ParentGroup.RootPart.Name, item.Name, assetID, part.UUID, part.ParentGroup.RootPart.AbsolutePosition.ToString());
759 816
760 lock (m_PrimObjects) 817 if (presence != null)
761 { 818 {
762 if (!m_PrimObjects.ContainsKey(localID)) 819 ShowScriptSaveResponse(item.OwnerID,
763 m_PrimObjects[localID] = new List<UUID>(); 820 assetID, "Compile successful", true);
821 }
764 822
765 if (!m_PrimObjects[localID].Contains(itemID)) 823 instance.AppDomain = appDomain;
766 m_PrimObjects[localID].Add(itemID); 824 instance.LineMap = linemap;
825 lockScriptsForWrite(true);
826 m_Scripts[itemID] = instance;
827 lockScriptsForWrite(false);
828 }
829 else
830 {
831 lockScriptsForRead(false);
832 }
833 lock (m_PrimObjects)
834 {
835 if (!m_PrimObjects.ContainsKey(localID))
836 m_PrimObjects[localID] = new List<UUID>();
767 837
768 } 838 if (!m_PrimObjects[localID].Contains(itemID))
839 m_PrimObjects[localID].Add(itemID);
769 840
770 if (!m_Assemblies.ContainsKey(assetID)) 841 }
771 m_Assemblies[assetID] = assembly;
772 842
773 lock (m_AddingAssemblies) 843 if (!m_Assemblies.ContainsKey(assetID))
774 { 844 m_Assemblies[assetID] = assembly;
775 m_AddingAssemblies[assembly]--;
776 }
777 845
778 if (instance!=null) 846 lock (m_AddingAssemblies)
779 instance.Init(); 847 {
848 m_AddingAssemblies[assembly]--;
780 } 849 }
850
851 if (instance!=null)
852 instance.Init();
853
781 return true; 854 return true;
782 } 855 }
783 856
784 public void OnRemoveScript(uint localID, UUID itemID) 857 public void OnRemoveScript(uint localID, UUID itemID)
785 { 858 {
786 lock (m_Scripts) 859 lockScriptsForRead(true);
860 // Do we even have it?
861 if (!m_Scripts.ContainsKey(itemID))
787 { 862 {
788 // Do we even have it? 863 lockScriptsForRead(false);
789 if (!m_Scripts.ContainsKey(itemID)) 864 return;
790 return; 865 }
791 866
792 IScriptInstance instance=m_Scripts[itemID];
793 m_Scripts.Remove(itemID);
794 867
795 instance.ClearQueue(); 868 IScriptInstance instance=m_Scripts[itemID];
796 instance.Stop(0); 869 lockScriptsForRead(false);
870 lockScriptsForWrite(true);
871 m_Scripts.Remove(itemID);
872 lockScriptsForWrite(false);
873 instance.ClearQueue();
874 instance.Stop(0);
797 875
798 SceneObjectPart part = 876 SceneObjectPart part =
799 m_Scene.GetSceneObjectPart(localID); 877 m_Scene.GetSceneObjectPart(localID);
800 878
801 if (part != null) 879 if (part != null)
802 part.RemoveScriptEvents(itemID); 880 part.RemoveScriptEvents(itemID);
803 881
804// bool objectRemoved = false; 882// bool objectRemoved = false;
805 883
806 lock (m_PrimObjects) 884 lock (m_PrimObjects)
885 {
886 // Remove the script from it's prim
887 if (m_PrimObjects.ContainsKey(localID))
807 { 888 {
808 // Remove the script from it's prim 889 // Remove inventory item record
809 if (m_PrimObjects.ContainsKey(localID)) 890 if (m_PrimObjects[localID].Contains(itemID))
810 { 891 m_PrimObjects[localID].Remove(itemID);
811 // Remove inventory item record
812 if (m_PrimObjects[localID].Contains(itemID))
813 m_PrimObjects[localID].Remove(itemID);
814 892
815 // If there are no more scripts, remove prim 893 // If there are no more scripts, remove prim
816 if (m_PrimObjects[localID].Count == 0) 894 if (m_PrimObjects[localID].Count == 0)
817 { 895 {
818 m_PrimObjects.Remove(localID); 896 m_PrimObjects.Remove(localID);
819// objectRemoved = true; 897// objectRemoved = true;
820 }
821 } 898 }
822 } 899 }
900 }
823 901
824 instance.RemoveState(); 902 instance.RemoveState();
825 instance.DestroyScriptInstance(); 903 instance.DestroyScriptInstance();
826 904
827 m_DomainScripts[instance.AppDomain].Remove(instance.ItemID); 905 m_DomainScripts[instance.AppDomain].Remove(instance.ItemID);
828 if (m_DomainScripts[instance.AppDomain].Count == 0) 906 if (m_DomainScripts[instance.AppDomain].Count == 0)
829 { 907 {
830 m_DomainScripts.Remove(instance.AppDomain); 908 m_DomainScripts.Remove(instance.AppDomain);
831 UnloadAppDomain(instance.AppDomain); 909 UnloadAppDomain(instance.AppDomain);
832 } 910 }
833 911
834 instance = null; 912 instance = null;
835 913
836 ObjectRemoved handlerObjectRemoved = OnObjectRemoved; 914 ObjectRemoved handlerObjectRemoved = OnObjectRemoved;
837 if (handlerObjectRemoved != null) 915 if (handlerObjectRemoved != null)
838 handlerObjectRemoved(part.UUID); 916 handlerObjectRemoved(part.UUID);
839 917
840 CleanAssemblies(); 918 CleanAssemblies();
841 } 919
842 920
843 ScriptRemoved handlerScriptRemoved = OnScriptRemoved; 921 ScriptRemoved handlerScriptRemoved = OnScriptRemoved;
844 if (handlerScriptRemoved != null) 922 if (handlerScriptRemoved != null)
@@ -1091,12 +1169,14 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1091 private IScriptInstance GetInstance(UUID itemID) 1169 private IScriptInstance GetInstance(UUID itemID)
1092 { 1170 {
1093 IScriptInstance instance; 1171 IScriptInstance instance;
1094 lock (m_Scripts) 1172 lockScriptsForRead(true);
1173 if (!m_Scripts.ContainsKey(itemID))
1095 { 1174 {
1096 if (!m_Scripts.ContainsKey(itemID)) 1175 lockScriptsForRead(false);
1097 return null; 1176 return null;
1098 instance = m_Scripts[itemID];
1099 } 1177 }
1178 instance = m_Scripts[itemID];
1179 lockScriptsForRead(false);
1100 return instance; 1180 return instance;
1101 } 1181 }
1102 1182
@@ -1200,11 +1280,10 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1200 { 1280 {
1201 List<IScriptInstance> instances = new List<IScriptInstance>(); 1281 List<IScriptInstance> instances = new List<IScriptInstance>();
1202 1282
1203 lock (m_Scripts) 1283 lockScriptsForRead(true);
1204 { 1284 foreach (IScriptInstance instance in m_Scripts.Values)
1205 foreach (IScriptInstance instance in m_Scripts.Values)
1206 instances.Add(instance); 1285 instances.Add(instance);
1207 } 1286 lockScriptsForRead(false);
1208 1287
1209 foreach (IScriptInstance i in instances) 1288 foreach (IScriptInstance i in instances)
1210 { 1289 {
@@ -1394,7 +1473,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1394 if (rootE.GetAttribute("UUID") != itemID.ToString()) 1473 if (rootE.GetAttribute("UUID") != itemID.ToString())
1395 return; 1474 return;
1396 1475
1397 string assetID = rootE.GetAttribute("Asset"); 1476// string assetID = rootE.GetAttribute("Asset");
1398 1477
1399 XmlNodeList stateL = rootE.GetElementsByTagName("ScriptState"); 1478 XmlNodeList stateL = rootE.GetElementsByTagName("ScriptState");
1400 1479