[glib] Make the closure variants of name owning and watching actually work



commit 402ad1958ccdb4586da9614ec4276396fd4c0faf
Author: Matthias Clasen <mclasen redhat com>
Date:   Sat Aug 7 16:27:38 2010 -0400

    Make the closure variants of name owning and watching actually work
    
    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   |   92 ++++++++++++++++++++++++++--------------------
 gio/gdbusnamewatching.c |   76 ++++++++++++++++++++-------------------
 gio/gio-marshal.list    |    2 +
 gio/tests/gdbus-names.c |   57 ++++++++++++++++++-----------
 4 files changed, 128 insertions(+), 99 deletions(-)
---
diff --git a/gio/gdbusnameowning.c b/gio/gdbusnameowning.c
index f50e7f7..6a5dc84 100644
--- a/gio/gdbusnameowning.c
+++ b/gio/gdbusnameowning.c
@@ -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);
 }
 
diff --git a/gio/gdbusnamewatching.c b/gio/gdbusnamewatching.c
index d4f70db..fc919b1 100644
--- a/gio/gdbusnamewatching.c
+++ b/gio/gdbusnamewatching.c
@@ -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);
 }
 
diff --git a/gio/gio-marshal.list b/gio/gio-marshal.list
index c75d5c4..600361d 100644
--- a/gio/gio-marshal.list
+++ b/gio/gio-marshal.list
@@ -18,3 +18,5 @@ VOID:STRING,UINT
 VOID:BOXED,BOXED
 VOID:VARIANT,BOXED
 VOID:STRING,STRING,VARIANT
+VOID:STRING
+VOID:STRING,STRING
diff --git a/gio/tests/gdbus-names.c b/gio/tests/gdbus-names.c
index d5e2342..d69d0bf 100644
--- a/gio/tests/gdbus-names.c
+++ b/gio/tests/gdbus-names.c
@@ -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);



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]