diff options
author | Thomas Haller <thaller@redhat.com> | 2016-03-30 11:55:50 +0200 |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2016-04-01 08:58:18 +0200 |
commit | efae518e3ce91a34ba5e825b0215b3b7978a4e4f (patch) | |
tree | f35c872389eba5d9276d891e3618dbf3e9df4b7c /src/nm-exported-object.c | |
parent | 2b9462f172f2410b9a24fa06d345126a645b75cd (diff) | |
download | NetworkManager-efae518e3ce91a34ba5e825b0215b3b7978a4e4f.tar.gz |
exported-object: sort fields in emitted "property-changed" data variant
The fields of the variant should have a consistent sort order.
Diffstat (limited to 'src/nm-exported-object.c')
-rw-r--r-- | src/nm-exported-object.c | 42 |
1 files changed, 33 insertions, 9 deletions
diff --git a/src/nm-exported-object.c b/src/nm-exported-object.c index 1518b492bc..aceaf11dfc 100644 --- a/src/nm-exported-object.c +++ b/src/nm-exported-object.c @@ -725,27 +725,53 @@ nm_exported_object_init (NMExportedObject *self) (GDestroyNotify) g_variant_unref); } +typedef struct { + const char *property_name; + GVariant *variant; +} PendingNotifiesItem; + +static int +_sort_pending_notifies (gconstpointer a, gconstpointer b, gpointer user_data) +{ + return strcmp (((const PendingNotifiesItem *) a)->property_name, + ((const PendingNotifiesItem *) b)->property_name); +} + static gboolean idle_emit_properties_changed (gpointer self) { NMExportedObjectPrivate *priv = NM_EXPORTED_OBJECT_GET_PRIVATE (self); - GVariant *variant; + gs_unref_variant GVariant *variant = NULL; GSList *iter; GDBusInterfaceSkeleton *interface = NULL; guint signal_id = 0; GHashTableIter hash_iter; - const char *dbus_property_name; GVariantBuilder notifies; + guint i, n; + PendingNotifiesItem *values; priv->notify_idle_id = 0; - g_variant_builder_init (¬ifies, G_VARIANT_TYPE_VARDICT); + + n = g_hash_table_size (priv->pending_notifies); + g_return_val_if_fail (n > 0, FALSE); + + values = g_alloca (sizeof (values[0]) * n); + + i = 0; g_hash_table_iter_init (&hash_iter, priv->pending_notifies); - while (g_hash_table_iter_next (&hash_iter, (gpointer) &dbus_property_name, (gpointer) &variant)) - g_variant_builder_add (¬ifies, "{sv}", dbus_property_name, variant); + while (g_hash_table_iter_next (&hash_iter, (gpointer) &values[i].property_name, (gpointer) &values[i].variant)) + i++; + nm_assert (i == n); + + g_qsort_with_data (values, n, sizeof (values[0]), _sort_pending_notifies, NULL); + + g_variant_builder_init (¬ifies, G_VARIANT_TYPE_VARDICT); + for (i = 0; i < n; i++) + g_variant_builder_add (¬ifies, "{sv}", values[i].property_name, values[i].variant); + variant = g_variant_ref_sink (g_variant_builder_end (¬ifies)); + g_hash_table_remove_all (priv->pending_notifies); - variant = g_variant_builder_end (¬ifies); - g_variant_ref_sink (variant); for (iter = priv->interfaces; iter; iter = iter->next) { signal_id = g_signal_lookup ("properties-changed", G_OBJECT_TYPE (iter->data)); @@ -764,8 +790,6 @@ idle_emit_properties_changed (gpointer self) } g_signal_emit (interface, signal_id, 0, variant); - g_variant_unref (variant); - return FALSE; } |