Make the closure variants of name owning and watching actually work
authorMatthias Clasen <mclasen@redhat.com>
Sat, 7 Aug 2010 20:27:38 +0000 (16:27 -0400)
committerMatthias Clasen <mclasen@redhat.com>
Sat, 7 Aug 2010 21:10:17 +0000 (17:10 -0400)
The GClosure API is a bit funky (and badly documented), and requires
you to set a marshaller on the closure, and the marshaller has an
implicit 'this' argument, and the caller is reponsible for unsetting
the values after invoking the closure.

I've added some calls of the _with_closures variants to the
gdbus-names test now.

gio/gdbusnameowning.c
gio/gdbusnamewatching.c
gio/gio-marshal.list
gio/tests/gdbus-names.c

index f50e7f7..6a5dc84 100644 (file)
@@ -29,6 +29,7 @@
 #include "gdbuserror.h"
 #include "gdbusprivate.h"
 #include "gdbusconnection.h"
+#include "gio-marshal.h"
 
 #include "glibintl.h"
 
@@ -634,6 +635,42 @@ typedef struct {
   GClosure *name_lost_closure;
 } OwnNameData;
 
+static OwnNameData *
+own_name_data_new (GClosure *bus_acquired_closure,
+                   GClosure *name_acquired_closure,
+                   GClosure *name_lost_closure)
+{
+  OwnNameData *data;
+
+  data = g_new0 (OwnNameData, 1);
+
+  if (bus_acquired_closure != NULL)
+    {
+      data->bus_acquired_closure = g_closure_ref (bus_acquired_closure);
+      g_closure_sink (bus_acquired_closure);
+      if (G_CLOSURE_NEEDS_MARSHAL (bus_acquired_closure))
+        g_closure_set_marshal (bus_acquired_closure, _gio_marshal_VOID__STRING);
+    }
+
+  if (name_acquired_closure != NULL)
+    {
+      data->name_acquired_closure = g_closure_ref (name_acquired_closure);
+      g_closure_sink (name_acquired_closure);
+      if (G_CLOSURE_NEEDS_MARSHAL (name_acquired_closure))
+        g_closure_set_marshal (name_acquired_closure, _gio_marshal_VOID__STRING);
+    }
+
+  if (name_lost_closure != NULL)
+    {
+      data->name_lost_closure = g_closure_ref (name_lost_closure);
+      g_closure_sink (name_lost_closure);
+      if (G_CLOSURE_NEEDS_MARSHAL (name_lost_closure))
+        g_closure_set_marshal (name_lost_closure, _gio_marshal_VOID__STRING);
+    }
+
+  return data;
+}
+
 static void
 own_with_closures_on_bus_acquired (GDBusConnection *connection,
                                    const gchar     *name,
@@ -649,6 +686,9 @@ own_with_closures_on_bus_acquired (GDBusConnection *connection,
   g_value_set_string (&params[1], name);
 
   g_closure_invoke (data->bus_acquired_closure, NULL, 2, params, NULL);
+
+  g_value_unset (params + 0);
+  g_value_unset (params + 1);
 }
 
 static void
@@ -666,6 +706,9 @@ own_with_closures_on_name_acquired (GDBusConnection *connection,
   g_value_set_string (&params[1], name);
 
   g_closure_invoke (data->name_acquired_closure, NULL, 2, params, NULL);
+
+  g_value_unset (params + 0);
+  g_value_unset (params + 1);
 }
 
 static void
@@ -683,6 +726,9 @@ own_with_closures_on_name_lost (GDBusConnection *connection,
   g_value_set_string (&params[1], name);
 
   g_closure_invoke (data->name_lost_closure, NULL, 2, params, NULL);
+
+  g_value_unset (params + 0);
+  g_value_unset (params + 1);
 }
 
 static void
@@ -732,35 +778,15 @@ g_bus_own_name_with_closures (GBusType                  bus_type,
                               GClosure                 *name_acquired_closure,
                               GClosure                 *name_lost_closure)
 {
-  OwnNameData *data;
-
-  data = g_new0 (OwnNameData, 1);
-
-  if (bus_acquired_closure != NULL)
-    {
-      data->bus_acquired_closure = g_closure_ref (bus_acquired_closure);
-      g_closure_sink (bus_acquired_closure);
-    }
-
-  if (name_acquired_closure != NULL)
-    {
-      data->name_acquired_closure = g_closure_ref (name_acquired_closure);
-      g_closure_sink (name_acquired_closure);
-    }
-
-  if (name_lost_closure != NULL)
-    {
-      data->name_lost_closure = g_closure_ref (name_lost_closure);
-      g_closure_sink (name_lost_closure);
-    }
-
   return g_bus_own_name (bus_type,
           name,
           flags,
           bus_acquired_closure != NULL ? own_with_closures_on_bus_acquired : NULL,
           name_acquired_closure != NULL ? own_with_closures_on_name_acquired : NULL,
           name_lost_closure != NULL ? own_with_closures_on_name_lost : NULL,
-          data,
+          own_name_data_new (bus_acquired_closure,
+                             name_acquired_closure,
+                             name_lost_closure),
           bus_own_name_free_func);
 }
 
@@ -791,28 +817,14 @@ g_bus_own_name_on_connection_with_closures (GDBusConnection          *connection
                                             GClosure                 *name_acquired_closure,
                                             GClosure                 *name_lost_closure)
 {
-  OwnNameData *data;
-
-  data = g_new0 (OwnNameData, 1);
-
-  if (name_acquired_closure != NULL)
-    {
-      data->name_acquired_closure = g_closure_ref (name_acquired_closure);
-      g_closure_sink (name_acquired_closure);
-    }
-
-  if (name_lost_closure != NULL)
-    {
-      data->name_lost_closure = g_closure_ref (name_lost_closure);
-      g_closure_sink (name_lost_closure);
-    }
-
   return g_bus_own_name_on_connection (connection,
           name,
           flags,
           name_acquired_closure != NULL ? own_with_closures_on_name_acquired : NULL,
           name_lost_closure != NULL ? own_with_closures_on_name_lost : NULL,
-          data,
+          own_name_data_new (NULL,
+                             name_acquired_closure,
+                             name_lost_closure),
           bus_own_name_free_func);
 }
 
index d4f70db..fc919b1 100644 (file)
@@ -30,6 +30,7 @@
 #include "gdbuserror.h"
 #include "gdbusprivate.h"
 #include "gdbusconnection.h"
+#include "gio-marshal.h"
 
 #include "glibintl.h"
 
@@ -635,9 +636,8 @@ guint g_bus_watch_name_on_connection (GDBusConnection          *connection,
     g_main_context_ref (client->main_context);
 
   if (map_id_to_client == NULL)
-    {
-      map_id_to_client = g_hash_table_new (g_direct_hash, g_direct_equal);
-    }
+    map_id_to_client = g_hash_table_new (g_direct_hash, g_direct_equal);
+
   g_hash_table_insert (map_id_to_client,
                        GUINT_TO_POINTER (client->id),
                        client);
@@ -655,6 +655,33 @@ typedef struct {
   GClosure *name_vanished_closure;
 } WatchNameData;
 
+static WatchNameData *
+watch_name_data_new (GClosure *name_appeared_closure,
+                     GClosure *name_vanished_closure)
+{
+  WatchNameData *data;
+
+  data = g_new0 (WatchNameData, 1);
+
+  if (name_appeared_closure != NULL)
+    {
+      data->name_appeared_closure = g_closure_ref (name_appeared_closure);
+      g_closure_sink (name_appeared_closure);
+      if (G_CLOSURE_NEEDS_MARSHAL (name_appeared_closure))
+        g_closure_set_marshal (name_appeared_closure, _gio_marshal_VOID__STRING_STRING);
+    }
+
+  if (name_vanished_closure != NULL)
+    {
+      data->name_vanished_closure = g_closure_ref (name_vanished_closure);
+      g_closure_sink (name_vanished_closure);
+      if (G_CLOSURE_NEEDS_MARSHAL (name_vanished_closure))
+        g_closure_set_marshal (name_vanished_closure, _gio_marshal_VOID__STRING);
+    }
+
+  return data;
+}
+
 static void
 watch_with_closures_on_name_appeared (GDBusConnection *connection,
                                       const gchar     *name,
@@ -674,6 +701,10 @@ watch_with_closures_on_name_appeared (GDBusConnection *connection,
   g_value_set_string (&params[2], name_owner);
 
   g_closure_invoke (data->name_appeared_closure, NULL, 3, params, NULL);
+
+  g_value_unset (params + 0);
+  g_value_unset (params + 1);
+  g_value_unset (params + 2);
 }
 
 static void
@@ -691,6 +722,9 @@ watch_with_closures_on_name_vanished (GDBusConnection *connection,
   g_value_set_string (&params[1], name);
 
   g_closure_invoke (data->name_vanished_closure, NULL, 2, params, NULL);
+
+  g_value_unset (params + 0);
+  g_value_unset (params + 1);
 }
 
 static void
@@ -734,28 +768,12 @@ g_bus_watch_name_with_closures (GBusType                 bus_type,
                                 GClosure                *name_appeared_closure,
                                 GClosure                *name_vanished_closure)
 {
-  WatchNameData *data;
-
-  data = g_new0 (WatchNameData, 1);
-
-  if (name_appeared_closure != NULL)
-    {
-      data->name_appeared_closure = g_closure_ref (name_appeared_closure);
-      g_closure_sink (name_appeared_closure);
-    }
-
-  if (name_vanished_closure != NULL)
-    {
-      data->name_vanished_closure = g_closure_ref (name_vanished_closure);
-      g_closure_sink (name_vanished_closure);
-    }
-
   return g_bus_watch_name (bus_type,
           name,
           flags,
           name_appeared_closure != NULL ? watch_with_closures_on_name_appeared : NULL,
           name_vanished_closure != NULL ? watch_with_closures_on_name_vanished : NULL,
-          data,
+          watch_name_data_new (name_appeared_closure, name_vanished_closure),
           bus_watch_name_free_func);
 }
 
@@ -786,28 +804,12 @@ guint g_bus_watch_name_on_connection_with_closures (
                                       GClosure                 *name_appeared_closure,
                                       GClosure                 *name_vanished_closure)
 {
-  WatchNameData *data;
-
-  data = g_new0 (WatchNameData, 1);
-
-  if (name_appeared_closure != NULL)
-    {
-      data->name_appeared_closure = g_closure_ref (name_appeared_closure);
-      g_closure_sink (name_appeared_closure);
-    }
-
-  if (name_vanished_closure != NULL)
-    {
-      data->name_vanished_closure = g_closure_ref (name_vanished_closure);
-      g_closure_sink (name_vanished_closure);
-    }
-
   return g_bus_watch_name_on_connection (connection,
           name,
           flags,
           name_appeared_closure != NULL ? watch_with_closures_on_name_appeared : NULL,
           name_vanished_closure != NULL ? watch_with_closures_on_name_vanished : NULL,
-          data,
+          watch_name_data_new (name_appeared_closure, name_vanished_closure),
           bus_watch_name_free_func);
 }
 
index c75d5c4..600361d 100644 (file)
@@ -18,3 +18,5 @@ VOID:STRING,UINT
 VOID:BOXED,BOXED
 VOID:VARIANT,BOXED
 VOID:STRING,STRING,VARIANT
+VOID:STRING
+VOID:STRING,STRING
index d5e2342..d69d0bf 100644 (file)
@@ -220,14 +220,18 @@ test_bus_own_name (void)
   data.num_acquired = 0;
   data.num_lost = 0;
   data.expect_null_connection = FALSE;
-  id = g_bus_own_name (G_BUS_TYPE_SESSION,
-                       name,
-                       G_BUS_NAME_OWNER_FLAGS_NONE,
-                       bus_acquired_handler,
-                       name_acquired_handler,
-                       name_lost_handler,
-                       &data,
-                       (GDestroyNotify) own_name_data_free_func);
+  id = g_bus_own_name_with_closures (G_BUS_TYPE_SESSION,
+                                     name,
+                                     G_BUS_NAME_OWNER_FLAGS_NONE,
+                                     g_cclosure_new (G_CALLBACK (bus_acquired_handler),
+                                                     &data,
+                                                     NULL),
+                                     g_cclosure_new (G_CALLBACK (name_acquired_handler),
+                                                     &data,
+                                                     NULL),
+                                     g_cclosure_new (G_CALLBACK (name_lost_handler),
+                                                     &data,
+                                                     (GClosureNotify) own_name_data_free_func));
   g_assert_cmpint (data.num_bus_acquired, ==, 0);
   g_assert_cmpint (data.num_acquired, ==, 0);
   g_assert_cmpint (data.num_lost,     ==, 0);
@@ -538,6 +542,7 @@ test_bus_watch_name (void)
   WatchNameData data;
   guint id;
   guint owner_id;
+  GDBusConnection *connection;
 
   /*
    * First check that name_vanished_handler() is invoked if there is no bus.
@@ -585,16 +590,20 @@ test_bus_watch_name (void)
   g_main_loop_run (loop);
   g_assert_cmpint (data.num_acquired, ==, 1);
   g_assert_cmpint (data.num_lost,     ==, 0);
+
+  connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL);
+  g_assert (connection != NULL);
+
   /* now watch the name */
   data.num_appeared = 0;
   data.num_vanished = 0;
-  id = g_bus_watch_name (G_BUS_TYPE_SESSION,
-                         "org.gtk.GDBus.Name1",
-                         G_BUS_NAME_WATCHER_FLAGS_NONE,
-                         name_appeared_handler,
-                         name_vanished_handler,
-                         &data,
-                         (GDestroyNotify) watch_name_data_free_func);
+  id = g_bus_watch_name_on_connection (connection,
+                                       "org.gtk.GDBus.Name1",
+                                       G_BUS_NAME_WATCHER_FLAGS_NONE,
+                                       name_appeared_handler,
+                                       name_vanished_handler,
+                                       &data,
+                                       (GDestroyNotify) watch_name_data_free_func);
   g_assert_cmpint (data.num_appeared, ==, 0);
   g_assert_cmpint (data.num_vanished, ==, 0);
   g_main_loop_run (loop);
@@ -607,6 +616,8 @@ test_bus_watch_name (void)
   g_bus_unwatch_name (id);
   g_assert_cmpint (data.num_free_func, ==, 1);
 
+  g_object_unref (connection);
+
   /* unown the name */
   g_bus_unown_name (owner_id);
   g_assert_cmpint (data.num_acquired, ==, 1);
@@ -621,13 +632,15 @@ test_bus_watch_name (void)
   data.num_appeared = 0;
   data.num_vanished = 0;
   data.num_free_func = 0;
-  id = g_bus_watch_name (G_BUS_TYPE_SESSION,
-                         "org.gtk.GDBus.Name1",
-                         G_BUS_NAME_WATCHER_FLAGS_NONE,
-                         name_appeared_handler,
-                         name_vanished_handler,
-                         &data,
-                         (GDestroyNotify) watch_name_data_free_func);
+  id = g_bus_watch_name_with_closures (G_BUS_TYPE_SESSION,
+                                       "org.gtk.GDBus.Name1",
+                                       G_BUS_NAME_WATCHER_FLAGS_NONE,
+                                       g_cclosure_new (G_CALLBACK (name_appeared_handler),
+                                                       &data,
+                                                       NULL),
+                                       g_cclosure_new (G_CALLBACK (name_vanished_handler),
+                                                       &data,
+                                                       (GClosureNotify) watch_name_data_free_func));
   g_assert_cmpint (data.num_appeared, ==, 0);
   g_assert_cmpint (data.num_vanished, ==, 0);
   g_main_loop_run (loop);