diff options
Diffstat (limited to 'OpenSim/Region/ScriptEngine/XEngine/XEngine.cs')
-rw-r--r-- | OpenSim/Region/ScriptEngine/XEngine/XEngine.cs | 118 |
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; | |||
50 | using OpenSim.Region.ScriptEngine.Shared.Instance; | 50 | using OpenSim.Region.ScriptEngine.Shared.Instance; |
51 | using OpenSim.Region.ScriptEngine.Interfaces; | 51 | using OpenSim.Region.ScriptEngine.Interfaces; |
52 | 52 | ||
53 | using ScriptCompileQueue = OpenSim.Framework.LocklessQueue<object[]>; | ||
54 | using Parallel = OpenSim.Framework.Parallel; | ||
55 | |||
53 | namespace OpenSim.Region.ScriptEngine.XEngine | 56 | namespace 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 | ||