Commit 402ad195 authored by Matthias Clasen's avatar Matthias Clasen

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.
parent c15d20e5
......@@ -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);
}
......
......@@ -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);
}
......
......@@ -18,3 +18,5 @@ VOID:STRING,UINT
VOID:BOXED,BOXED
VOID:VARIANT,BOXED
VOID:STRING,STRING,VARIANT
VOID:STRING
VOID:STRING,STRING
......@@ -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);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment