diff options
author | David Zeuthen <davidz@redhat.com> | 2010-06-18 13:12:53 -0400 |
---|---|---|
committer | David Zeuthen <davidz@redhat.com> | 2010-06-18 13:12:53 -0400 |
commit | c035ac1bac4914794acc869acce9c1532434cb91 (patch) | |
tree | d87494faf2a95ce788058843f071573dec118012 | |
parent | 54050bb239a60f59c573314bc87fbf4c2c740f6f (diff) |
Updates
Signed-off-by: David Zeuthen <davidz@redhat.com>
-rw-r--r-- | src/gdbusgi.c | 144 | ||||
-rw-r--r-- | src/myfrobnicator.c | 27 | ||||
-rw-r--r-- | src/myfrobnicator.h | 1 | ||||
-rw-r--r-- | src/test.c | 36 |
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, @@ -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; } |