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.cs361
1 files changed, 224 insertions, 137 deletions
diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
index bb08d90..696c216 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"; }
@@ -365,47 +433,45 @@ namespace OpenSim.Region.ScriptEngine.XEngine
365 { 433 {
366 if (!m_Enabled) 434 if (!m_Enabled)
367 return; 435 return;
368 436 lockScriptsForRead(true);
369 lock (m_Scripts) 437 foreach (IScriptInstance instance in m_Scripts.Values)
370 { 438 {
371 m_log.InfoFormat( 439 // Force a final state save
372 "[XEngine]: Shutting down {0} scripts in {1}", m_Scripts.Count, m_Scene.RegionInfo.RegionName); 440 //
373 441 if (m_Assemblies.ContainsKey(instance.AssetID))
374 foreach (IScriptInstance instance in m_Scripts.Values)
375 { 442 {
376 // Force a final state save 443 string assembly = m_Assemblies[instance.AssetID];
377 // 444 instance.SaveState(assembly);
378 if (m_Assemblies.ContainsKey(instance.AssetID)) 445 }
379 {
380 string assembly = m_Assemblies[instance.AssetID];
381 instance.SaveState(assembly);
382 }
383 446
384 // Clear the event queue and abort the instance thread 447 // Clear the event queue and abort the instance thread
385 // 448 //
386 instance.ClearQueue(); 449 instance.ClearQueue();
387 instance.Stop(0); 450 instance.Stop(0);
388 451
389 // Release events, timer, etc 452 // Release events, timer, etc
390 // 453 //
391 instance.DestroyScriptInstance(); 454 instance.DestroyScriptInstance();
392 455
393 // Unload scripts and app domains 456 // Unload scripts and app domains
394 // Must be done explicitly because they have infinite 457 // Must be done explicitly because they have infinite
395 // lifetime 458 // lifetime
396 // 459 //
397 m_DomainScripts[instance.AppDomain].Remove(instance.ItemID); 460 m_DomainScripts[instance.AppDomain].Remove(instance.ItemID);
398 if (m_DomainScripts[instance.AppDomain].Count == 0) 461 if (m_DomainScripts[instance.AppDomain].Count == 0)
399 { 462 {
400 m_DomainScripts.Remove(instance.AppDomain); 463 m_DomainScripts.Remove(instance.AppDomain);
401 UnloadAppDomain(instance.AppDomain); 464 UnloadAppDomain(instance.AppDomain);
402 }
403 } 465 }
404 m_Scripts.Clear();
405 m_PrimObjects.Clear();
406 m_Assemblies.Clear();
407 m_DomainScripts.Clear();
408 } 466 }
467 lockScriptsForRead(false);
468 lockScriptsForWrite(true);
469 m_Scripts.Clear();
470 lockScriptsForWrite(false);
471 m_PrimObjects.Clear();
472 m_Assemblies.Clear();
473 m_DomainScripts.Clear();
474
409 lock (m_ScriptEngines) 475 lock (m_ScriptEngines)
410 { 476 {
411 m_ScriptEngines.Remove(this); 477 m_ScriptEngines.Remove(this);
@@ -470,22 +536,20 @@ namespace OpenSim.Region.ScriptEngine.XEngine
470 536
471 List<IScriptInstance> instances = new List<IScriptInstance>(); 537 List<IScriptInstance> instances = new List<IScriptInstance>();
472 538
473 lock (m_Scripts) 539 lockScriptsForRead(true);
474 { 540 foreach (IScriptInstance instance in m_Scripts.Values)
475 foreach (IScriptInstance instance in m_Scripts.Values)
476 instances.Add(instance); 541 instances.Add(instance);
477 } 542 lockScriptsForRead(false);
478 543
479 foreach (IScriptInstance i in instances) 544 foreach (IScriptInstance i in instances)
480 { 545 {
481 string assembly = String.Empty; 546 string assembly = String.Empty;
482 547
483 lock (m_Scripts) 548
484 {
485 if (!m_Assemblies.ContainsKey(i.AssetID)) 549 if (!m_Assemblies.ContainsKey(i.AssetID))
486 continue; 550 continue;
487 assembly = m_Assemblies[i.AssetID]; 551 assembly = m_Assemblies[i.AssetID];
488 } 552
489 553
490 i.SaveState(assembly); 554 i.SaveState(assembly);
491 } 555 }
@@ -819,92 +883,95 @@ namespace OpenSim.Region.ScriptEngine.XEngine
819 } 883 }
820 884
821 ScriptInstance instance = null; 885 ScriptInstance instance = null;
822 lock (m_Scripts) 886 // Create the object record
887 lockScriptsForRead(true);
888 if ((!m_Scripts.ContainsKey(itemID)) ||
889 (m_Scripts[itemID].AssetID != assetID))
823 { 890 {
824 // Create the object record 891 lockScriptsForRead(false);
825 892
826 if ((!m_Scripts.ContainsKey(itemID)) || 893 UUID appDomain = assetID;
827 (m_Scripts[itemID].AssetID != assetID))
828 {
829 UUID appDomain = assetID;
830 894
831 if (part.ParentGroup.IsAttachment) 895 if (part.ParentGroup.IsAttachment)
832 appDomain = part.ParentGroup.RootPart.UUID; 896 appDomain = part.ParentGroup.RootPart.UUID;
833 897
834 if (!m_AppDomains.ContainsKey(appDomain)) 898 if (!m_AppDomains.ContainsKey(appDomain))
899 {
900 try
835 { 901 {
836 try 902 AppDomainSetup appSetup = new AppDomainSetup();
837 { 903 appSetup.PrivateBinPath = Path.Combine(
838 AppDomainSetup appSetup = new AppDomainSetup(); 904 m_ScriptEnginesPath,
839 appSetup.PrivateBinPath = Path.Combine( 905 m_Scene.RegionInfo.RegionID.ToString());
840 m_ScriptEnginesPath, 906
841 m_Scene.RegionInfo.RegionID.ToString()); 907 Evidence baseEvidence = AppDomain.CurrentDomain.Evidence;
842 908 Evidence evidence = new Evidence(baseEvidence);
843 Evidence baseEvidence = AppDomain.CurrentDomain.Evidence; 909
844 Evidence evidence = new Evidence(baseEvidence); 910 AppDomain sandbox;
845 911 if (m_AppDomainLoading)
846 AppDomain sandbox; 912 sandbox = AppDomain.CreateDomain(
847 if (m_AppDomainLoading) 913 m_Scene.RegionInfo.RegionID.ToString(),
848 sandbox = AppDomain.CreateDomain( 914 evidence, appSetup);
849 m_Scene.RegionInfo.RegionID.ToString(), 915 else
850 evidence, appSetup); 916 sandbox = AppDomain.CurrentDomain;
851 else 917
852 sandbox = AppDomain.CurrentDomain; 918 //PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel();
853 919 //AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition();
854 //PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel(); 920 //PermissionSet sandboxPermissionSet = sandboxPolicy.GetNamedPermissionSet("Internet");
855 //AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition(); 921 //PolicyStatement sandboxPolicyStatement = new PolicyStatement(sandboxPermissionSet);
856 //PermissionSet sandboxPermissionSet = sandboxPolicy.GetNamedPermissionSet("Internet"); 922 //CodeGroup sandboxCodeGroup = new UnionCodeGroup(sandboxMembershipCondition, sandboxPolicyStatement);
857 //PolicyStatement sandboxPolicyStatement = new PolicyStatement(sandboxPermissionSet); 923 //sandboxPolicy.RootCodeGroup = sandboxCodeGroup;
858 //CodeGroup sandboxCodeGroup = new UnionCodeGroup(sandboxMembershipCondition, sandboxPolicyStatement); 924 //sandbox.SetAppDomainPolicy(sandboxPolicy);
859 //sandboxPolicy.RootCodeGroup = sandboxCodeGroup; 925
860 //sandbox.SetAppDomainPolicy(sandboxPolicy); 926 m_AppDomains[appDomain] = sandbox;
861 927
862 m_AppDomains[appDomain] = sandbox; 928 m_AppDomains[appDomain].AssemblyResolve +=
863 929 new ResolveEventHandler(
864 m_AppDomains[appDomain].AssemblyResolve += 930 AssemblyResolver.OnAssemblyResolve);
865 new ResolveEventHandler( 931 m_DomainScripts[appDomain] = new List<UUID>();
866 AssemblyResolver.OnAssemblyResolve); 932 }
867 m_DomainScripts[appDomain] = new List<UUID>(); 933 catch (Exception e)
868 } 934 {
869 catch (Exception e) 935 m_log.ErrorFormat("[XEngine] Exception creating app domain:\n {0}", e.ToString());
936 m_ScriptErrorMessage += "Exception creating app domain:\n";
937 m_ScriptFailCount++;
938 lock (m_AddingAssemblies)
870 { 939 {
871 m_log.ErrorFormat("[XEngine] Exception creating app domain:\n {0}", e.ToString()); 940 m_AddingAssemblies[assembly]--;
872 m_ScriptErrorMessage += "Exception creating app domain:\n";
873 m_ScriptFailCount++;
874 lock (m_AddingAssemblies)
875 {
876 m_AddingAssemblies[assembly]--;
877 }
878 return false;
879 } 941 }
942 return false;
880 } 943 }
881 m_DomainScripts[appDomain].Add(itemID); 944 }
882 945 m_DomainScripts[appDomain].Add(itemID);
883 instance = new ScriptInstance(this, part, 946
884 itemID, assetID, assembly, 947 instance = new ScriptInstance(this, part,
885 m_AppDomains[appDomain], 948 itemID, assetID, assembly,
886 part.ParentGroup.RootPart.Name, 949 m_AppDomains[appDomain],
887 item.Name, startParam, postOnRez, 950 part.ParentGroup.RootPart.Name,
888 stateSource, m_MaxScriptQueue); 951 item.Name, startParam, postOnRez,
889 952 stateSource, m_MaxScriptQueue);
890 m_log.DebugFormat( 953
891 "[XEngine] Loaded script {0}.{1}, item UUID {2}, prim UUID {3} @ {4}.{5}", 954 m_log.DebugFormat(
892 part.ParentGroup.RootPart.Name, item.Name, itemID, part.UUID, 955 "[XEngine] Loaded script {0}.{1}, script UUID {2}, prim UUID {3} @ {4}.{5}",
956 part.ParentGroup.RootPart.Name, item.Name, assetID, part.UUID,
893 part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName); 957 part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName);
894 958
895 if (presence != null) 959 if (presence != null)
896 { 960 {
897 ShowScriptSaveResponse(item.OwnerID, 961 ShowScriptSaveResponse(item.OwnerID,
898 assetID, "Compile successful", true); 962 assetID, "Compile successful", true);
899 }
900
901 instance.AppDomain = appDomain;
902 instance.LineMap = linemap;
903
904 m_Scripts[itemID] = instance;
905 } 963 }
906 }
907 964
965 instance.AppDomain = appDomain;
966 instance.LineMap = linemap;
967 lockScriptsForWrite(true);
968 m_Scripts[itemID] = instance;
969 lockScriptsForWrite(false);
970 }
971 else
972 {
973 lockScriptsForRead(false);
974 }
908 lock (m_PrimObjects) 975 lock (m_PrimObjects)
909 { 976 {
910 if (!m_PrimObjects.ContainsKey(localID)) 977 if (!m_PrimObjects.ContainsKey(localID))
@@ -923,9 +990,9 @@ namespace OpenSim.Region.ScriptEngine.XEngine
923 m_AddingAssemblies[assembly]--; 990 m_AddingAssemblies[assembly]--;
924 } 991 }
925 992
926 if (instance != null) 993 if (instance!=null)
927 instance.Init(); 994 instance.Init();
928 995
929 return true; 996 return true;
930 } 997 }
931 998
@@ -938,20 +1005,23 @@ namespace OpenSim.Region.ScriptEngine.XEngine
938 m_CompileDict.Remove(itemID); 1005 m_CompileDict.Remove(itemID);
939 } 1006 }
940 1007
941 IScriptInstance instance = null; 1008 lockScriptsForRead(true);
942 1009 // Do we even have it?
943 lock (m_Scripts) 1010 if (!m_Scripts.ContainsKey(itemID))
944 { 1011 {
945 // Do we even have it? 1012 lockScriptsForRead(false);
946 if (!m_Scripts.ContainsKey(itemID)) 1013 return;
947 return;
948
949 instance=m_Scripts[itemID];
950 m_Scripts.Remove(itemID);
951 } 1014 }
1015
952 1016
1017 IScriptInstance instance=m_Scripts[itemID];
1018 lockScriptsForRead(false);
1019 lockScriptsForWrite(true);
1020 m_Scripts.Remove(itemID);
1021 lockScriptsForWrite(false);
953 instance.ClearQueue(); 1022 instance.ClearQueue();
954 instance.Stop(0); 1023 instance.Stop(0);
1024
955// bool objectRemoved = false; 1025// bool objectRemoved = false;
956 1026
957 lock (m_PrimObjects) 1027 lock (m_PrimObjects)
@@ -987,11 +1057,12 @@ namespace OpenSim.Region.ScriptEngine.XEngine
987 ObjectRemoved handlerObjectRemoved = OnObjectRemoved; 1057 ObjectRemoved handlerObjectRemoved = OnObjectRemoved;
988 if (handlerObjectRemoved != null) 1058 if (handlerObjectRemoved != null)
989 { 1059 {
990 SceneObjectPart part = m_Scene.GetSceneObjectPart(localID); 1060 SceneObjectPart part = m_Scene.GetSceneObjectPart(localID);
991 handlerObjectRemoved(part.UUID); 1061 handlerObjectRemoved(part.UUID);
992 } 1062 }
993 1063
994 1064 CleanAssemblies();
1065
995 ScriptRemoved handlerScriptRemoved = OnScriptRemoved; 1066 ScriptRemoved handlerScriptRemoved = OnScriptRemoved;
996 if (handlerScriptRemoved != null) 1067 if (handlerScriptRemoved != null)
997 handlerScriptRemoved(itemID); 1068 handlerScriptRemoved(itemID);
@@ -1133,7 +1204,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1133 return false; 1204 return false;
1134 1205
1135 uuids = m_PrimObjects[localID]; 1206 uuids = m_PrimObjects[localID];
1136 } 1207
1137 1208
1138 foreach (UUID itemID in uuids) 1209 foreach (UUID itemID in uuids)
1139 { 1210 {
@@ -1151,6 +1222,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1151 result = true; 1222 result = true;
1152 } 1223 }
1153 } 1224 }
1225 }
1154 1226
1155 return result; 1227 return result;
1156 } 1228 }
@@ -1250,12 +1322,14 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1250 private IScriptInstance GetInstance(UUID itemID) 1322 private IScriptInstance GetInstance(UUID itemID)
1251 { 1323 {
1252 IScriptInstance instance; 1324 IScriptInstance instance;
1253 lock (m_Scripts) 1325 lockScriptsForRead(true);
1326 if (!m_Scripts.ContainsKey(itemID))
1254 { 1327 {
1255 if (!m_Scripts.ContainsKey(itemID)) 1328 lockScriptsForRead(false);
1256 return null; 1329 return null;
1257 instance = m_Scripts[itemID];
1258 } 1330 }
1331 instance = m_Scripts[itemID];
1332 lockScriptsForRead(false);
1259 return instance; 1333 return instance;
1260 } 1334 }
1261 1335
@@ -1279,6 +1353,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1279 return false; 1353 return false;
1280 } 1354 }
1281 1355
1356 [DebuggerNonUserCode]
1282 public void ApiResetScript(UUID itemID) 1357 public void ApiResetScript(UUID itemID)
1283 { 1358 {
1284 IScriptInstance instance = GetInstance(itemID); 1359 IScriptInstance instance = GetInstance(itemID);
@@ -1330,6 +1405,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1330 return UUID.Zero; 1405 return UUID.Zero;
1331 } 1406 }
1332 1407
1408 [DebuggerNonUserCode]
1333 public void SetState(UUID itemID, string newState) 1409 public void SetState(UUID itemID, string newState)
1334 { 1410 {
1335 IScriptInstance instance = GetInstance(itemID); 1411 IScriptInstance instance = GetInstance(itemID);
@@ -1350,11 +1426,10 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1350 { 1426 {
1351 List<IScriptInstance> instances = new List<IScriptInstance>(); 1427 List<IScriptInstance> instances = new List<IScriptInstance>();
1352 1428
1353 lock (m_Scripts) 1429 lockScriptsForRead(true);
1354 { 1430 foreach (IScriptInstance instance in m_Scripts.Values)
1355 foreach (IScriptInstance instance in m_Scripts.Values)
1356 instances.Add(instance); 1431 instances.Add(instance);
1357 } 1432 lockScriptsForRead(false);
1358 1433
1359 foreach (IScriptInstance i in instances) 1434 foreach (IScriptInstance i in instances)
1360 { 1435 {
@@ -1735,5 +1810,17 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1735 1810
1736 instance.Resume(); 1811 instance.Resume();
1737 } 1812 }
1813
1814 public bool HasScript(UUID itemID, out bool running)
1815 {
1816 running = true;
1817
1818 IScriptInstance instance = GetInstance(itemID);
1819 if (instance == null)
1820 return false;
1821
1822 running = instance.Running;
1823 return true;
1824 }
1738 } 1825 }
1739} 1826}