dbus/mono ProxyBuilder.cs,1.5.2.1,1.5.2.2
Joe Shaw
joe at freedesktop.org
Sat Mar 12 17:12:02 PST 2005
Update of /cvs/dbus/dbus/mono
In directory gabe:/tmp/cvs-serv9650/mono
Modified Files:
Tag: dbus-0-23
ProxyBuilder.cs
Log Message:
2005-03-12 Joe Shaw <joeshaw at novell.com>
* mono/ProxyBuilder.cs: Add a finalizer to the generated proxy
classes that disconnects the signal handler delegate from the
service object. Fixes a big leak of proxy objects on the
client side of things. Patch from Ben Maurer
<bmaurer at ximian.com>
Index: ProxyBuilder.cs
===================================================================
RCS file: /cvs/dbus/dbus/mono/ProxyBuilder.cs,v
retrieving revision 1.5.2.1
retrieving revision 1.5.2.2
diff -u -d -r1.5.2.1 -r1.5.2.2
--- ProxyBuilder.cs 9 Mar 2005 04:35:17 -0000 1.5.2.1
+++ ProxyBuilder.cs 13 Mar 2005 01:11:59 -0000 1.5.2.2
@@ -21,6 +21,8 @@
new Type[0]);
private static MethodInfo Service_AddSignalCalledMI = typeof(Service).GetMethod("add_SignalCalled",
new Type[] {typeof(Service.SignalCalledHandler)});
+ private static MethodInfo Service_RemoveSignalCalledMI = typeof(Service).GetMethod("remove_SignalCalled",
+ new Type[] {typeof(Service.SignalCalledHandler)});
private static MethodInfo Signal_PathNameMI = typeof(Signal).GetMethod("get_PathName",
new Type[0]);
private static MethodInfo Message_ArgumentsMI = typeof(Message).GetMethod("get_Arguments",
@@ -402,7 +404,7 @@
}
}
- public void BuildConstructor(ref TypeBuilder typeB, FieldInfo serviceF, FieldInfo pathF, MethodInfo signalCalledMI)
+ public void BuildConstructor(ref TypeBuilder typeB, FieldInfo serviceF, FieldInfo pathF, MethodInfo signalCalledMI, FieldInfo deleF)
{
Type[] pars = {typeof(Service), typeof(string)};
ConstructorBuilder constructor = typeB.DefineConstructor(MethodAttributes.RTSpecialName |
@@ -419,12 +421,19 @@
generator.Emit(OpCodes.Ldarg_0);
generator.Emit(OpCodes.Ldarg_2);
generator.Emit(OpCodes.Stfld, pathF);
-
- //generator.EmitWriteLine("myService.SignalCalled += new Service.SignalCalledHandler(Service_SignalCalled)");
+
+ //generator.EmitWriteLine("this.delegate_created = new Service.SignalCalledHandler(Service_SignalCalled)");
generator.Emit(OpCodes.Ldarg_1);
generator.Emit(OpCodes.Ldarg_0);
generator.Emit(OpCodes.Ldftn, signalCalledMI);
generator.Emit(OpCodes.Newobj, Service_SignalCalledHandlerC);
+ generator.Emit(OpCodes.Stloc_0);
+ generator.Emit(OpCodes.Ldarg_0);
+ generator.Emit(OpCodes.Ldloc_0);
+ generator.Emit(OpCodes.Stfld, deleF);
+
+ //generator.EmitWriteLine("myService.SignalCalled += this.delegate_created");
+ generator.Emit(OpCodes.Ldloc_0);
generator.EmitCall(OpCodes.Callvirt, Service_AddSignalCalledMI, null);
//generator.EmitWriteLine("return");
@@ -453,6 +462,27 @@
generator.Emit(OpCodes.Ret);
}
+ public void BuildFinalizer (TypeBuilder tb, FieldInfo fi)
+ {
+ // Note that this is a *HORRIBLE* example of how to build a finalizer
+ // It doesn't use the try/finally to chain to Object::Finalize. However,
+ // because that is always going to be a nop, lets just ignore that here.
+ // If you are trying to find the right code, look at what mcs does ;-).
+
+ MethodBuilder mb = tb.DefineMethod("Finalize",
+ MethodAttributes.Family |
+ MethodAttributes.HideBySig |
+ MethodAttributes.Virtual,
+ typeof (void),
+ new Type [0]);
+ ILGenerator generator = mb.GetILGenerator();
+
+ //generator.EmitWriteLine("this.service.SignalCalled -= this.delegate_created");
+ generator.Emit (OpCodes.Ldfld, fi);
+ generator.Emit (OpCodes.Call, Service_RemoveSignalCalledMI);
+ generator.Emit (OpCodes.Ret);
+ }
+
public object GetSignalProxy()
{
Type proxyType = Service.ProxyAssembly.GetType(ObjectName + ".SignalProxy");
@@ -516,9 +546,13 @@
FieldBuilder pathF = typeB.DefineField("pathName",
typeof(string),
FieldAttributes.Private);
+ FieldBuilder deleF = typeB.DefineField("delegate_created",
+ typeof(Service.SignalCalledHandler),
+ FieldAttributes.Private);
+ BuildFinalizer (typeB, deleF);
MethodInfo signalCalledMI = BuildSignalCalled(ref typeB, serviceF, pathF);
- BuildConstructor(ref typeB, serviceF, pathF, signalCalledMI);
+ BuildConstructor(ref typeB, serviceF, pathF, signalCalledMI, deleF);
// Build the methods
foreach (DictionaryEntry interfaceEntry in this.introspector.InterfaceProxies) {
More information about the dbus-commit
mailing list