diff --git a/OpenSim/Region/ScriptEngine/DotNetEngine/AppDomainManager.cs b/OpenSim/Region/ScriptEngine/DotNetEngine/AppDomainManager.cs index 5a77d3929d..da461e3bc3 100644 --- a/OpenSim/Region/ScriptEngine/DotNetEngine/AppDomainManager.cs +++ b/OpenSim/Region/ScriptEngine/DotNetEngine/AppDomainManager.cs @@ -37,46 +37,37 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine public class AppDomainManager : iScriptEngineFunctionModule { // - // This class does AppDomain handling and loading/unloading of scripts in it. - // It is instanced in "ScriptEngine" and controlled from "ScriptManager" + // This class does AppDomain handling and loading/unloading of + // scripts in it. It is instanced in "ScriptEngine" and controlled + // from "ScriptManager" // // 1. Create a new AppDomain if old one is full (or doesn't exist) // 2. Load scripts into AppDomain - // 3. Unload scripts from AppDomain (stopping them and marking them as inactive) + // 3. Unload scripts from AppDomain (stopping them and marking + // them as inactive) // 4. Unload AppDomain completely when all scripts in it has stopped // private int maxScriptsPerAppDomain = 1; - /// - /// Internal list of all AppDomains - /// - private List appDomains = new List(); + // Internal list of all AppDomains + private List appDomains = + new List(); - /// - /// Structure to keep track of data around AppDomain - /// + // Structure to keep track of data around AppDomain private class AppDomainStructure { - /// - /// The AppDomain itself - /// + // The AppDomain itself public AppDomain CurrentAppDomain; - /// - /// Number of scripts loaded into AppDomain - /// + // Number of scripts loaded into AppDomain public int ScriptsLoaded; - /// - /// Number of dead scripts - /// + // Number of dead scripts public int ScriptsWaitingUnload; } - /// - /// Current AppDomain - /// + // Current AppDomain private AppDomainStructure currentAD; private object getLock = new object(); // Mutex @@ -92,20 +83,18 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine public void ReadConfig() { - maxScriptsPerAppDomain = m_scriptEngine.ScriptConfigSource.GetInt("ScriptsPerAppDomain", 1); + maxScriptsPerAppDomain = m_scriptEngine.ScriptConfigSource.GetInt( + "ScriptsPerAppDomain", 1); } - /// - /// Find a free AppDomain, creating one if necessary - /// - /// Free AppDomain + // Find a free AppDomain, creating one if necessary private AppDomainStructure GetFreeAppDomain() { - // Console.WriteLine("Finding free AppDomain"); lock (getLock) { // Current full? - if (currentAD != null && currentAD.ScriptsLoaded >= maxScriptsPerAppDomain) + if (currentAD != null && + currentAD.ScriptsLoaded >= maxScriptsPerAppDomain) { // Add it to AppDomains list and empty current appDomains.Add(currentAD); @@ -119,21 +108,18 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine currentAD.CurrentAppDomain = PrepareNewAppDomain(); } - // Console.WriteLine("Scripts loaded in this Appdomain: " + currentAD.ScriptsLoaded); return currentAD; } } private int AppDomainNameCount; - /// - /// Create and prepare a new AppDomain for scripts - /// - /// The new AppDomain + // Create and prepare a new AppDomain for scripts private AppDomain PrepareNewAppDomain() { // Create and prepare a new AppDomain AppDomainNameCount++; + // TODO: Currently security match current appdomain // Construct and initialize settings for a second AppDomain. @@ -143,21 +129,24 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine ads.DisallowCodeDownload = true; ads.LoaderOptimization = LoaderOptimization.MultiDomainHost; ads.ShadowCopyFiles = "false"; // Disable shadowing - ads.ConfigurationFile = AppDomain.CurrentDomain.SetupInformation.ConfigurationFile; + ads.ConfigurationFile = + AppDomain.CurrentDomain.SetupInformation.ConfigurationFile; - AppDomain AD = AppDomain.CreateDomain("ScriptAppDomain_" + AppDomainNameCount, null, ads); - m_scriptEngine.Log.Info("[" + m_scriptEngine.ScriptEngineName + "]: AppDomain Loading: " + - AssemblyName.GetAssemblyName("OpenSim.Region.ScriptEngine.Shared.dll").ToString()); - AD.Load(AssemblyName.GetAssemblyName("OpenSim.Region.ScriptEngine.Shared.dll")); + AppDomain AD = AppDomain.CreateDomain("ScriptAppDomain_" + + AppDomainNameCount, null, ads); + m_scriptEngine.Log.Info("[" + m_scriptEngine.ScriptEngineName + + "]: AppDomain Loading: " + + AssemblyName.GetAssemblyName( + "OpenSim.Region.ScriptEngine.Shared.dll").ToString()); + AD.Load(AssemblyName.GetAssemblyName( + "OpenSim.Region.ScriptEngine.Shared.dll")); // Return the new AppDomain return AD; } - /// - /// Unload appdomains that are full and have only dead scripts - /// + // Unload appdomains that are full and have only dead scripts private void UnloadAppDomains() { lock (freeLock) @@ -174,15 +163,9 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine { // Remove from internal list appDomains.Remove(ads); -//#if DEBUG - //Console.WriteLine("Found empty AppDomain, unloading"); - //long m = GC.GetTotalMemory(true); // This force a garbage collect that freezes some windows plateforms -//#endif + // Unload AppDomain.Unload(ads.CurrentAppDomain); -//#if DEBUG - //m_scriptEngine.Log.Info("[" + m_scriptEngine.ScriptEngineName + "]: AppDomain unload freed " + (m - GC.GetTotalMemory(true)) + " bytes of memory"); -//#endif } } } @@ -194,13 +177,10 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine // Find next available AppDomain to put it in AppDomainStructure FreeAppDomain = GetFreeAppDomain(); -#if DEBUG - m_scriptEngine.Log.Info("[" + m_scriptEngine.ScriptEngineName + "]: Loading into AppDomain: " + FileName); -#endif - IScript mbrt = - (IScript) - FreeAppDomain.CurrentAppDomain.CreateInstanceFromAndUnwrap(FileName, "SecondLife.Script"); - //Console.WriteLine("ScriptEngine AppDomainManager: is proxy={0}", RemotingServices.IsTransparentProxy(mbrt)); + IScript mbrt = (IScript) + FreeAppDomain.CurrentAppDomain.CreateInstanceFromAndUnwrap( + FileName, "SecondLife.Script"); + FreeAppDomain.ScriptsLoaded++; ad = FreeAppDomain.CurrentAppDomain; @@ -208,18 +188,11 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine } - /// - /// Increase "dead script" counter for an AppDomain - /// - /// - //[Obsolete("Needs fixing, needs a real purpose in life!!!")] + // Increase "dead script" counter for an AppDomain public void StopScript(AppDomain ad) { lock (freeLock) { -#if DEBUG - m_scriptEngine.Log.Info("[" + m_scriptEngine.ScriptEngineName + "]: Stopping script in AppDomain"); -#endif // Check if it is current AppDomain if (currentAD.CurrentAppDomain == ad) { @@ -243,9 +216,8 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine UnloadAppDomains(); // Outsite lock, has its own GetLock } - /// - /// If set to true then threads and stuff should try to make a graceful exit - /// + // If set to true then threads and stuff should try + // to make a graceful exit public bool PleaseShutdown { get { return _PleaseShutdown; } diff --git a/OpenSim/Region/ScriptEngine/DotNetEngine/Common.cs b/OpenSim/Region/ScriptEngine/DotNetEngine/Common.cs index 3d9e19b3e4..56b4c8ed21 100644 --- a/OpenSim/Region/ScriptEngine/DotNetEngine/Common.cs +++ b/OpenSim/Region/ScriptEngine/DotNetEngine/Common.cs @@ -29,28 +29,18 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine { public static class Common { - public static bool debug = true; public static ScriptEngine mySE; // This class just contains some static log stuff used for debugging. - //public delegate void SendToDebugEventDelegate(string message); - //public delegate void SendToLogEventDelegate(string message); - //static public event SendToDebugEventDelegate SendToDebugEvent; - //static public event SendToLogEventDelegate SendToLogEvent; - public static void SendToDebug(string message) { - //if (Debug == true) mySE.Log.Info("[" + mySE.ScriptEngineName + "]: Debug: " + message); - //SendToDebugEvent("\r\n" + DateTime.Now.ToString("[HH:mm:ss] ") + message); } public static void SendToLog(string message) { - //if (Debug == true) mySE.Log.Info("[" + mySE.ScriptEngineName + "]: LOG: " + message); - //SendToLogEvent("\r\n" + DateTime.Now.ToString("[HH:mm:ss] ") + message); } } } diff --git a/OpenSim/Region/ScriptEngine/DotNetEngine/ScriptEngine.cs b/OpenSim/Region/ScriptEngine/DotNetEngine/ScriptEngine.cs index 71db4eede8..ee64c41375 100644 --- a/OpenSim/Region/ScriptEngine/DotNetEngine/ScriptEngine.cs +++ b/OpenSim/Region/ScriptEngine/DotNetEngine/ScriptEngine.cs @@ -44,19 +44,35 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine [Serializable] public class ScriptEngine : IRegionModule, IEventReceiver, IScriptModule { - private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + private static readonly ILog m_log = + LogManager.GetLogger( + MethodBase.GetCurrentMethod().DeclaringType); + + public static List ScriptEngines = + new List(); - public static List ScriptEngines = new List(); private Scene m_Scene; public Scene World { get { return m_Scene; } } - public EventManager m_EventManager; // Handles and queues incoming events from OpenSim - public EventQueueManager m_EventQueueManager; // Executes events, handles script threads - public ScriptManager m_ScriptManager; // Load, unload and execute scripts - public AppDomainManager m_AppDomainManager; // Handles loading/unloading of scripts into AppDomains - public static MaintenanceThread m_MaintenanceThread; // Thread that does different kinds of maintenance, for example refreshing config and killing scripts that has been running too long + + // Handles and queues incoming events from OpenSim + public EventManager m_EventManager; + + // Executes events, handles script threads + public EventQueueManager m_EventQueueManager; + + // Load, unload and execute scripts + public ScriptManager m_ScriptManager; + + // Handles loading/unloading of scripts into AppDomains + public AppDomainManager m_AppDomainManager; + + // Thread that does different kinds of maintenance, + // for example refreshing config and killing scripts + // that has been running too long + public static MaintenanceThread m_MaintenanceThread; public IConfigSource ConfigSource; public IConfig ScriptConfigSource; @@ -67,13 +83,13 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine get { return ScriptConfigSource; } } - /// - /// How many seconds between re-reading config-file. 0 = never. ScriptEngine will try to adjust to new config changes. - /// + // How many seconds between re-reading config-file. + // 0 = never. ScriptEngine will try to adjust to new config changes. public int RefreshConfigFileSeconds { get { return (int)(RefreshConfigFilens / 10000000); } set { RefreshConfigFilens = value * 10000000; } } + public long RefreshConfigFilens; public string ScriptEngineName @@ -88,10 +104,14 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine public ScriptEngine() { - Common.mySE = this; // For logging, just need any instance, doesn't matter + // For logging, just need any instance, doesn't matter + Common.mySE = this; + lock (ScriptEngines) { - ScriptEngines.Add(this); // Keep a list of ScriptEngines for shared threads to process all instances + // Keep a list of ScriptEngines for shared threads + // to process all instances + ScriptEngines.Add(this); } } @@ -105,17 +125,17 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine // Make sure we have config if (ConfigSource.Configs[ScriptEngineName] == null) ConfigSource.AddConfig(ScriptEngineName); + ScriptConfigSource = ConfigSource.Configs[ScriptEngineName]; m_enabled = ScriptConfigSource.GetBoolean("Enabled", true); if (!m_enabled) return; - //m_log.Info("[" + ScriptEngineName + "]: InitializeEngine"); - // Create all objects we'll be using m_EventQueueManager = new EventQueueManager(this); m_EventManager = new EventManager(this, true); + // We need to start it m_ScriptManager = new ScriptManager(this); m_ScriptManager.Setup(); @@ -123,7 +143,9 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine if (m_MaintenanceThread == null) m_MaintenanceThread = new MaintenanceThread(); - m_log.Info("[" + ScriptEngineName + "]: Reading configuration from config section \"" + ScriptEngineName + "\""); + m_log.Info("[" + ScriptEngineName + "]: Reading configuration "+ + "from config section \"" + ScriptEngineName + "\""); + ReadConfig(); m_Scene.StackModuleInterface(this); @@ -155,15 +177,8 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine public void ReadConfig() { -#if DEBUG - //m_log.Debug("[" + ScriptEngineName + "]: Refreshing configuration for all modules"); -#endif RefreshConfigFileSeconds = ScriptConfigSource.GetInt("RefreshConfig", 30); - - // Create a new object (probably not necessary?) -// ScriptConfigSource = ConfigSource.Configs[ScriptEngineName]; - if (m_EventQueueManager != null) m_EventQueueManager.ReadConfig(); if (m_EventManager != null) m_EventManager.ReadConfig(); if (m_ScriptManager != null) m_ScriptManager.ReadConfig(); @@ -189,13 +204,15 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine public bool PostObjectEvent(uint localID, EventParams p) { - return m_EventQueueManager.AddToObjectQueue(localID, p.EventName, p.DetectParams, p.Params); + return m_EventQueueManager.AddToObjectQueue(localID, p.EventName, + p.DetectParams, p.Params); } public bool PostScriptEvent(UUID itemID, EventParams p) { uint localID = m_ScriptManager.GetLocalID(itemID); - return m_EventQueueManager.AddToScriptQueue(localID, itemID, p.EventName, p.DetectParams, p.Params); + return m_EventQueueManager.AddToScriptQueue(localID, itemID, + p.EventName, p.DetectParams, p.Params); } public DetectParams GetDetectParams(UUID itemID, int number) @@ -341,7 +358,8 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine id.Running = false; } - public void OnGetScriptRunning(IClientAPI controllingClient, UUID objectID, UUID itemID) + public void OnGetScriptRunning(IClientAPI controllingClient, + UUID objectID, UUID itemID) { uint localID = m_ScriptManager.GetLocalID(itemID); if (localID == 0)