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.cs118
1 files changed, 56 insertions, 62 deletions
diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
index 7b19ce3..b0fce75 100644
--- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
+++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
@@ -50,6 +50,9 @@ using OpenSim.Region.ScriptEngine.Shared.CodeTools;
50using OpenSim.Region.ScriptEngine.Shared.Instance; 50using OpenSim.Region.ScriptEngine.Shared.Instance;
51using OpenSim.Region.ScriptEngine.Interfaces; 51using OpenSim.Region.ScriptEngine.Interfaces;
52 52
53using ScriptCompileQueue = OpenSim.Framework.LocklessQueue<object[]>;
54using Parallel = OpenSim.Framework.Parallel;
55
53namespace OpenSim.Region.ScriptEngine.XEngine 56namespace OpenSim.Region.ScriptEngine.XEngine
54{ 57{
55 public class XEngine : INonSharedRegionModule, IScriptModule, IScriptEngine 58 public class XEngine : INonSharedRegionModule, IScriptModule, IScriptEngine
@@ -73,9 +76,11 @@ namespace OpenSim.Region.ScriptEngine.XEngine
73 private bool m_InitialStartup = true; 76 private bool m_InitialStartup = true;
74 private int m_ScriptFailCount; // Number of script fails since compile queue was last empty 77 private int m_ScriptFailCount; // Number of script fails since compile queue was last empty
75 private string m_ScriptErrorMessage; 78 private string m_ScriptErrorMessage;
79 private Dictionary<string, string> m_uniqueScripts = new Dictionary<string, string>();
80 private bool m_AppDomainLoading;
76 81
77// disable warning: need to keep a reference to XEngine.EventManager 82 // disable warning: need to keep a reference to XEngine.EventManager
78// alive to avoid it being garbage collected 83 // alive to avoid it being garbage collected
79#pragma warning disable 414 84#pragma warning disable 414
80 private EventManager m_EventManager; 85 private EventManager m_EventManager;
81#pragma warning restore 414 86#pragma warning restore 414
@@ -114,7 +119,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
114 private Dictionary<UUID, List<UUID> > m_DomainScripts = 119 private Dictionary<UUID, List<UUID> > m_DomainScripts =
115 new Dictionary<UUID, List<UUID> >(); 120 new Dictionary<UUID, List<UUID> >();
116 121
117 private Queue m_CompileQueue = new Queue(100); 122 private ScriptCompileQueue m_CompileQueue = new ScriptCompileQueue();
118 IWorkItemResult m_CurrentCompile = null; 123 IWorkItemResult m_CurrentCompile = null;
119 124
120 public string ScriptEngineName 125 public string ScriptEngineName
@@ -201,6 +206,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
201 m_MaxScriptQueue = m_ScriptConfig.GetInt("MaxScriptEventQueue",300); 206 m_MaxScriptQueue = m_ScriptConfig.GetInt("MaxScriptEventQueue",300);
202 m_StackSize = m_ScriptConfig.GetInt("ThreadStackSize", 262144); 207 m_StackSize = m_ScriptConfig.GetInt("ThreadStackSize", 262144);
203 m_SleepTime = m_ScriptConfig.GetInt("MaintenanceInterval", 10) * 1000; 208 m_SleepTime = m_ScriptConfig.GetInt("MaintenanceInterval", 10) * 1000;
209 m_AppDomainLoading = m_ScriptConfig.GetBoolean("AppDomainLoading", true);
204 210
205 m_EventLimit = m_ScriptConfig.GetInt("EventLimit", 30); 211 m_EventLimit = m_ScriptConfig.GetInt("EventLimit", 30);
206 m_KillTimedOutScripts = m_ScriptConfig.GetBoolean("KillTimedOutScripts", false); 212 m_KillTimedOutScripts = m_ScriptConfig.GetBoolean("KillTimedOutScripts", false);
@@ -470,6 +476,12 @@ namespace OpenSim.Region.ScriptEngine.XEngine
470 if (engine != ScriptEngineName) 476 if (engine != ScriptEngineName)
471 return; 477 return;
472 478
479 // If we've seen this exact script text before, use that reference instead
480 if (m_uniqueScripts.ContainsKey(script))
481 script = m_uniqueScripts[script];
482 else
483 m_uniqueScripts[script] = script;
484
473 Object[] parms = new Object[]{localID, itemID, script, startParam, postOnRez, (StateSource)stateSource}; 485 Object[] parms = new Object[]{localID, itemID, script, startParam, postOnRez, (StateSource)stateSource};
474 486
475 if (stateSource == (int)StateSource.ScriptedRez) 487 if (stateSource == (int)StateSource.ScriptedRez)
@@ -478,16 +490,11 @@ namespace OpenSim.Region.ScriptEngine.XEngine
478 } 490 }
479 else 491 else
480 { 492 {
481 lock (m_CompileQueue) 493 m_CompileQueue.Enqueue(parms);
482 {
483 m_CompileQueue.Enqueue(parms);
484 494
485 if (m_CurrentCompile == null) 495 if (m_CurrentCompile == null)
486 { 496 {
487 m_CurrentCompile = m_ThreadPool.QueueWorkItem( 497 m_CurrentCompile = m_ThreadPool.QueueWorkItem(DoOnRezScriptQueue, null);
488 new WorkItemCallback(this.DoOnRezScriptQueue),
489 new Object[0]);
490 }
491 } 498 }
492 } 499 }
493 } 500 }
@@ -498,50 +505,35 @@ namespace OpenSim.Region.ScriptEngine.XEngine
498 { 505 {
499 m_InitialStartup = false; 506 m_InitialStartup = false;
500 System.Threading.Thread.Sleep(15000); 507 System.Threading.Thread.Sleep(15000);
501 lock (m_CompileQueue) 508
509 if (m_CompileQueue.Count == 0)
502 { 510 {
503 if (m_CompileQueue.Count==0) 511 // No scripts on region, so won't get triggered later
504 // No scripts on region, so won't get triggered later 512 // by the queue becoming empty so we trigger it here
505 // by the queue becoming empty so we trigger it here 513 m_Scene.EventManager.TriggerEmptyScriptCompileQueue(0, String.Empty);
506 m_Scene.EventManager.TriggerEmptyScriptCompileQueue(0, String.Empty);
507 } 514 }
508 } 515 }
509 516
510 Object o; 517 List<object[]> compiles = new List<object[]>();
511 lock (m_CompileQueue) 518 object[] o;
519 while (m_CompileQueue.Dequeue(out o))
512 { 520 {
513 o = m_CompileQueue.Dequeue(); 521 compiles.Add(o);
514 if (o == null)
515 {
516 m_CurrentCompile = null;
517 return null;
518 }
519 } 522 }
520 523
521 DoOnRezScript(o); 524 Parallel.For(0, compiles.Count, delegate(int i) { DoOnRezScript(compiles[i]); });
525
526 m_CurrentCompile = null;
527 m_Scene.EventManager.TriggerEmptyScriptCompileQueue(m_ScriptFailCount,
528 m_ScriptErrorMessage);
529 m_ScriptFailCount = 0;
522 530
523 lock (m_CompileQueue)
524 {
525 if (m_CompileQueue.Count > 0)
526 {
527 m_CurrentCompile = m_ThreadPool.QueueWorkItem(
528 new WorkItemCallback(this.DoOnRezScriptQueue),
529 new Object[0]);
530 }
531 else
532 {
533 m_CurrentCompile = null;
534 m_Scene.EventManager.TriggerEmptyScriptCompileQueue(m_ScriptFailCount,
535 m_ScriptErrorMessage);
536 m_ScriptFailCount = 0;
537 }
538 }
539 return null; 531 return null;
540 } 532 }
541 533
542 private bool DoOnRezScript(object parm) 534 private bool DoOnRezScript(object[] parms)
543 { 535 {
544 Object[] p = (Object[])parm; 536 Object[] p = parms;
545 uint localID = (uint)p[0]; 537 uint localID = (uint)p[0];
546 UUID itemID = (UUID)p[1]; 538 UUID itemID = (UUID)p[1];
547 string script =(string)p[2]; 539 string script =(string)p[2];
@@ -590,14 +582,12 @@ namespace OpenSim.Region.ScriptEngine.XEngine
590 { 582 {
591 lock (m_AddingAssemblies) 583 lock (m_AddingAssemblies)
592 { 584 {
593 assembly = (string)m_Compiler.PerformScriptCompile(script, 585 m_Compiler.PerformScriptCompile(script, assetID.ToString(), item.OwnerID, out assembly, out linemap);
594 assetID.ToString(), item.OwnerID);
595 if (!m_AddingAssemblies.ContainsKey(assembly)) { 586 if (!m_AddingAssemblies.ContainsKey(assembly)) {
596 m_AddingAssemblies[assembly] = 1; 587 m_AddingAssemblies[assembly] = 1;
597 } else { 588 } else {
598 m_AddingAssemblies[assembly]++; 589 m_AddingAssemblies[assembly]++;
599 } 590 }
600 linemap = m_Compiler.LineMap();
601 } 591 }
602 592
603 string[] warnings = m_Compiler.GetWarnings(); 593 string[] warnings = m_Compiler.GetWarnings();
@@ -696,19 +686,22 @@ namespace OpenSim.Region.ScriptEngine.XEngine
696 Evidence baseEvidence = AppDomain.CurrentDomain.Evidence; 686 Evidence baseEvidence = AppDomain.CurrentDomain.Evidence;
697 Evidence evidence = new Evidence(baseEvidence); 687 Evidence evidence = new Evidence(baseEvidence);
698 688
699 AppDomain sandbox = 689 AppDomain sandbox;
700 AppDomain.CreateDomain( 690 if (m_AppDomainLoading)
701 m_Scene.RegionInfo.RegionID.ToString(), 691 sandbox = AppDomain.CreateDomain(
702 evidence, appSetup); 692 m_Scene.RegionInfo.RegionID.ToString(),
703/* 693 evidence, appSetup);
704 PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel(); 694 else
705 AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition(); 695 sandbox = AppDomain.CurrentDomain;
706 PermissionSet sandboxPermissionSet = sandboxPolicy.GetNamedPermissionSet("Internet"); 696
707 PolicyStatement sandboxPolicyStatement = new PolicyStatement(sandboxPermissionSet); 697 //PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel();
708 CodeGroup sandboxCodeGroup = new UnionCodeGroup(sandboxMembershipCondition, sandboxPolicyStatement); 698 //AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition();
709 sandboxPolicy.RootCodeGroup = sandboxCodeGroup; 699 //PermissionSet sandboxPermissionSet = sandboxPolicy.GetNamedPermissionSet("Internet");
710 sandbox.SetAppDomainPolicy(sandboxPolicy); 700 //PolicyStatement sandboxPolicyStatement = new PolicyStatement(sandboxPermissionSet);
711*/ 701 //CodeGroup sandboxCodeGroup = new UnionCodeGroup(sandboxMembershipCondition, sandboxPolicyStatement);
702 //sandboxPolicy.RootCodeGroup = sandboxCodeGroup;
703 //sandbox.SetAppDomainPolicy(sandboxPolicy);
704
712 m_AppDomains[appDomain] = sandbox; 705 m_AppDomains[appDomain] = sandbox;
713 706
714 m_AppDomains[appDomain].AssemblyResolve += 707 m_AppDomains[appDomain].AssemblyResolve +=
@@ -905,9 +898,10 @@ namespace OpenSim.Region.ScriptEngine.XEngine
905 AppDomain domain = m_AppDomains[id]; 898 AppDomain domain = m_AppDomains[id];
906 m_AppDomains.Remove(id); 899 m_AppDomains.Remove(id);
907 900
908 AppDomain.Unload(domain); 901 if (domain != AppDomain.CurrentDomain)
902 AppDomain.Unload(domain);
909 domain = null; 903 domain = null;
910// m_log.DebugFormat("[XEngine] Unloaded app domain {0}", id.ToString()); 904 // m_log.DebugFormat("[XEngine] Unloaded app domain {0}", id.ToString());
911 } 905 }
912 } 906 }
913 907