From 1ae73931da62409a36b9c448ac35537dfe3745eb Mon Sep 17 00:00:00 2001
From: Tedd Hansen
Date: Sat, 18 Aug 2007 22:33:06 +0000
Subject: Added (theoretical) AppDomain cleanup code.
---
.../ScriptEngine/DotNetEngine/AppDomainManager.cs | 106 +++++++++++++++++----
1 file changed, 89 insertions(+), 17 deletions(-)
(limited to 'OpenSim')
diff --git a/OpenSim/Region/ScriptEngine/DotNetEngine/AppDomainManager.cs b/OpenSim/Region/ScriptEngine/DotNetEngine/AppDomainManager.cs
index 7941ea2..f80ebac 100644
--- a/OpenSim/Region/ScriptEngine/DotNetEngine/AppDomainManager.cs
+++ b/OpenSim/Region/ScriptEngine/DotNetEngine/AppDomainManager.cs
@@ -10,7 +10,10 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine
{
public class AppDomainManager
{
- private int MaxScriptsPerAppDomain = 10;
+ private int MaxScriptsPerAppDomain = 1;
+ ///
+ /// List of all AppDomains
+ ///
private List AppDomains = new List();
private struct AppDomainStructure
{
@@ -27,8 +30,12 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine
///
public int ScriptsWaitingUnload;
}
+ ///
+ /// Current AppDomain
+ ///
private AppDomainStructure CurrentAD;
- private object GetLock = new object();
+ private object GetLock = new object(); // Mutex
+ private object FreeLock = new object(); // Mutex
private ScriptEngine m_scriptEngine;
public AppDomainManager(ScriptEngine scriptEngine)
@@ -36,17 +43,28 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine
m_scriptEngine = scriptEngine;
}
+ ///
+ /// Find a free AppDomain, creating one if necessary
+ ///
+ /// Free AppDomain
internal AppDomain GetFreeAppDomain()
{
+ FreeAppDomains();
lock(GetLock) {
- // No current or current full?
- if (CurrentAD.CurrentAppDomain == null || CurrentAD.ScriptsLoaded >= MaxScriptsPerAppDomain)
+ // Current full?
+ if (CurrentAD.ScriptsLoaded >= MaxScriptsPerAppDomain)
+ {
+ AppDomains.Add(CurrentAD);
+ CurrentAD = new AppDomainStructure();
+ }
+ // No current
+ if (CurrentAD.CurrentAppDomain == null)
{
// Create a new current AppDomain
CurrentAD = new AppDomainStructure();
CurrentAD.ScriptsWaitingUnload = 0; // to avoid compile warning for not in use
CurrentAD.CurrentAppDomain = PrepareNewAppDomain();
- AppDomains.Add(CurrentAD);
+
}
@@ -58,6 +76,10 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine
}
private int AppDomainNameCount;
+ ///
+ /// Create and prepare a new AppDomain for scripts
+ ///
+ /// The new AppDomain
private AppDomain PrepareNewAppDomain()
{
// Create and prepare a new AppDomain
@@ -80,20 +102,20 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine
AppDomain.CurrentDomain.SetupInformation.ConfigurationFile;
AppDomain AD = AppDomain.CreateDomain("ScriptAppDomain_" + AppDomainNameCount, null, ads);
- foreach (Assembly a in AppDomain.CurrentDomain.GetAssemblies())
- {
- //Console.WriteLine("Loading: " + a.GetName(true));
- try
- {
- //AD.Load(a.GetName(true));
+ //foreach (Assembly a in AppDomain.CurrentDomain.GetAssemblies())
+ //{
+ // //Console.WriteLine("Loading: " + a.GetName(true));
+ // try
+ // {
+ // //AD.Load(a.GetName(true));
- }
- catch (Exception e)
- {
- //Console.WriteLine("FAILED load");
- }
+ // }
+ // catch (Exception e)
+ // {
+ // //Console.WriteLine("FAILED load");
+ // }
- }
+ //}
//Console.WriteLine("Assembly file: " + this.GetType().Assembly.CodeBase);
//Console.WriteLine("Assembly name: " + this.GetType().ToString());
@@ -106,5 +128,55 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine
}
+ ///
+ /// Unload appdomains that are full and have only dead scripts
+ ///
+ private void FreeAppDomains()
+ {
+ lock (FreeLock)
+ {
+ foreach (AppDomainStructure ads in new System.Collections.ArrayList(AppDomains))
+ {
+ if (ads.CurrentAppDomain != CurrentAD.CurrentAppDomain)
+ {
+ // Not current AppDomain
+ if (ads.ScriptsLoaded == ads.ScriptsWaitingUnload)
+ {
+ AppDomains.Remove(ads);
+ AppDomain.Unload(ads.CurrentAppDomain);
+ }
+ }
+ } // foreach
+ } // lock
+ }
+
+ ///
+ /// Increase "dead script" counter for an AppDomain
+ ///
+ ///
+ [Obsolete("Needs optimizing!!!")]
+ public void StopScriptInAppDomain(AppDomain ad)
+ {
+ lock (FreeLock)
+ {
+ if (CurrentAD.CurrentAppDomain == ad)
+ {
+ CurrentAD.ScriptsWaitingUnload++;
+ return;
+ }
+
+ foreach (AppDomainStructure ads in new System.Collections.ArrayList(AppDomains))
+ {
+ if (ads.CurrentAppDomain == ad)
+ {
+ AppDomainStructure ads2 = ads;
+ ads2.ScriptsWaitingUnload++;
+ AppDomains.Remove(ads);
+ AppDomains.Add(ads2);
+ return;
+ }
+ } // foreach
+ } // lock
+ }
}
}
--
cgit v1.1