summaryrefslogtreecommitdiffstats
path: root/mono/Connection.cs
diff options
context:
space:
mode:
authorHavoc Pennington <hp@redhat.com>2003-06-22 22:59:31 +0000
committerHavoc Pennington <hp@redhat.com>2003-06-22 22:59:31 +0000
commit1cc184b4a849619b56bed2be0e752fbc0fb75a29 (patch)
tree867409e28e08152147e095606e487793873dd51e /mono/Connection.cs
parent958805418359aca169cd363a4a3279f0fdab753c (diff)
2003-06-22 Havoc Pennington <hp@pobox.com>
* mono/Connection.cs, mono/DBus.cs, mono/Error.cs: Start wrapping more stuff.
Diffstat (limited to 'mono/Connection.cs')
-rw-r--r--mono/Connection.cs123
1 files changed, 123 insertions, 0 deletions
diff --git a/mono/Connection.cs b/mono/Connection.cs
new file mode 100644
index 00000000..f0d34eec
--- /dev/null
+++ b/mono/Connection.cs
@@ -0,0 +1,123 @@
+namespace DBus {
+
+ using System;
+ using System.Runtime.InteropServices;
+ using System.Diagnostics;
+
+ public class Connection {
+
+ public Connection (string address) {
+ // the assignment bumps the refcount
+ Error error = new Error ();
+ error.Init ();
+ raw = dbus_connection_open (address, ref error);
+ if (raw != (IntPtr) 0) {
+ dbus_connection_unref (raw);
+ } else {
+ Exception e = new Exception (ref error);
+ error.Free ();
+ throw e;
+ }
+ }
+
+ public static Connection Wrap (IntPtr ptr) {
+ IntPtr gch_ptr;
+
+ gch_ptr = dbus_connection_get_data (ptr, wrapper_slot);
+ if (gch_ptr != (IntPtr) 0) {
+ return (DBus.Connection) ((GCHandle)gch_ptr).Target;
+ } else {
+ return new Connection (ptr);
+ }
+ }
+
+ // surely there's a convention for this pattern with the property
+ // and the real member
+ IntPtr raw_;
+ IntPtr raw {
+ get {
+ return raw_;
+ }
+ set {
+ if (value == raw_)
+ return;
+
+ if (raw_ != (IntPtr) 0) {
+ IntPtr gch_ptr;
+
+ gch_ptr = dbus_connection_get_data (raw_,
+ wrapper_slot);
+ Debug.Assert (gch_ptr != (IntPtr) 0);
+
+ dbus_connection_set_data (raw_, wrapper_slot,
+ (IntPtr) 0, (IntPtr) 0);
+
+ ((GCHandle) gch_ptr).Free ();
+
+ dbus_connection_unref (raw_);
+ }
+
+ raw_ = value;
+
+ if (raw_ != (IntPtr) 0) {
+ GCHandle gch;
+
+ dbus_connection_ref (raw_);
+
+ // We store a weak reference to the C# object on the C object
+ gch = GCHandle.Alloc (this, GCHandleType.WeakTrackResurrection);
+
+ dbus_connection_set_data (raw_, wrapper_slot,
+ (IntPtr) gch, (IntPtr) 0);
+ }
+ }
+ }
+
+ ~Connection () {
+ raw = (IntPtr) 0; // free the native object
+ }
+
+ Connection (IntPtr r) {
+ raw = r;
+ }
+
+ // static constructor runs before any methods
+ static Connection () {
+ Debug.Assert (wrapper_slot == -1);
+
+ if (!dbus_connection_allocate_data_slot (ref wrapper_slot))
+ throw new OutOfMemoryException ();
+
+ Debug.Assert (wrapper_slot >= 0);
+ }
+
+ // slot used to store the C# object on the C object
+ static int wrapper_slot = -1;
+
+ [DllImport (DBus.Internals.Libname, EntryPoint="dbus_connection_open")]
+ private extern static IntPtr dbus_connection_open (string address,
+ ref Error error);
+
+ [DllImport (DBus.Internals.Libname, EntryPoint="dbus_connection_unref")]
+ private extern static void dbus_connection_unref (IntPtr ptr);
+
+ [DllImport (DBus.Internals.Libname, EntryPoint="dbus_connection_ref")]
+ private extern static void dbus_connection_ref (IntPtr ptr);
+
+ [DllImport (DBus.Internals.Libname, EntryPoint="dbus_connection_allocate_data_slot")]
+ private extern static bool dbus_connection_allocate_data_slot (ref int slot);
+
+ [DllImport (DBus.Internals.Libname, EntryPoint="dbus_connection_free_data_slot")]
+ private extern static void dbus_connection_free_data_slot (ref int slot);
+
+ [DllImport (DBus.Internals.Libname, EntryPoint="dbus_connection_set_data")]
+ private extern static bool dbus_connection_set_data (IntPtr ptr,
+ int slot,
+ IntPtr data,
+ IntPtr free_data_func);
+
+ [DllImport (DBus.Internals.Libname, EntryPoint="dbus_connection_get_data")]
+ private extern static IntPtr dbus_connection_get_data (IntPtr ptr,
+ int slot);
+ }
+}