summaryrefslogtreecommitdiffstats
path: root/mono/Connection.cs
diff options
context:
space:
mode:
authorJoe Shaw <joeshaw@novell.com>2005-03-09 04:36:15 +0000
committerJoe Shaw <joeshaw@novell.com>2005-03-09 04:36:15 +0000
commit2958e723fc996e2dd7edfdc6ac53dcdf48323549 (patch)
treec031fe0f0f40e868f18eb3e257667856c1d9f4fc /mono/Connection.cs
parentd96c9e465abb291cb943a1b4ec3643de4b3f6423 (diff)
2005-03-08 Joe Shaw <joeshaw@novell.com>
Fix a bunch of lifecycle and memory management problems in the mono bindings. * mono/Arguments.cs (Arguments): Implement IDisposable * mono/Bus.cs (Bus): Don't allow public instantiation. This is strictly a static class. * mono/Connection.cs: Move the DBusObjectPathVTable and associated delegates into this file. (Connection): Implement IDisposable. (Dispose): Disconnect the connection and set the raw connection pointer to IntPtr.Zero. (~Connection): Call Dispose(). (RegisterObjectPath): Added. Manages the registration of object paths so we can cleanly disconnect them at dispose/finalize time. (UnregisterObjectPath): Ditto. (set_RawConnection): Unregister all of the object paths when changing the underlying DBusConnection. Add them back onto the new connection, if any. * mono/Handler.cs: Don't implement IDisposable; it doesn't use any more unmanaged resources anymore, so it's not necessary. Move all the DBusObjectPathVTable stuff out of here. (Handler): Save references to our delegates so that they don't get finalized. Call Connection.RegisterObjectPath() instead of dbus_connection_register_object_path() directly. (Message_Called): Dispose the message after we're finished with it. * mono/Message.cs (Message): Implement IDisposable. (Dispose): Dispose the Arguments, and set the RawMessage to IntPtr.Zero. (SendWithReplyAndBlock): We own the ref to the reply that comes back from dbus_connection_send_with_reply_and_block() so add a comment about that and unref it after we've constructed a managed MethodReturn class around it. Fixes a big, big leak. * mono/ProxyBuilder.cs: Reflect into Message to get the Dispose method. (BuildSignalHandler): After we've sent the Signal message, dispose of it. (BuildMethod): Dispose of the method call and reply messages after we've sent the message and extracted the data we want from the reply. * mono/Service.cs (UnregisterObject): Don't call handler.Dispose() anymore. (Service_FilterCalled): Dispose of the message after we're finished with it.
Diffstat (limited to 'mono/Connection.cs')
-rw-r--r--mono/Connection.cs100
1 files changed, 86 insertions, 14 deletions
diff --git a/mono/Connection.cs b/mono/Connection.cs
index 6abd7e80..af0764db 100644
--- a/mono/Connection.cs
+++ b/mono/Connection.cs
@@ -12,7 +12,36 @@ namespace DBus
IntPtr rawMessage,
IntPtr userData);
- public class Connection
+ internal delegate void DBusObjectPathUnregisterFunction(IntPtr rawConnection,
+ IntPtr userData);
+
+ internal delegate int DBusObjectPathMessageFunction(IntPtr rawConnection,
+ IntPtr rawMessage,
+ IntPtr userData);
+
+ [StructLayout (LayoutKind.Sequential)]
+ internal struct DBusObjectPathVTable
+ {
+ public DBusObjectPathUnregisterFunction unregisterFunction;
+ public DBusObjectPathMessageFunction messageFunction;
+ public IntPtr padding1;
+ public IntPtr padding2;
+ public IntPtr padding3;
+ public IntPtr padding4;
+
+ public DBusObjectPathVTable(DBusObjectPathUnregisterFunction unregisterFunction,
+ DBusObjectPathMessageFunction messageFunction)
+ {
+ this.unregisterFunction = unregisterFunction;
+ this.messageFunction = messageFunction;
+ this.padding1 = IntPtr.Zero;
+ this.padding2 = IntPtr.Zero;
+ this.padding3 = IntPtr.Zero;
+ this.padding4 = IntPtr.Zero;
+ }
+ }
+
+ public class Connection : IDisposable
{
/// <summary>
/// A pointer to the underlying Connection structure
@@ -26,8 +55,9 @@ namespace DBus
private int timeout = -1;
- private ArrayList filters = new ArrayList (); // of DBusHandleMessageFunction
- private ArrayList matches = new ArrayList (); // of string
+ private ArrayList filters = new ArrayList (); // of DBusHandleMessageFunction
+ private ArrayList matches = new ArrayList (); // of string
+ private Hashtable object_paths = new Hashtable (); // key: string value: DBusObjectPathVTable
internal Connection(IntPtr rawConnection)
{
@@ -49,6 +79,22 @@ namespace DBus
SetupWithMain();
}
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ public void Dispose (bool disposing)
+ {
+ if (disposing && RawConnection != IntPtr.Zero)
+ {
+ dbus_connection_disconnect(rawConnection);
+
+ RawConnection = IntPtr.Zero; // free the native object
+ }
+ }
+
public void Flush()
{
dbus_connection_flush(RawConnection);
@@ -61,17 +107,7 @@ namespace DBus
~Connection ()
{
- if (RawConnection != IntPtr.Zero)
- {
- foreach (DBusHandleMessageFunction func in this.filters)
- RemoveFilter (func);
-
- foreach (string match_rule in this.matches)
- RemoveMatch (match_rule);
-
- dbus_connection_disconnect(rawConnection);
- }
- RawConnection = IntPtr.Zero; // free the native object
+ Dispose (false);
}
internal static Connection Wrap(IntPtr rawConnection)
@@ -121,6 +157,22 @@ namespace DBus
this.matches.Remove (match_rule);
}
+ internal void RegisterObjectPath (string path, DBusObjectPathVTable vtable)
+ {
+ if (!dbus_connection_register_object_path (RawConnection, path, ref vtable, IntPtr.Zero))
+ throw new OutOfMemoryException ();
+
+ this.object_paths[path] = vtable;
+ }
+
+ internal void UnregisterObjectPath (string path)
+ {
+ dbus_connection_unregister_object_path (RawConnection, path);
+
+ this.object_paths.Remove (path);
+ }
+
+
public string UniqueName
{
get
@@ -178,6 +230,9 @@ namespace DBus
foreach (string match_rule in this.matches)
dbus_bus_remove_match (rawConnection, match_rule, IntPtr.Zero);
+ foreach (string path in this.object_paths.Keys)
+ dbus_connection_unregister_object_path (rawConnection, path);
+
// Get the reference to this
IntPtr rawThis = dbus_connection_get_data (rawConnection, Slot);
Debug.Assert (rawThis != IntPtr.Zero);
@@ -211,11 +266,17 @@ namespace DBus
foreach (string match_rule in this.matches)
dbus_bus_add_match (rawConnection, match_rule, IntPtr.Zero);
+
+ foreach (string path in this.object_paths.Keys) {
+ DBusObjectPathVTable vtable = (DBusObjectPathVTable) this.object_paths[path];
+ dbus_connection_register_object_path (rawConnection, path, ref vtable, IntPtr.Zero);
+ }
}
else
{
this.filters.Clear ();
this.matches.Clear ();
+ this.object_paths.Clear ();
}
}
}
@@ -278,5 +339,16 @@ namespace DBus
private extern static void dbus_bus_remove_match(IntPtr rawConnection,
string rule,
IntPtr erro);
+
+ [DllImport ("dbus-1")]
+ private extern static bool dbus_connection_register_object_path (IntPtr rawConnection,
+ string path,
+ ref DBusObjectPathVTable vTable,
+ IntPtr userData);
+
+ [DllImport ("dbus-1")]
+ private extern static void dbus_connection_unregister_object_path (IntPtr rawConnection,
+ string path);
+
}
}