aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ScriptEngine/XEngine
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ScriptEngine/XEngine')
-rw-r--r--OpenSim/Region/ScriptEngine/XEngine/XEngine.cs357
1 files changed, 222 insertions, 135 deletions
diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
index c74cd64..d606b37 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;
@@ -103,6 +104,8 @@ namespace OpenSim.Region.ScriptEngine.XEngine
103 private Dictionary<UUID, IScriptInstance> m_Scripts = 104 private Dictionary<UUID, IScriptInstance> m_Scripts =
104 new Dictionary<UUID, IScriptInstance>(); 105 new Dictionary<UUID, IScriptInstance>();
105 106
107 private OpenMetaverse.ReaderWriterLockSlim m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim();
108
106 // Maps the asset ID to the assembly 109 // Maps the asset ID to the assembly
107 110
108 private Dictionary<UUID, string> m_Assemblies = 111 private Dictionary<UUID, string> m_Assemblies =
@@ -125,6 +128,71 @@ namespace OpenSim.Region.ScriptEngine.XEngine
125 IWorkItemResult m_CurrentCompile = null; 128 IWorkItemResult m_CurrentCompile = null;
126 private Dictionary<UUID, int> m_CompileDict = new Dictionary<UUID, int>(); 129 private Dictionary<UUID, int> m_CompileDict = new Dictionary<UUID, int>();
127 130
131 private void lockScriptsForRead(bool locked)
132 {
133 if (locked)
134 {
135 if (m_scriptsLock.RecursiveReadCount > 0)
136 {
137 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.");
138 m_scriptsLock.ExitReadLock();
139 }
140 if (m_scriptsLock.RecursiveWriteCount > 0)
141 {
142 m_log.Error("[XEngine.m_Scripts] Recursive write lock requested. This should not happen and means something needs to be fixed.");
143 m_scriptsLock.ExitWriteLock();
144 }
145
146 while (!m_scriptsLock.TryEnterReadLock(60000))
147 {
148 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.");
149 if (m_scriptsLock.IsWriteLockHeld)
150 {
151 m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim();
152 }
153 }
154 }
155 else
156 {
157 if (m_scriptsLock.RecursiveReadCount > 0)
158 {
159 m_scriptsLock.ExitReadLock();
160 }
161 }
162 }
163 private void lockScriptsForWrite(bool locked)
164 {
165 if (locked)
166 {
167 if (m_scriptsLock.RecursiveReadCount > 0)
168 {
169 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.");
170 m_scriptsLock.ExitReadLock();
171 }
172 if (m_scriptsLock.RecursiveWriteCount > 0)
173 {
174 m_log.Error("[XEngine.m_Scripts] Recursive write lock requested. This should not happen and means something needs to be fixed.");
175 m_scriptsLock.ExitWriteLock();
176 }
177
178 while (!m_scriptsLock.TryEnterWriteLock(60000))
179 {
180 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.");
181 if (m_scriptsLock.IsWriteLockHeld)
182 {
183 m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim();
184 }
185 }
186 }
187 else
188 {
189 if (m_scriptsLock.RecursiveWriteCount > 0)
190 {
191 m_scriptsLock.ExitWriteLock();
192 }
193 }
194 }
195
128 public string ScriptEngineName 196 public string ScriptEngineName
129 { 197 {
130 get { return "XEngine"; } 198 get { return "XEngine"; }
@@ -317,47 +385,45 @@ namespace OpenSim.Region.ScriptEngine.XEngine
317 { 385 {
318 if (!m_Enabled) 386 if (!m_Enabled)
319 return; 387 return;
320 388 lockScriptsForRead(true);
321 lock (m_Scripts) 389 foreach (IScriptInstance instance in m_Scripts.Values)
322 { 390 {
323 m_log.InfoFormat( 391 // Force a final state save
324 "[XEngine]: Shutting down {0} scripts in {1}", m_Scripts.Count, m_Scene.RegionInfo.RegionName); 392 //
325 393 if (m_Assemblies.ContainsKey(instance.AssetID))
326 foreach (IScriptInstance instance in m_Scripts.Values)
327 { 394 {
328 // Force a final state save 395 string assembly = m_Assemblies[instance.AssetID];
329 // 396 instance.SaveState(assembly);
330 if (m_Assemblies.ContainsKey(instance.AssetID)) 397 }
331 {
332 string assembly = m_Assemblies[instance.AssetID];
333 instance.SaveState(assembly);
334 }
335 398
336 // Clear the event queue and abort the instance thread 399 // Clear the event queue and abort the instance thread
337 // 400 //
338 instance.ClearQueue(); 401 instance.ClearQueue();
339 instance.Stop(0); 402 instance.Stop(0);
340 403
341 // Release events, timer, etc 404 // Release events, timer, etc
342 // 405 //
343 instance.DestroyScriptInstance(); 406 instance.DestroyScriptInstance();
344 407
345 // Unload scripts and app domains 408 // Unload scripts and app domains
346 // Must be done explicitly because they have infinite 409 // Must be done explicitly because they have infinite
347 // lifetime 410 // lifetime
348 // 411 //
349 m_DomainScripts[instance.AppDomain].Remove(instance.ItemID); 412 m_DomainScripts[instance.AppDomain].Remove(instance.ItemID);
350 if (m_DomainScripts[instance.AppDomain].Count == 0) 413 if (m_DomainScripts[instance.AppDomain].Count == 0)
351 { 414 {
352 m_DomainScripts.Remove(instance.AppDomain); 415 m_DomainScripts.Remove(instance.AppDomain);
353 UnloadAppDomain(instance.AppDomain); 416 UnloadAppDomain(instance.AppDomain);
354 }
355 } 417 }
356 m_Scripts.Clear();
357 m_PrimObjects.Clear();
358 m_Assemblies.Clear();
359 m_DomainScripts.Clear();
360 } 418 }
419 lockScriptsForRead(false);
420 lockScriptsForWrite(true);
421 m_Scripts.Clear();
422 lockScriptsForWrite(false);
423 m_PrimObjects.Clear();
424 m_Assemblies.Clear();
425 m_DomainScripts.Clear();
426
361 lock (m_ScriptEngines) 427 lock (m_ScriptEngines)
362 { 428 {
363 m_ScriptEngines.Remove(this); 429 m_ScriptEngines.Remove(this);
@@ -422,22 +488,20 @@ namespace OpenSim.Region.ScriptEngine.XEngine
422 488
423 List<IScriptInstance> instances = new List<IScriptInstance>(); 489 List<IScriptInstance> instances = new List<IScriptInstance>();
424 490
425 lock (m_Scripts) 491 lockScriptsForRead(true);
426 { 492 foreach (IScriptInstance instance in m_Scripts.Values)
427 foreach (IScriptInstance instance in m_Scripts.Values)
428 instances.Add(instance); 493 instances.Add(instance);
429 } 494 lockScriptsForRead(false);
430 495
431 foreach (IScriptInstance i in instances) 496 foreach (IScriptInstance i in instances)
432 { 497 {
433 string assembly = String.Empty; 498 string assembly = String.Empty;
434 499
435 lock (m_Scripts) 500
436 {
437 if (!m_Assemblies.ContainsKey(i.AssetID)) 501 if (!m_Assemblies.ContainsKey(i.AssetID))
438 continue; 502 continue;
439 assembly = m_Assemblies[i.AssetID]; 503 assembly = m_Assemblies[i.AssetID];
440 } 504
441 505
442 i.SaveState(assembly); 506 i.SaveState(assembly);
443 } 507 }
@@ -771,92 +835,95 @@ namespace OpenSim.Region.ScriptEngine.XEngine
771 } 835 }
772 836
773 ScriptInstance instance = null; 837 ScriptInstance instance = null;
774 lock (m_Scripts) 838 // Create the object record
839 lockScriptsForRead(true);
840 if ((!m_Scripts.ContainsKey(itemID)) ||
841 (m_Scripts[itemID].AssetID != assetID))
775 { 842 {
776 // Create the object record 843 lockScriptsForRead(false);
777 844
778 if ((!m_Scripts.ContainsKey(itemID)) || 845 UUID appDomain = assetID;
779 (m_Scripts[itemID].AssetID != assetID))
780 {
781 UUID appDomain = assetID;
782 846
783 if (part.ParentGroup.IsAttachment) 847 if (part.ParentGroup.IsAttachment)
784 appDomain = part.ParentGroup.RootPart.UUID; 848 appDomain = part.ParentGroup.RootPart.UUID;
785 849
786 if (!m_AppDomains.ContainsKey(appDomain)) 850 if (!m_AppDomains.ContainsKey(appDomain))
851 {
852 try
787 { 853 {
788 try 854 AppDomainSetup appSetup = new AppDomainSetup();
789 { 855 appSetup.PrivateBinPath = Path.Combine(
790 AppDomainSetup appSetup = new AppDomainSetup(); 856 m_ScriptEnginesPath,
791 appSetup.PrivateBinPath = Path.Combine( 857 m_Scene.RegionInfo.RegionID.ToString());
792 m_ScriptEnginesPath, 858
793 m_Scene.RegionInfo.RegionID.ToString()); 859 Evidence baseEvidence = AppDomain.CurrentDomain.Evidence;
794 860 Evidence evidence = new Evidence(baseEvidence);
795 Evidence baseEvidence = AppDomain.CurrentDomain.Evidence; 861
796 Evidence evidence = new Evidence(baseEvidence); 862 AppDomain sandbox;
797 863 if (m_AppDomainLoading)
798 AppDomain sandbox; 864 sandbox = AppDomain.CreateDomain(
799 if (m_AppDomainLoading) 865 m_Scene.RegionInfo.RegionID.ToString(),
800 sandbox = AppDomain.CreateDomain( 866 evidence, appSetup);
801 m_Scene.RegionInfo.RegionID.ToString(), 867 else
802 evidence, appSetup); 868 sandbox = AppDomain.CurrentDomain;
803 else 869
804 sandbox = AppDomain.CurrentDomain; 870 //PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel();
805 871 //AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition();
806 //PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel(); 872 //PermissionSet sandboxPermissionSet = sandboxPolicy.GetNamedPermissionSet("Internet");
807 //AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition(); 873 //PolicyStatement sandboxPolicyStatement = new PolicyStatement(sandboxPermissionSet);
808 //PermissionSet sandboxPermissionSet = sandboxPolicy.GetNamedPermissionSet("Internet"); 874 //CodeGroup sandboxCodeGroup = new UnionCodeGroup(sandboxMembershipCondition, sandboxPolicyStatement);
809 //PolicyStatement sandboxPolicyStatement = new PolicyStatement(sandboxPermissionSet); 875 //sandboxPolicy.RootCodeGroup = sandboxCodeGroup;
810 //CodeGroup sandboxCodeGroup = new UnionCodeGroup(sandboxMembershipCondition, sandboxPolicyStatement); 876 //sandbox.SetAppDomainPolicy(sandboxPolicy);
811 //sandboxPolicy.RootCodeGroup = sandboxCodeGroup; 877
812 //sandbox.SetAppDomainPolicy(sandboxPolicy); 878 m_AppDomains[appDomain] = sandbox;
813 879
814 m_AppDomains[appDomain] = sandbox; 880 m_AppDomains[appDomain].AssemblyResolve +=
815 881 new ResolveEventHandler(
816 m_AppDomains[appDomain].AssemblyResolve += 882 AssemblyResolver.OnAssemblyResolve);
817 new ResolveEventHandler( 883 m_DomainScripts[appDomain] = new List<UUID>();
818 AssemblyResolver.OnAssemblyResolve); 884 }
819 m_DomainScripts[appDomain] = new List<UUID>(); 885 catch (Exception e)
820 } 886 {
821 catch (Exception e) 887 m_log.ErrorFormat("[XEngine] Exception creating app domain:\n {0}", e.ToString());
888 m_ScriptErrorMessage += "Exception creating app domain:\n";
889 m_ScriptFailCount++;
890 lock (m_AddingAssemblies)
822 { 891 {
823 m_log.ErrorFormat("[XEngine] Exception creating app domain:\n {0}", e.ToString()); 892 m_AddingAssemblies[assembly]--;
824 m_ScriptErrorMessage += "Exception creating app domain:\n";
825 m_ScriptFailCount++;
826 lock (m_AddingAssemblies)
827 {
828 m_AddingAssemblies[assembly]--;
829 }
830 return false;
831 } 893 }
894 return false;
832 } 895 }
833 m_DomainScripts[appDomain].Add(itemID); 896 }
834 897 m_DomainScripts[appDomain].Add(itemID);
835 instance = new ScriptInstance(this, part, 898
836 itemID, assetID, assembly, 899 instance = new ScriptInstance(this, part,
837 m_AppDomains[appDomain], 900 itemID, assetID, assembly,
838 part.ParentGroup.RootPart.Name, 901 m_AppDomains[appDomain],
839 item.Name, startParam, postOnRez, 902 part.ParentGroup.RootPart.Name,
840 stateSource, m_MaxScriptQueue); 903 item.Name, startParam, postOnRez,
841 904 stateSource, m_MaxScriptQueue);
842 m_log.DebugFormat( 905
906 m_log.DebugFormat(
843 "[XEngine] Loaded script {0}.{1}, script UUID {2}, prim UUID {3} @ {4}.{5}", 907 "[XEngine] Loaded script {0}.{1}, script UUID {2}, prim UUID {3} @ {4}.{5}",
844 part.ParentGroup.RootPart.Name, item.Name, assetID, part.UUID, 908 part.ParentGroup.RootPart.Name, item.Name, assetID, part.UUID,
845 part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName); 909 part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName);
846 910
847 if (presence != null) 911 if (presence != null)
848 { 912 {
849 ShowScriptSaveResponse(item.OwnerID, 913 ShowScriptSaveResponse(item.OwnerID,
850 assetID, "Compile successful", true); 914 assetID, "Compile successful", true);
851 }
852
853 instance.AppDomain = appDomain;
854 instance.LineMap = linemap;
855
856 m_Scripts[itemID] = instance;
857 } 915 }
858 }
859 916
917 instance.AppDomain = appDomain;
918 instance.LineMap = linemap;
919 lockScriptsForWrite(true);
920 m_Scripts[itemID] = instance;
921 lockScriptsForWrite(false);
922 }
923 else
924 {
925 lockScriptsForRead(false);
926 }
860 lock (m_PrimObjects) 927 lock (m_PrimObjects)
861 { 928 {
862 if (!m_PrimObjects.ContainsKey(localID)) 929 if (!m_PrimObjects.ContainsKey(localID))
@@ -875,9 +942,9 @@ namespace OpenSim.Region.ScriptEngine.XEngine
875 m_AddingAssemblies[assembly]--; 942 m_AddingAssemblies[assembly]--;
876 } 943 }
877 944
878 if (instance != null) 945 if (instance!=null)
879 instance.Init(); 946 instance.Init();
880 947
881 return true; 948 return true;
882 } 949 }
883 950
@@ -890,20 +957,23 @@ namespace OpenSim.Region.ScriptEngine.XEngine
890 m_CompileDict.Remove(itemID); 957 m_CompileDict.Remove(itemID);
891 } 958 }
892 959
893 IScriptInstance instance = null; 960 lockScriptsForRead(true);
894 961 // Do we even have it?
895 lock (m_Scripts) 962 if (!m_Scripts.ContainsKey(itemID))
896 { 963 {
897 // Do we even have it? 964 lockScriptsForRead(false);
898 if (!m_Scripts.ContainsKey(itemID)) 965 return;
899 return;
900
901 instance=m_Scripts[itemID];
902 m_Scripts.Remove(itemID);
903 } 966 }
967
904 968
969 IScriptInstance instance=m_Scripts[itemID];
970 lockScriptsForRead(false);
971 lockScriptsForWrite(true);
972 m_Scripts.Remove(itemID);
973 lockScriptsForWrite(false);
905 instance.ClearQueue(); 974 instance.ClearQueue();
906 instance.Stop(0); 975 instance.Stop(0);
976
907// bool objectRemoved = false; 977// bool objectRemoved = false;
908 978
909 lock (m_PrimObjects) 979 lock (m_PrimObjects)
@@ -939,11 +1009,12 @@ namespace OpenSim.Region.ScriptEngine.XEngine
939 ObjectRemoved handlerObjectRemoved = OnObjectRemoved; 1009 ObjectRemoved handlerObjectRemoved = OnObjectRemoved;
940 if (handlerObjectRemoved != null) 1010 if (handlerObjectRemoved != null)
941 { 1011 {
942 SceneObjectPart part = m_Scene.GetSceneObjectPart(localID); 1012 SceneObjectPart part = m_Scene.GetSceneObjectPart(localID);
943 handlerObjectRemoved(part.UUID); 1013 handlerObjectRemoved(part.UUID);
944 } 1014 }
945 1015
946 1016 CleanAssemblies();
1017
947 ScriptRemoved handlerScriptRemoved = OnScriptRemoved; 1018 ScriptRemoved handlerScriptRemoved = OnScriptRemoved;
948 if (handlerScriptRemoved != null) 1019 if (handlerScriptRemoved != null)
949 handlerScriptRemoved(itemID); 1020 handlerScriptRemoved(itemID);
@@ -1085,7 +1156,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1085 return false; 1156 return false;
1086 1157
1087 uuids = m_PrimObjects[localID]; 1158 uuids = m_PrimObjects[localID];
1088 } 1159
1089 1160
1090 foreach (UUID itemID in uuids) 1161 foreach (UUID itemID in uuids)
1091 { 1162 {
@@ -1103,6 +1174,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1103 result = true; 1174 result = true;
1104 } 1175 }
1105 } 1176 }
1177 }
1106 1178
1107 return result; 1179 return result;
1108 } 1180 }
@@ -1202,12 +1274,14 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1202 private IScriptInstance GetInstance(UUID itemID) 1274 private IScriptInstance GetInstance(UUID itemID)
1203 { 1275 {
1204 IScriptInstance instance; 1276 IScriptInstance instance;
1205 lock (m_Scripts) 1277 lockScriptsForRead(true);
1278 if (!m_Scripts.ContainsKey(itemID))
1206 { 1279 {
1207 if (!m_Scripts.ContainsKey(itemID)) 1280 lockScriptsForRead(false);
1208 return null; 1281 return null;
1209 instance = m_Scripts[itemID];
1210 } 1282 }
1283 instance = m_Scripts[itemID];
1284 lockScriptsForRead(false);
1211 return instance; 1285 return instance;
1212 } 1286 }
1213 1287
@@ -1231,6 +1305,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1231 return false; 1305 return false;
1232 } 1306 }
1233 1307
1308 [DebuggerNonUserCode]
1234 public void ApiResetScript(UUID itemID) 1309 public void ApiResetScript(UUID itemID)
1235 { 1310 {
1236 IScriptInstance instance = GetInstance(itemID); 1311 IScriptInstance instance = GetInstance(itemID);
@@ -1282,6 +1357,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1282 return UUID.Zero; 1357 return UUID.Zero;
1283 } 1358 }
1284 1359
1360 [DebuggerNonUserCode]
1285 public void SetState(UUID itemID, string newState) 1361 public void SetState(UUID itemID, string newState)
1286 { 1362 {
1287 IScriptInstance instance = GetInstance(itemID); 1363 IScriptInstance instance = GetInstance(itemID);
@@ -1302,11 +1378,10 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1302 { 1378 {
1303 List<IScriptInstance> instances = new List<IScriptInstance>(); 1379 List<IScriptInstance> instances = new List<IScriptInstance>();
1304 1380
1305 lock (m_Scripts) 1381 lockScriptsForRead(true);
1306 { 1382 foreach (IScriptInstance instance in m_Scripts.Values)
1307 foreach (IScriptInstance instance in m_Scripts.Values)
1308 instances.Add(instance); 1383 instances.Add(instance);
1309 } 1384 lockScriptsForRead(false);
1310 1385
1311 foreach (IScriptInstance i in instances) 1386 foreach (IScriptInstance i in instances)
1312 { 1387 {
@@ -1687,5 +1762,17 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1687 1762
1688 instance.Resume(); 1763 instance.Resume();
1689 } 1764 }
1765
1766 public bool HasScript(UUID itemID, out bool running)
1767 {
1768 running = true;
1769
1770 IScriptInstance instance = GetInstance(itemID);
1771 if (instance == null)
1772 return false;
1773
1774 running = instance.Running;
1775 return true;
1776 }
1690 } 1777 }
1691} 1778}