diff options
| author | Joe Shaw <joeshaw@novell.com> | 2005-03-09 04:36:15 +0000 | 
|---|---|---|
| committer | Joe Shaw <joeshaw@novell.com> | 2005-03-09 04:36:15 +0000 | 
| commit | 2958e723fc996e2dd7edfdc6ac53dcdf48323549 (patch) | |
| tree | c031fe0f0f40e868f18eb3e257667856c1d9f4fc /mono/Connection.cs | |
| parent | d96c9e465abb291cb943a1b4ec3643de4b3f6423 (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.cs | 100 | 
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); +    }  }  | 
