summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Zeuthen <davidz@redhat.com>2010-06-18 13:12:53 -0400
committerDavid Zeuthen <davidz@redhat.com>2010-06-18 13:12:53 -0400
commitc035ac1bac4914794acc869acce9c1532434cb91 (patch)
treed87494faf2a95ce788058843f071573dec118012
parent54050bb239a60f59c573314bc87fbf4c2c740f6f (diff)
Updates
Signed-off-by: David Zeuthen <davidz@redhat.com>
-rw-r--r--src/gdbusgi.c144
-rw-r--r--src/myfrobnicator.c27
-rw-r--r--src/myfrobnicator.h1
-rw-r--r--src/test.c36
4 files changed, 175 insertions, 33 deletions
diff --git a/src/gdbusgi.c b/src/gdbusgi.c
index a826c02..c543542 100644
--- a/src/gdbusgi.c
+++ b/src/gdbusgi.c
@@ -1029,6 +1029,7 @@ typedef struct
GHashTable *g_signal_name_to_signal_data;
} InterfaceData;
+/* see comment in export_data_free() */
static void
interface_data_free (InterfaceData *data)
{
@@ -1053,13 +1054,21 @@ typedef struct
GDestroyNotify user_data_free_func;
InterfaceData *interface_data;
+
+ /* A list of GDBusClosure objects - one for each signal */
+ GList *closures;
} ExportData;
static void
export_data_free (ExportData *data)
{
- if (data->interface_data != NULL)
- interface_data_free (data->interface_data);
+ GList *l;
+
+ for (l = data->closures; l != NULL; l = l->next)
+ {
+ GClosure *closure = l->data;
+ g_closure_unref (closure);
+ }
if (data->object != NULL)
g_object_unref (data->object);
g_free (data->object_path);
@@ -1067,7 +1076,13 @@ export_data_free (ExportData *data)
g_object_unref (data->connection);
if (data->user_data_free_func != NULL)
data->user_data_free_func (data->user_data);
+#if 0
+ /* TODO: for now we just leak the InterfaceData object to avoid recreating it all the time. */
+ if (data->interface_data != NULL)
+ interface_data_free (data->interface_data);
+#endif
g_free (data);
+ g_debug ("blah");
}
/* ---------------------------------------------------------------------------------------------------- */
@@ -1417,9 +1432,11 @@ process_args (GArgument *return_value,
/* ---------------------------------------------------------------------------------------------------- */
static void
-free_one_arg (GArgument *arg,
- GITypeInfo *type,
- GITransfer transfer)
+free_one_arg (GArgument *arg,
+ GITypeInfo *type,
+ GITransfer transfer,
+ GArgument **all_args,
+ ArgData **all_args_data)
{
GITypeTag tag;
@@ -1456,20 +1473,126 @@ free_one_arg (GArgument *arg,
break;
case GI_TRANSFER_EVERYTHING:
+ //g_debug ("freeing %p (%s)", arg->v_string, arg->v_string);
g_free (arg->v_string);
+ //g_debug ("done");
break;
}
break;
case GI_TYPE_TAG_ARRAY:
- /* TODO */
+ {
+ GITypeInfo *element_type;
+ element_type = g_type_info_get_param_type (type, 0);
+ switch (transfer)
+ {
+ case GI_TRANSFER_NOTHING:
+ /* do nothing */
+ break;
+
+ case GI_TRANSFER_EVERYTHING:
+ {
+ guint n;
+ gint array_length;
+ switch (g_type_info_get_array_type (type))
+ {
+ case GI_ARRAY_TYPE_C:
+ {
+ GArgument *element;
+ if (g_type_info_is_zero_terminated (type))
+ {
+ gpointer *p;
+ p = arg->v_pointer;
+ while (*p != NULL)
+ {
+ element = (GArgument *) p++;
+ free_one_arg (element, element_type, transfer, all_args, all_args_data);
+ }
+ }
+ else if ((array_length = g_type_info_get_array_length (type)) != -1)
+ {
+ guint64 array_len;
+ array_len = argument_get_number (all_args[array_length], all_args_data[array_length]->type_info);
+ /* We only support scalar types and strings here */
+ if (g_type_info_get_tag (element_type) == GI_TYPE_TAG_UTF8)
+ {
+ for (n = 0; n < array_len; n++)
+ {
+ element = (GArgument *) ((gpointer *) arg->v_pointer + n);
+ free_one_arg (element, element_type, transfer, all_args, all_args_data);
+ }
+ }
+ else
+ {
+ guint element_size;
+ element_size = get_scalar_element_size (element_type);
+ for (n = 0; n < array_len; n++)
+ {
+ element = (GArgument *) ((guchar *) arg->v_pointer + element_size * n);
+ free_one_arg (element, element_type, transfer, all_args, all_args_data);
+ }
+ }
+ }
+ else
+ {
+ g_assert_not_reached ();
+ }
+ }
+ break;
+
+ case GI_ARRAY_TYPE_ARRAY:
+ {
+ GArray *a = (GArray *) arg->v_pointer;
+ guint elem_size = g_array_get_element_size (a);
+ for (n = 0; n < a->len; n++)
+ free_one_arg ((GArgument *) a->data + n*elem_size, element_type, transfer, all_args, all_args_data);
+ }
+ break;
+
+ case GI_ARRAY_TYPE_PTR_ARRAY:
+ {
+ GPtrArray *a = (GPtrArray *) arg->v_pointer;
+ for (n = 0; n < a->len; n++)
+ free_one_arg ((GArgument *) &(a->pdata[n]), element_type, transfer, all_args, all_args_data);
+ }
+ break;
+
+ case GI_ARRAY_TYPE_BYTE_ARRAY:
+ /* nothing to do */
+ break;
+ }
+ }
+ /* explicit fallthrough */
+
+ case GI_TRANSFER_CONTAINER:
+ {
+ switch (g_type_info_get_array_type (type))
+ {
+ case GI_ARRAY_TYPE_C:
+ g_free (arg->v_pointer);
+ break;
+ case GI_ARRAY_TYPE_ARRAY:
+ g_array_unref ((GArray *) arg->v_pointer);
+ break;
+ case GI_ARRAY_TYPE_PTR_ARRAY:
+ g_ptr_array_unref ((GPtrArray *) arg->v_pointer);
+ break;
+ case GI_ARRAY_TYPE_BYTE_ARRAY:
+ g_byte_array_unref ((GByteArray *) arg->v_pointer);
+ break;
+ }
+ }
+ break;
+ }
+ g_base_info_unref (element_type);
+ }
break;
default:
g_error ("Don't know how to free type tag `%s' with transfer `%s'",
g_type_tag_to_string (tag),
transfer == GI_TRANSFER_NOTHING ? "nothing" :
- (transfer == GI_TRANSFER_CONTAINER ? "container" : "everything"));
+ (transfer == GI_TRANSFER_CONTAINER ? "container" : "everything"));
break;
}
}
@@ -1487,14 +1610,14 @@ free_args (GArgument *return_value,
if (g_type_info_get_tag (data->return_value->type_info) != GI_TYPE_TAG_VOID)
{
ad = data->return_value;
- free_one_arg (return_value, ad->type_info, ad->transfer);
+ free_one_arg (return_value, ad->type_info, ad->transfer, args, (ArgData **) data->args->pdata);
}
/* want to skip this/self so start at 1 */
for (n = 1; n < data->args->len; n++)
{
ad = data->args->pdata[n];
- free_one_arg (args[n], ad->type_info, ad->transfer);
+ free_one_arg (args[n], ad->type_info, ad->transfer, args, (ArgData **) data->args->pdata);
}
}
@@ -1873,7 +1996,8 @@ g_dbus_connection_register_gobject (GDBusConnection *connection,
(GClosure *) closure,
TRUE);
closure->export_data = data;
- /* TODO: we need to unregister these handlers in export_data_free() */
+
+ data->closures = g_list_prepend (data->closures, closure);
}
return g_dbus_connection_register_object (connection,
diff --git a/src/myfrobnicator.c b/src/myfrobnicator.c
index 9936e62..2b901b0 100644
--- a/src/myfrobnicator.c
+++ b/src/myfrobnicator.c
@@ -371,7 +371,8 @@ my_frobnicator_test_arrays (MyFrobnicator *frobnicator,
* @frobnicator:
* @out_garray_ai: (out) (element-type gint):
* @out_garray_ad: (out)(element-type gdouble):
- * @out_gptrarray_as: (out) (element-type utf8):
+ * @out_gptrarray_as: (out) (element-type utf8) (transfer container):
+ * @out_other_gptrarray_as: (out) (element-type utf8) (transfer full):
* @out_gbytearray_ay: (out) (element-type guint8):
* @out_carray_ai: (out) (array length=out_carray_ai_len):
* @out_carray_ai_len:
@@ -386,6 +387,7 @@ my_frobnicator_return_arrays (MyFrobnicator *frobnicator,
GArray **out_garray_ai,
GArray **out_garray_ad,
GPtrArray **out_gptrarray_as,
+ GPtrArray **out_other_gptrarray_as,
GByteArray **out_gbytearray_ay,
gint **out_carray_ai,
guint *out_carray_ai_len,
@@ -398,20 +400,25 @@ my_frobnicator_return_arrays (MyFrobnicator *frobnicator,
*out_garray_ai = g_array_new (FALSE, FALSE, sizeof (gint));
g_array_set_size (*out_garray_ai, 3);
- ((gint *) (*out_garray_ai)->data)[0] = 10000;
- ((gint *) (*out_garray_ai)->data)[1] = 20000;
- ((gint *) (*out_garray_ai)->data)[2] = 30000;
+ ((gint *) (*out_garray_ai)->data)[0] = 100000;
+ ((gint *) (*out_garray_ai)->data)[1] = 200000;
+ ((gint *) (*out_garray_ai)->data)[2] = 300000;
*out_garray_ad = g_array_new (FALSE, FALSE, sizeof (gdouble));
g_array_set_size (*out_garray_ad, 3);
- ((gdouble *) (*out_garray_ad)->data)[0] = 1000.0;
- ((gdouble *) (*out_garray_ad)->data)[1] = 2000.0;
- ((gdouble *) (*out_garray_ad)->data)[2] = 3000.0;
+ ((gdouble *) (*out_garray_ad)->data)[0] = 10000.0;
+ ((gdouble *) (*out_garray_ad)->data)[1] = 20000.0;
+ ((gdouble *) (*out_garray_ad)->data)[2] = 30000.0;
*out_gptrarray_as = g_ptr_array_new ();
- g_ptr_array_add (*out_gptrarray_as, "100");
- g_ptr_array_add (*out_gptrarray_as, "200");
- g_ptr_array_add (*out_gptrarray_as, "300");
+ g_ptr_array_add (*out_gptrarray_as, "1000");
+ g_ptr_array_add (*out_gptrarray_as, "2000");
+ g_ptr_array_add (*out_gptrarray_as, "3000");
+
+ *out_other_gptrarray_as = g_ptr_array_new ();
+ g_ptr_array_add (*out_other_gptrarray_as, g_strdup ("100"));
+ g_ptr_array_add (*out_other_gptrarray_as, g_strdup ("200"));
+ g_ptr_array_add (*out_other_gptrarray_as, g_strdup ("300"));
*out_gbytearray_ay = g_byte_array_new ();
g_byte_array_set_size (*out_gbytearray_ay, 3);
diff --git a/src/myfrobnicator.h b/src/myfrobnicator.h
index b299b69..43c1901 100644
--- a/src/myfrobnicator.h
+++ b/src/myfrobnicator.h
@@ -126,6 +126,7 @@ void my_frobnicator_return_arrays (MyFrobnicator *frobnicator,
GArray **out_garray_ai,
GArray **out_garray_ad,
GPtrArray **out_gptrarray_as,
+ GPtrArray **out_other_gptrarray_as,
GByteArray **out_gbytearray_ay,
gint **out_carray_ai,
guint *out_carray_ai_len,
diff --git a/src/test.c b/src/test.c
index 191597f..1893f4d 100644
--- a/src/test.c
+++ b/src/test.c
@@ -32,25 +32,30 @@
static GMainLoop *loop;
static GMainLoop *thread_loop;
-static MyFrobnicator *obj;
+static GDBusConnection *connection;
+static MyFrobnicator *frobnicator;
+static guint frobnicator_registration_id;
static gboolean just_serve = FALSE;
static void
-on_bus_acquired (GDBusConnection *connection,
+on_bus_acquired (GDBusConnection *_connection,
const gchar *name,
gpointer user_data)
{
GError *error;
+ connection = _connection;
+
error = NULL;
- g_dbus_connection_register_gobject (connection,
- G_OBJECT (obj),
- "/org/My/Frobnicator",
- NULL, /* user_data */
- NULL, /* GDestroynotify */
- &error);
+ frobnicator_registration_id = g_dbus_connection_register_gobject (connection,
+ G_OBJECT (frobnicator),
+ "/org/My/Frobnicator",
+ NULL, /* user_data */
+ NULL, /* GDestroynotify */
+ &error);
g_assert_no_error (error);
+ g_assert_cmpint (frobnicator_registration_id, >, 0);
}
static void
@@ -290,14 +295,15 @@ run_test (GDBusConnection *connection)
"org.MyProject.Frobnicator",
"ReturnArrays",
NULL,
- G_VARIANT_TYPE ("(aiadasayaiasas)"),
+ G_VARIANT_TYPE ("(aiadasasayaiasas)"),
G_DBUS_CALL_FLAGS_NONE,
-1,
NULL, /* GCancellable */
&error);
g_assert_no_error (error);
- other = g_variant_new_parsed ("([10000, 20000, 30000], "
- " [1000.0, 2000.0, 3000.0], "
+ other = g_variant_new_parsed ("([100000, 200000, 300000], "
+ " [10000.0, 20000.0, 30000.0], "
+ " ['1000', '2000', '3000'], "
" ['100', '200', '300'], "
" [byte 10, 20, 30], "
" [1, 2, 3], "
@@ -426,7 +432,7 @@ main (gint argc, gchar *argv[])
loop = g_main_loop_new (NULL, FALSE);
- obj = my_frobnicator_new ();
+ frobnicator = my_frobnicator_new ();
owner_id = g_bus_own_name (G_BUS_TYPE_SESSION,
"org.My.Service",
@@ -442,8 +448,12 @@ main (gint argc, gchar *argv[])
g_main_loop_run (loop);
+ g_assert_cmpint (frobnicator_registration_id, >, 0);
+ g_dbus_connection_unregister_object (connection, frobnicator_registration_id);
+ frobnicator_registration_id = 0;
+
g_main_loop_unref (loop);
- g_object_unref (obj);
+ g_object_unref (frobnicator);
return 0;
}