Revert the XEngine memleak patch, it causes premature GC.

This matches behavior seen with an earlier attempt to do this, apparently
the sponsor mechanism does't work in Mono
arthursv
Melanie 2009-08-07 03:04:06 +01:00
parent ed3b21ce4e
commit f8d8366bfa
11 changed files with 68 additions and 73 deletions

View File

@ -953,12 +953,11 @@ namespace OpenSim.Region.Framework.Scenes
// this lets us keep track of nasty script events like timer, etc. // this lets us keep track of nasty script events like timer, etc.
public void TriggerTimerEvent(uint objLocalID, double Interval) public void TriggerTimerEvent(uint objLocalID, double Interval)
{ {
throw new NotImplementedException("TriggerTimerEvent was thought to be not used anymore and the registration for the event from scene object part has been commented out due to a memory leak"); handlerScriptTimerEvent = OnScriptTimerEvent;
//handlerScriptTimerEvent = OnScriptTimerEvent; if (handlerScriptTimerEvent != null)
//if (handlerScriptTimerEvent != null) {
//{ handlerScriptTimerEvent(objLocalID, Interval);
// handlerScriptTimerEvent(objLocalID, Interval); }
//}
} }
/// <summary> /// <summary>

View File

@ -3673,14 +3673,14 @@ if (m_shape != null) {
return; return;
} }
//if ((GetEffectiveObjectFlags() & (uint)PrimFlags.Scripted) != 0) if ((GetEffectiveObjectFlags() & (uint)PrimFlags.Scripted) != 0)
//{ {
// m_parentGroup.Scene.EventManager.OnScriptTimerEvent += handleTimerAccounting; m_parentGroup.Scene.EventManager.OnScriptTimerEvent += handleTimerAccounting;
//} }
//else else
//{ {
// m_parentGroup.Scene.EventManager.OnScriptTimerEvent -= handleTimerAccounting; m_parentGroup.Scene.EventManager.OnScriptTimerEvent -= handleTimerAccounting;
//} }
LocalFlags=(PrimFlags)objectflagupdate; LocalFlags=(PrimFlags)objectflagupdate;

View File

@ -41,7 +41,5 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
Dictionary<string,Object> GetVars(); Dictionary<string,Object> GetVars();
void SetVars(Dictionary<string,Object> vars); void SetVars(Dictionary<string,Object> vars);
void ResetVars(); void ResetVars();
void Close();
} }
} }

View File

@ -119,15 +119,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
AsyncCommands = new AsyncCommandManager(ScriptEngine); AsyncCommands = new AsyncCommandManager(ScriptEngine);
} }
// Object never expires
public override Object InitializeLifetimeService() public override Object InitializeLifetimeService()
{ {
ILease lease = (ILease)base.InitializeLifetimeService(); ILease lease = (ILease)base.InitializeLifetimeService();
if (lease.CurrentState == LeaseState.Initial) if (lease.CurrentState == LeaseState.Initial)
{ {
lease.InitialLeaseTime = TimeSpan.FromMinutes(1.0); lease.InitialLeaseTime = TimeSpan.Zero;
lease.RenewOnCallTime = TimeSpan.FromSeconds(10.0);
lease.SponsorshipTimeout = TimeSpan.FromMinutes(1.0);
} }
return lease; return lease;
} }

View File

@ -159,15 +159,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
} }
} }
//
// Never expire this object
//
public override Object InitializeLifetimeService() public override Object InitializeLifetimeService()
{ {
ILease lease = (ILease)base.InitializeLifetimeService(); ILease lease = (ILease)base.InitializeLifetimeService();
if (lease.CurrentState == LeaseState.Initial) if (lease.CurrentState == LeaseState.Initial)
{ {
lease.InitialLeaseTime = TimeSpan.FromMinutes(1.0); lease.InitialLeaseTime = TimeSpan.Zero;
lease.RenewOnCallTime = TimeSpan.FromSeconds(10.0);
lease.SponsorshipTimeout = TimeSpan.FromMinutes(1.0);
} }
return lease; return lease;
} }

View File

@ -35,7 +35,7 @@ using log4net;
namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
{ {
public class Executor public class Executor : MarshalByRefObject
{ {
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
@ -89,6 +89,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
initEventFlags(); initEventFlags();
} }
/// <summary>
/// Make sure our object does not timeout when in AppDomain. (Called by ILease base class)
/// </summary>
/// <returns></returns>
public override Object InitializeLifetimeService()
{
//m_log.Debug("Executor: InitializeLifetimeService()");
// return null;
ILease lease = (ILease)base.InitializeLifetimeService();
if (lease.CurrentState == LeaseState.Initial)
{
lease.InitialLeaseTime = TimeSpan.Zero; // TimeSpan.FromMinutes(1);
// lease.SponsorshipTimeout = TimeSpan.FromMinutes(2);
// lease.RenewOnCallTime = TimeSpan.FromSeconds(2);
}
return lease;
}
public scriptEvents GetStateEventFlags(string state) public scriptEvents GetStateEventFlags(string state)
{ {
//m_log.Debug("Get event flags for " + state); //m_log.Debug("Get event flags for " + state);

View File

@ -32,7 +32,7 @@ using LSLInteger = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
{ {
public partial class ScriptBaseClass public partial class ScriptBaseClass : MarshalByRefObject
{ {
// LSL CONSTANTS // LSL CONSTANTS
public static readonly LSLInteger TRUE = new LSLInteger(1); public static readonly LSLInteger TRUE = new LSLInteger(1);

View File

@ -26,7 +26,6 @@
*/ */
using System; using System;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Lifetime; using System.Runtime.Remoting.Lifetime;
using System.Security.Permissions; using System.Security.Permissions;
using System.Threading; using System.Threading;
@ -35,23 +34,26 @@ using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using OpenSim.Region.ScriptEngine.Interfaces; using OpenSim.Region.ScriptEngine.Interfaces;
using OpenSim.Region.ScriptEngine.Shared; using OpenSim.Region.ScriptEngine.Shared;
using OpenSim.Region.ScriptEngine.Shared.Api.Runtime;
namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
{ {
public partial class ScriptBaseClass : MarshalByRefObject, IScript public partial class ScriptBaseClass : MarshalByRefObject, IScript
{ {
private Dictionary<string, MethodInfo> inits = new Dictionary<string, MethodInfo>(); private Dictionary<string, MethodInfo> inits = new Dictionary<string, MethodInfo>();
private ScriptSponsor m_sponser;
// Object expires if we don't keep it alive
// sponsor will be added on object load
[SecurityPermissionAttribute(SecurityAction.Demand,
Flags = SecurityPermissionFlag.Infrastructure)]
public override Object InitializeLifetimeService() public override Object InitializeLifetimeService()
{ {
ILease lease = (ILease)base.InitializeLifetimeService(); ILease lease = (ILease)base.InitializeLifetimeService();
if (lease.CurrentState == LeaseState.Initial) if (lease.CurrentState == LeaseState.Initial)
{ {
lease.InitialLeaseTime = TimeSpan.FromMinutes(1.0); lease.InitialLeaseTime = TimeSpan.Zero;
lease.RenewOnCallTime = TimeSpan.FromSeconds(10.0); // lease.InitialLeaseTime = TimeSpan.FromMinutes(1);
lease.SponsorshipTimeout = TimeSpan.FromMinutes(1.0); // lease.SponsorshipTimeout = TimeSpan.FromMinutes(2);
// lease.RenewOnCallTime = TimeSpan.FromSeconds(2);
} }
return lease; return lease;
} }
@ -64,6 +66,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
} }
#endif #endif
public ScriptBaseClass() public ScriptBaseClass()
{ {
m_Executor = new Executor(this); m_Executor = new Executor(this);
@ -78,8 +81,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
inits[type] = mi; inits[type] = mi;
} }
} }
m_sponser = new ScriptSponsor();
} }
private Executor m_Executor = null; private Executor m_Executor = null;
@ -111,9 +112,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
if (!inits.ContainsKey(api)) if (!inits.ContainsKey(api))
return; return;
ILease lease = (ILease)RemotingServices.GetLifetimeService(data as MarshalByRefObject);
lease.Register(m_sponser);
MethodInfo mi = inits[api]; MethodInfo mi = inits[api];
Object[] args = new Object[1]; Object[] args = new Object[1];
@ -124,11 +122,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
m_InitialValues = GetVars(); m_InitialValues = GetVars();
} }
public void Close()
{
m_sponser.Close();
}
public Dictionary<string, object> GetVars() public Dictionary<string, object> GetVars()
{ {
Dictionary<string, object> vars = new Dictionary<string, object>(); Dictionary<string, object> vars = new Dictionary<string, object>();

View File

@ -32,19 +32,15 @@ using System.Text;
namespace OpenSim.Region.ScriptEngine.Shared.Api.Runtime namespace OpenSim.Region.ScriptEngine.Shared.Api.Runtime
{ {
[Serializable]
public class ScriptSponsor : MarshalByRefObject, ISponsor public class ScriptSponsor : MarshalByRefObject, ISponsor
{ {
private bool m_closed = false; // In theory: I execute, therefore I am.
// If GC collects this class then sponsorship will expire
public TimeSpan Renewal(ILease lease) public TimeSpan Renewal(ILease lease)
{ {
if (!m_closed) return TimeSpan.FromMinutes(2);
return lease.InitialLeaseTime;
return TimeSpan.FromTicks(0);
} }
public void Close() { m_closed = true; }
#if DEBUG #if DEBUG
// For tracing GC while debugging // For tracing GC while debugging
public static bool GCDummy = false; public static bool GCDummy = false;

View File

@ -96,8 +96,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
private string m_CurrentState = String.Empty; private string m_CurrentState = String.Empty;
private UUID m_RegionID = UUID.Zero; private UUID m_RegionID = UUID.Zero;
private ScriptSponsor m_ScriptSponsor; //private ISponsor m_ScriptSponsor;
private bool m_destroyed = false;
private Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>> private Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>>
m_LineMap; m_LineMap;
@ -262,9 +261,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
Path.GetFileNameWithoutExtension(assembly), Path.GetFileNameWithoutExtension(assembly),
"SecondLife.Script"); "SecondLife.Script");
m_ScriptSponsor = new ScriptSponsor(); // Add a sponsor to the script
ILease lease = (ILease)RemotingServices.GetLifetimeService(m_Script as ScriptBaseClass); // ISponsor scriptSponsor = new ScriptSponsor();
lease.Register(m_ScriptSponsor); // ILease lease = (ILease)RemotingServices.GetLifetimeService(m_Script as MarshalByRefObject);
// lease.Register(scriptSponsor);
//m_ScriptSponsor = scriptSponsor;
} }
catch (Exception) catch (Exception)
{ {
@ -447,13 +449,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
{ {
ReleaseControls(); ReleaseControls();
AsyncCommandManager.RemoveScript(m_Engine, m_LocalID, m_ItemID); AsyncCommandManager.RemoveScript(m_Engine, m_LocalID, m_ItemID);
m_Script.Close();
m_ScriptSponsor.Close();
ILease lease = (ILease)RemotingServices.GetLifetimeService(m_Script as ScriptBaseClass);
lease.Unregister(m_ScriptSponsor);
m_destroyed = true;
} }
public void RemoveState() public void RemoveState()
@ -889,8 +884,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
public void SaveState(string assembly) public void SaveState(string assembly)
{ {
// If we're currently in an event, just tell it to save upon return // If we're currently in an event, just tell it to save upon return
// //
if (m_InEvent) if (m_InEvent)
@ -899,10 +892,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
return; return;
} }
// Data may not be available as the script has already been destroyed
if (m_destroyed == true)
return;
PluginData = AsyncCommandManager.GetSerializationData(m_Engine, m_ItemID); PluginData = AsyncCommandManager.GetSerializationData(m_Engine, m_ItemID);
string xml = ScriptSerializer.Serialize(this); string xml = ScriptSerializer.Serialize(this);

View File

@ -272,10 +272,6 @@ namespace OpenSim.Region.ScriptEngine.XEngine
instance.ClearQueue(); instance.ClearQueue();
instance.Stop(0); instance.Stop(0);
// Release events, timer, etc
//
instance.DestroyScriptInstance();
// Unload scripts and app domains // Unload scripts and app domains
// Must be done explicitly because they have infinite // Must be done explicitly because they have infinite
// lifetime // lifetime
@ -286,6 +282,10 @@ namespace OpenSim.Region.ScriptEngine.XEngine
m_DomainScripts.Remove(instance.AppDomain); m_DomainScripts.Remove(instance.AppDomain);
UnloadAppDomain(instance.AppDomain); UnloadAppDomain(instance.AppDomain);
} }
// Release events, timer, etc
//
instance.DestroyScriptInstance();
} }
m_Scripts.Clear(); m_Scripts.Clear();
m_PrimObjects.Clear(); m_PrimObjects.Clear();
@ -802,9 +802,6 @@ namespace OpenSim.Region.ScriptEngine.XEngine
} }
} }
instance.RemoveState();
instance.DestroyScriptInstance();
m_DomainScripts[instance.AppDomain].Remove(instance.ItemID); m_DomainScripts[instance.AppDomain].Remove(instance.ItemID);
if (m_DomainScripts[instance.AppDomain].Count == 0) if (m_DomainScripts[instance.AppDomain].Count == 0)
{ {
@ -812,6 +809,9 @@ namespace OpenSim.Region.ScriptEngine.XEngine
UnloadAppDomain(instance.AppDomain); UnloadAppDomain(instance.AppDomain);
} }
instance.RemoveState();
instance.DestroyScriptInstance();
instance = null; instance = null;
ObjectRemoved handlerObjectRemoved = OnObjectRemoved; ObjectRemoved handlerObjectRemoved = OnObjectRemoved;