Added (theoretical) AppDomain cleanup code.
parent
240712ca9f
commit
1ae73931da
|
@ -10,7 +10,10 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine
|
|||
{
|
||||
public class AppDomainManager
|
||||
{
|
||||
private int MaxScriptsPerAppDomain = 10;
|
||||
private int MaxScriptsPerAppDomain = 1;
|
||||
/// <summary>
|
||||
/// List of all AppDomains
|
||||
/// </summary>
|
||||
private List<AppDomainStructure> AppDomains = new List<AppDomainStructure>();
|
||||
private struct AppDomainStructure
|
||||
{
|
||||
|
@ -27,8 +30,12 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine
|
|||
/// </summary>
|
||||
public int ScriptsWaitingUnload;
|
||||
}
|
||||
/// <summary>
|
||||
/// Current AppDomain
|
||||
/// </summary>
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Find a free AppDomain, creating one if necessary
|
||||
/// </summary>
|
||||
/// <returns>Free AppDomain</returns>
|
||||
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;
|
||||
/// <summary>
|
||||
/// Create and prepare a new AppDomain for scripts
|
||||
/// </summary>
|
||||
/// <returns>The new AppDomain</returns>
|
||||
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
|
|||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Unload appdomains that are full and have only dead scripts
|
||||
/// </summary>
|
||||
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
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Increase "dead script" counter for an AppDomain
|
||||
/// </summary>
|
||||
/// <param name="ad"></param>
|
||||
[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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue