From 2b9462f172f2410b9a24fa06d345126a645b75cd Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Wed, 30 Mar 2016 12:00:58 +0200 Subject: [PATCH 1/9] exported-object: reorder fields in NMExportedObjectPrivate struct For now, this doesn't change the overall size of the struct. But with the next commits this ordering allows tighter packing. --- src/nm-exported-object.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/nm-exported-object.c b/src/nm-exported-object.c index 38a6271cb7..1518b492bc 100644 --- a/src/nm-exported-object.c +++ b/src/nm-exported-object.c @@ -39,16 +39,17 @@ G_DEFINE_ABSTRACT_TYPE_WITH_CODE (NMExportedObject, nm_exported_object, G_TYPE_D ) typedef struct { - GSList *interfaces; - NMBusManager *bus_mgr; char *path; GHashTable *pending_notifies; + + GSList *interfaces; + guint notify_idle_id; #ifdef _ASSERT_NO_EARLY_EXPORT - gboolean _constructed; + bool _constructed:1; #endif } NMExportedObjectPrivate; From efae518e3ce91a34ba5e825b0215b3b7978a4e4f Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Wed, 30 Mar 2016 11:55:50 +0200 Subject: [PATCH 2/9] exported-object: sort fields in emitted "property-changed" data variant The fields of the variant should have a consistent sort order. --- src/nm-exported-object.c | 42 +++++++++++++++++++++++++++++++--------- 1 file 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; } From 6a42e18d53eaa8a643a5082041ecc3f4849f6192 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Wed, 30 Mar 2016 12:28:28 +0200 Subject: [PATCH 3/9] exported-object: refactor list of interfaces from GSList to an array NMExportedObject is the center of every D-Bus exported object in NetworkManager's core. It makes sense to optimize it. Transform the GSList of interfaces to be a array. The array is still allocated via the slice allocator (as we expect that there are only few types in the list). This saves the overhead to allocate a GSList item for each entry. Another advantage is that the interfaces list is now strongly typed instead of an opaque data pointer. --- src/nm-exported-object.c | 109 ++++++++++++++++++++++++--------------- src/nm-exported-object.h | 1 - 2 files changed, 66 insertions(+), 44 deletions(-) diff --git a/src/nm-exported-object.c b/src/nm-exported-object.c index aceaf11dfc..cff227aa41 100644 --- a/src/nm-exported-object.c +++ b/src/nm-exported-object.c @@ -38,13 +38,18 @@ G_DEFINE_ABSTRACT_TYPE_WITH_CODE (NMExportedObject, nm_exported_object, G_TYPE_D prefix_counters = g_hash_table_new (g_str_hash, g_str_equal); ) +typedef struct { + GDBusInterfaceSkeleton *interface; +} InterfaceData; + typedef struct { NMBusManager *bus_mgr; char *path; GHashTable *pending_notifies; - GSList *interfaces; + InterfaceData *interfaces; + guint num_interfaces; guint notify_idle_id; @@ -148,17 +153,18 @@ nm_exported_object_signal_hook (GSignalInvocationHint *ihint, NMExportedObjectPrivate *priv; GSignalQuery *signal_info = data; GDBusInterfaceSkeleton *interface = NULL; - GSList *iter; GValue *dbus_param_values; - int i; + guint i; priv = NM_EXPORTED_OBJECT_GET_PRIVATE (self); if (!priv->path) return TRUE; - for (iter = priv->interfaces; iter; iter = iter->next) { - if (g_type_is_a (G_OBJECT_TYPE (iter->data), signal_info->itype)) { - interface = G_DBUS_INTERFACE_SKELETON (iter->data); + for (i = 0; i < priv->num_interfaces; i++) { + InterfaceData *ifdata = &priv->interfaces[i]; + + if (g_type_is_a (G_OBJECT_TYPE (ifdata->interface), signal_info->itype)) { + interface = ifdata->interface; break; } } @@ -453,9 +459,10 @@ nm_exported_object_create_skeletons (NMExportedObject *self, GObjectClass *object_class; NMExportedObjectClassInfo *classinfo; GSList *iter; - GDBusInterfaceSkeleton *interface; const NMExportedObjectDBusMethodImpl *methods; - guint methods_len; + guint i, methods_len; + guint num_interfaces; + InterfaceData *interfaces; classinfo = g_type_get_qdata (object_type, nm_exported_object_class_info_quark ()); if (!classinfo) @@ -467,17 +474,30 @@ nm_exported_object_create_skeletons (NMExportedObject *self, methods = classinfo->methods->len ? &g_array_index (classinfo->methods, NMExportedObjectDBusMethodImpl, 0) : NULL; methods_len = classinfo->methods->len; - for (iter = classinfo->skeleton_types; iter; iter = iter->next) { - interface = nm_exported_object_skeleton_create (GPOINTER_TO_SIZE (iter->data), - object_class, - methods, - methods_len, - (GObject *) self); + num_interfaces = g_slist_length (classinfo->skeleton_types); + g_return_if_fail (num_interfaces > 0); - g_dbus_object_skeleton_add_interface ((GDBusObjectSkeleton *) self, interface); + interfaces = g_slice_alloc (sizeof (InterfaceData) * (num_interfaces + priv->num_interfaces)); - priv->interfaces = g_slist_prepend (priv->interfaces, interface); + for (i = num_interfaces, iter = classinfo->skeleton_types; iter; iter = iter->next) { + InterfaceData *ifdata = &interfaces[--i]; + + ifdata->interface = nm_exported_object_skeleton_create (GPOINTER_TO_SIZE (iter->data), + object_class, + methods, + methods_len, + (GObject *) self); + g_dbus_object_skeleton_add_interface ((GDBusObjectSkeleton *) self, ifdata->interface); } + nm_assert (i == 0); + + if (priv->num_interfaces > 0) { + memcpy (&interfaces[num_interfaces], priv->interfaces, sizeof (InterfaceData) * priv->num_interfaces); + g_slice_free1 (sizeof (InterfaceData) * priv->num_interfaces, priv->interfaces); + } + + priv->num_interfaces = num_interfaces + priv->num_interfaces; + priv->interfaces = interfaces; } void @@ -506,16 +526,22 @@ static void nm_exported_object_destroy_skeletons (NMExportedObject *self) { NMExportedObjectPrivate *priv = NM_EXPORTED_OBJECT_GET_PRIVATE (self); + guint n; - g_return_if_fail (priv->interfaces); + g_return_if_fail (priv->num_interfaces > 0); + nm_assert (priv->interfaces); - while (priv->interfaces) { - GDBusInterfaceSkeleton *interface = priv->interfaces->data; + n = priv->num_interfaces; - priv->interfaces = g_slist_delete_link (priv->interfaces, priv->interfaces); - g_dbus_object_skeleton_remove_interface ((GDBusObjectSkeleton *) self, interface); - nm_exported_object_skeleton_release (interface); + while (priv->num_interfaces > 0) { + InterfaceData *ifdata = &priv->interfaces[--priv->num_interfaces]; + + g_dbus_object_skeleton_remove_interface ((GDBusObjectSkeleton *) self, ifdata->interface); + nm_exported_object_skeleton_release (ifdata->interface); } + + g_slice_free1 (sizeof (InterfaceData) * n, priv->interfaces); + priv->interfaces = NULL; } /** @@ -664,30 +690,26 @@ nm_exported_object_unexport (NMExportedObject *self) } } -GSList * -nm_exported_object_get_interfaces (NMExportedObject *self) +GDBusInterfaceSkeleton * +nm_exported_object_get_interface_by_type (NMExportedObject *self, GType interface_type) { NMExportedObjectPrivate *priv; + guint i; g_return_val_if_fail (NM_IS_EXPORTED_OBJECT (self), NULL); priv = NM_EXPORTED_OBJECT_GET_PRIVATE (self); g_return_val_if_fail (priv->path, NULL); - g_return_val_if_fail (priv->interfaces, NULL); + g_return_val_if_fail (priv->num_interfaces > 0, NULL); - return priv->interfaces; -} + nm_assert (priv->interfaces); -GDBusInterfaceSkeleton * -nm_exported_object_get_interface_by_type (NMExportedObject *self, GType interface_type) -{ - GSList *interfaces; + for (i = 0; i < priv->num_interfaces; i++) { + InterfaceData *ifdata = &priv->interfaces[i]; - interfaces = nm_exported_object_get_interfaces (self); - for (; interfaces; interfaces = interfaces->next) { - if (G_TYPE_CHECK_INSTANCE_TYPE (interfaces->data, interface_type)) - return interfaces->data; + if (G_TYPE_CHECK_INSTANCE_TYPE (ifdata->interface, interface_type)) + return ifdata->interface; } return NULL; } @@ -742,7 +764,6 @@ idle_emit_properties_changed (gpointer self) { NMExportedObjectPrivate *priv = NM_EXPORTED_OBJECT_GET_PRIVATE (self); gs_unref_variant GVariant *variant = NULL; - GSList *iter; GDBusInterfaceSkeleton *interface = NULL; guint signal_id = 0; GHashTableIter hash_iter; @@ -773,10 +794,12 @@ idle_emit_properties_changed (gpointer self) g_hash_table_remove_all (priv->pending_notifies); - for (iter = priv->interfaces; iter; iter = iter->next) { - signal_id = g_signal_lookup ("properties-changed", G_OBJECT_TYPE (iter->data)); + for (i = 0; i < priv->num_interfaces; i++) { + InterfaceData *ifdata = &priv->interfaces[i]; + + signal_id = g_signal_lookup ("properties-changed", G_OBJECT_TYPE (ifdata->interface)); if (signal_id != 0) { - interface = G_DBUS_INTERFACE_SKELETON (iter->data); + interface = ifdata->interface; break; } } @@ -819,9 +842,9 @@ nm_exported_object_notify (GObject *object, GParamSpec *pspec) GValue value = G_VALUE_INIT; const GVariantType *vtype; GVariant *variant; - GSList *iter; + guint i; - if (!priv->interfaces) + if (priv->num_interfaces == 0) return; for (type = G_OBJECT_TYPE (object); type; type = g_type_parent (type)) { @@ -843,8 +866,8 @@ nm_exported_object_notify (GObject *object, GParamSpec *pspec) g_object_get_property (G_OBJECT (object), pspec->name, &value); vtype = NULL; - for (iter = priv->interfaces; iter && !vtype; iter = iter->next) - vtype = find_dbus_property_type (iter->data, dbus_property_name); + for (i = 0; !vtype && i < priv->num_interfaces; i++) + vtype = find_dbus_property_type (priv->interfaces[i].interface, dbus_property_name); g_return_if_fail (vtype != NULL); variant = g_dbus_gvalue_to_gvariant (&value, vtype); diff --git a/src/nm-exported-object.h b/src/nm-exported-object.h index 88efb6fe98..c2c2280447 100644 --- a/src/nm-exported-object.h +++ b/src/nm-exported-object.h @@ -74,7 +74,6 @@ const char *nm_exported_object_export (NMExportedObject *self); const char *nm_exported_object_get_path (NMExportedObject *self); gboolean nm_exported_object_is_exported (NMExportedObject *self); void nm_exported_object_unexport (NMExportedObject *self); -GSList * nm_exported_object_get_interfaces (NMExportedObject *self); GDBusInterfaceSkeleton *nm_exported_object_get_interface_by_type (NMExportedObject *self, GType interface_type); void _nm_exported_object_clear_and_unexport (NMExportedObject **location); From 05d4faf3340fbcb9e4e1af5e98779b5dcaacb73f Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Wed, 30 Mar 2016 12:36:37 +0200 Subject: [PATCH 4/9] exported-object: cache signal-id for "property-changed" in InterfaceData Instead of looking up the signal-id every time, cache it. g_signal_lookup() requires a g_quark_try_string() and a lock a lock on a global mutex. Downside is that the InterfaceData structure grows. --- src/nm-exported-object.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/src/nm-exported-object.c b/src/nm-exported-object.c index cff227aa41..2bfface5ac 100644 --- a/src/nm-exported-object.c +++ b/src/nm-exported-object.c @@ -40,6 +40,7 @@ G_DEFINE_ABSTRACT_TYPE_WITH_CODE (NMExportedObject, nm_exported_object, G_TYPE_D typedef struct { GDBusInterfaceSkeleton *interface; + guint property_changed_signal_id; } InterfaceData; typedef struct { @@ -488,6 +489,8 @@ nm_exported_object_create_skeletons (NMExportedObject *self, methods_len, (GObject *) self); g_dbus_object_skeleton_add_interface ((GDBusObjectSkeleton *) self, ifdata->interface); + + ifdata->property_changed_signal_id = g_signal_lookup ("properties-changed", G_OBJECT_TYPE (ifdata->interface)); } nm_assert (i == 0); @@ -764,8 +767,7 @@ idle_emit_properties_changed (gpointer self) { NMExportedObjectPrivate *priv = NM_EXPORTED_OBJECT_GET_PRIVATE (self); gs_unref_variant GVariant *variant = NULL; - GDBusInterfaceSkeleton *interface = NULL; - guint signal_id = 0; + InterfaceData *ifdata = NULL; GHashTableIter hash_iter; GVariantBuilder notifies; guint i, n; @@ -795,15 +797,12 @@ idle_emit_properties_changed (gpointer self) g_hash_table_remove_all (priv->pending_notifies); for (i = 0; i < priv->num_interfaces; i++) { - InterfaceData *ifdata = &priv->interfaces[i]; - - signal_id = g_signal_lookup ("properties-changed", G_OBJECT_TYPE (ifdata->interface)); - if (signal_id != 0) { - interface = ifdata->interface; + if (priv->interfaces[i].property_changed_signal_id != 0) { + ifdata = &priv->interfaces[i]; break; } } - g_return_val_if_fail (signal_id != 0, FALSE); + g_return_val_if_fail (ifdata, FALSE); if (nm_logging_enabled (LOGL_DEBUG, LOGD_DBUS_PROPS)) { gs_free char *notification = g_variant_print (variant, TRUE); @@ -812,7 +811,7 @@ idle_emit_properties_changed (gpointer self) G_OBJECT_TYPE_NAME (self), self, notification); } - g_signal_emit (interface, signal_id, 0, variant); + g_signal_emit (ifdata->interface, ifdata->property_changed_signal_id, 0, variant); return FALSE; } From 429cc306074320761341146f5c2b0bb06de02d90 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Wed, 30 Mar 2016 13:20:44 +0200 Subject: [PATCH 5/9] exported-object: allocate temporary buffer in nm_exported_object_signal_hook() using alloca The size of GValue is about 24 bytes. The number of arguments for a signal is also small. No problem allocating the temporary buffer on the stack. --- src/nm-exported-object.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/nm-exported-object.c b/src/nm-exported-object.c index 2bfface5ac..f95f154dd3 100644 --- a/src/nm-exported-object.c +++ b/src/nm-exported-object.c @@ -171,7 +171,8 @@ nm_exported_object_signal_hook (GSignalInvocationHint *ihint, } g_return_val_if_fail (interface != NULL, TRUE); - dbus_param_values = g_new0 (GValue, n_param_values); + dbus_param_values = g_newa (GValue, n_param_values); + memset (dbus_param_values, 0, sizeof (GValue) * n_param_values); g_value_init (&dbus_param_values[0], G_OBJECT_TYPE (interface)); g_value_set_object (&dbus_param_values[0], interface); for (i = 1; i < n_param_values; i++) { @@ -193,7 +194,6 @@ nm_exported_object_signal_hook (GSignalInvocationHint *ihint, for (i = 0; i < n_param_values; i++) g_value_unset (&dbus_param_values[i]); - g_free (dbus_param_values); return TRUE; } From d4d72e2bda262c35cd93c661b718d2f8d7714865 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Wed, 30 Mar 2016 13:29:05 +0200 Subject: [PATCH 6/9] exported-object: inline find_dbus_property_type() in nm_exported_object_notify() nm_exported_object_notify() is not that large of a function. Having it all at one place makes it clearer what it does. --- src/nm-exported-object.c | 44 +++++++++++++++++----------------------- 1 file changed, 19 insertions(+), 25 deletions(-) diff --git a/src/nm-exported-object.c b/src/nm-exported-object.c index f95f154dd3..2a267406f8 100644 --- a/src/nm-exported-object.c +++ b/src/nm-exported-object.c @@ -815,22 +815,6 @@ idle_emit_properties_changed (gpointer self) return FALSE; } -static const GVariantType * -find_dbus_property_type (GDBusInterfaceSkeleton *skel, - const char *dbus_property_name) -{ - GDBusInterfaceInfo *iinfo; - int i; - - iinfo = g_dbus_interface_skeleton_get_info (skel); - for (i = 0; iinfo->properties[i]; i++) { - if (!strcmp (iinfo->properties[i]->name, dbus_property_name)) - return G_VARIANT_TYPE (iinfo->properties[i]->signature); - } - - return NULL; -} - static void nm_exported_object_notify (GObject *object, GParamSpec *pspec) { @@ -840,8 +824,7 @@ nm_exported_object_notify (GObject *object, GParamSpec *pspec) const char *dbus_property_name = NULL; GValue value = G_VALUE_INIT; const GVariantType *vtype; - GVariant *variant; - guint i; + guint i, j; if (priv->num_interfaces == 0) return; @@ -861,18 +844,29 @@ nm_exported_object_notify (GObject *object, GParamSpec *pspec) return; } + for (i = 0; i < priv->num_interfaces; i++) { + GDBusInterfaceSkeleton *skel = priv->interfaces[i].interface; + GDBusInterfaceInfo *iinfo; + + iinfo = g_dbus_interface_skeleton_get_info (skel); + for (j = 0; iinfo->properties[j]; j++) { + if (nm_streq (iinfo->properties[j]->name, dbus_property_name)) { + vtype = G_VARIANT_TYPE (iinfo->properties[j]->signature); + goto vtype_found; + } + } + } + g_return_if_reached (); + +vtype_found: g_value_init (&value, pspec->value_type); g_object_get_property (G_OBJECT (object), pspec->name, &value); - vtype = NULL; - for (i = 0; !vtype && i < priv->num_interfaces; i++) - vtype = find_dbus_property_type (priv->interfaces[i].interface, dbus_property_name); - g_return_if_fail (vtype != NULL); - - variant = g_dbus_gvalue_to_gvariant (&value, vtype); /* @dbus_property_name is inside classinfo and never freed, thus we don't clone it. * Also, we do a pointer, not string comparison. */ - g_hash_table_insert (priv->pending_notifies, (gpointer) dbus_property_name, variant); + g_hash_table_insert (priv->pending_notifies, + (gpointer) dbus_property_name, + g_dbus_gvalue_to_gvariant (&value, vtype)); g_value_unset (&value); if (!priv->notify_idle_id) From 61f3c9890f28f799aabbccb9ba6ffcf08cb49ee3 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Wed, 30 Mar 2016 16:50:38 +0200 Subject: [PATCH 7/9] exported-object: static variable prefix_counters from global scope to _create_export_path() --- src/nm-exported-object.c | 59 +++++++++++++++++++++++----------------- 1 file changed, 34 insertions(+), 25 deletions(-) diff --git a/src/nm-exported-object.c b/src/nm-exported-object.c index 2a267406f8..abdc547ee4 100644 --- a/src/nm-exported-object.c +++ b/src/nm-exported-object.c @@ -26,7 +26,6 @@ #include "nm-exported-object.h" #include "nm-bus-manager.h" -static GHashTable *prefix_counters; static gboolean quitting = FALSE; @@ -34,9 +33,7 @@ static gboolean quitting = FALSE; #define _ASSERT_NO_EARLY_EXPORT #endif -G_DEFINE_ABSTRACT_TYPE_WITH_CODE (NMExportedObject, nm_exported_object, G_TYPE_DBUS_OBJECT_SKELETON, - prefix_counters = g_hash_table_new (g_str_hash, g_str_equal); - ) +G_DEFINE_ABSTRACT_TYPE (NMExportedObject, nm_exported_object, G_TYPE_DBUS_OBJECT_SKELETON); typedef struct { GDBusInterfaceSkeleton *interface; @@ -547,6 +544,37 @@ nm_exported_object_destroy_skeletons (NMExportedObject *self) priv->interfaces = NULL; } +static char * +_create_export_path (NMExportedObjectClass *klass) +{ + const char *class_export_path, *p; + static GHashTable *prefix_counters; + guint *counter; + + class_export_path = klass->export_path; + + nm_assert (class_export_path); + + p = strchr (class_export_path, '%'); + if (p) { + if (G_UNLIKELY (!prefix_counters)) + prefix_counters = g_hash_table_new (g_str_hash, g_str_equal); + + g_assert (p[1] == 'u'); + g_assert (strchr (p + 1, '%') == NULL); + + counter = g_hash_table_lookup (prefix_counters, class_export_path); + if (!counter) { + counter = g_slice_new0 (guint); + g_hash_table_insert (prefix_counters, g_strdup (class_export_path), counter); + } + + return g_strdup_printf (class_export_path, (*counter)++); + } + + return g_strdup (class_export_path); +} + /** * nm_exported_object_export: * @self: an #NMExportedObject @@ -565,9 +593,7 @@ const char * nm_exported_object_export (NMExportedObject *self) { NMExportedObjectPrivate *priv; - const char *class_export_path, *p; GType type; - char *path; g_return_val_if_fail (NM_IS_EXPORTED_OBJECT (self), NULL); priv = NM_EXPORTED_OBJECT_GET_PRIVATE (self); @@ -584,31 +610,14 @@ nm_exported_object_export (NMExportedObject *self) g_return_val_if_reached (NULL); g_object_add_weak_pointer ((GObject *) priv->bus_mgr, (gpointer *) &priv->bus_mgr); - class_export_path = NM_EXPORTED_OBJECT_GET_CLASS (self)->export_path; - p = strchr (class_export_path, '%'); - if (p) { - guint *counter; - - g_return_val_if_fail (p[1] == 'u', NULL); - g_return_val_if_fail (strchr (p + 1, '%') == NULL, NULL); - - counter = g_hash_table_lookup (prefix_counters, class_export_path); - if (!counter) { - counter = g_new0 (guint, 1); - g_hash_table_insert (prefix_counters, g_strdup (class_export_path), counter); - } - - path = g_strdup_printf (class_export_path, (*counter)++); - } else - path = g_strdup (class_export_path); - type = G_OBJECT_TYPE (self); while (type != NM_TYPE_EXPORTED_OBJECT) { nm_exported_object_create_skeletons (self, type); type = g_type_parent (type); } - priv->path = path; + priv->path = _create_export_path (NM_EXPORTED_OBJECT_GET_CLASS (self)); + _LOGT ("export: \"%s\"", priv->path); g_dbus_object_skeleton_set_object_path (G_DBUS_OBJECT_SKELETON (self), priv->path); From 8fd3a2b8939be4c3195bede68a1b0b40cebe6ea7 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Wed, 30 Mar 2016 16:58:02 +0200 Subject: [PATCH 8/9] exported-object/trivial: move code --- src/nm-exported-object.c | 143 +++++++++++++++++++++------------------ 1 file changed, 78 insertions(+), 65 deletions(-) diff --git a/src/nm-exported-object.c b/src/nm-exported-object.c index abdc547ee4..7415348042 100644 --- a/src/nm-exported-object.c +++ b/src/nm-exported-object.c @@ -347,6 +347,8 @@ nm_exported_object_class_add_interface (NMExportedObjectClass *object_class, g_type_class_unref (dbus_object_class); } +/*****************************************************************************/ + /* "meta-marshaller" that receives the skeleton "handle-foo" signal, replaces * the skeleton object with an #NMExportedObject in the parameters, drops the * user_data parameter, and adds a "TRUE" return value (indicating to gdbus that @@ -575,6 +577,38 @@ _create_export_path (NMExportedObjectClass *klass) return g_strdup (class_export_path); } +/** + * nm_exported_object_get_path: + * @self: an #NMExportedObject + * + * Gets @self's D-Bus path. + * + * Returns: @self's D-Bus path, or %NULL if @self is not exported. + */ +const char * +nm_exported_object_get_path (NMExportedObject *self) +{ + g_return_val_if_fail (NM_IS_EXPORTED_OBJECT (self), NULL); + + return NM_EXPORTED_OBJECT_GET_PRIVATE (self)->path; +} + +/** + * nm_exported_object_is_exported: + * @self: an #NMExportedObject + * + * Checks if @self is exported + * + * Returns: %TRUE if @self is exported + */ +gboolean +nm_exported_object_is_exported (NMExportedObject *self) +{ + g_return_val_if_fail (NM_IS_EXPORTED_OBJECT (self), FALSE); + + return NM_EXPORTED_OBJECT_GET_PRIVATE (self)->path != NULL; +} + /** * nm_exported_object_export: * @self: an #NMExportedObject @@ -629,38 +663,6 @@ nm_exported_object_export (NMExportedObject *self) return priv->path; } -/** - * nm_exported_object_get_path: - * @self: an #NMExportedObject - * - * Gets @self's D-Bus path. - * - * Returns: @self's D-Bus path, or %NULL if @self is not exported. - */ -const char * -nm_exported_object_get_path (NMExportedObject *self) -{ - g_return_val_if_fail (NM_IS_EXPORTED_OBJECT (self), NULL); - - return NM_EXPORTED_OBJECT_GET_PRIVATE (self)->path; -} - -/** - * nm_exported_object_is_exported: - * @self: an #NMExportedObject - * - * Checks if @self is exported - * - * Returns: %TRUE if @self is exported - */ -gboolean -nm_exported_object_is_exported (NMExportedObject *self) -{ - g_return_val_if_fail (NM_IS_EXPORTED_OBJECT (self), FALSE); - - return NM_EXPORTED_OBJECT_GET_PRIVATE (self)->path != NULL; -} - /** * nm_exported_object_unexport: * @self: an #NMExportedObject @@ -702,6 +704,32 @@ nm_exported_object_unexport (NMExportedObject *self) } } +/*****************************************************************************/ + +void +_nm_exported_object_clear_and_unexport (NMExportedObject **location) +{ + NMExportedObject *self; + NMExportedObjectPrivate *priv; + + if (!location || !*location) + return; + + self = *location; + *location = NULL; + + g_return_if_fail (NM_IS_EXPORTED_OBJECT (self)); + + priv = NM_EXPORTED_OBJECT_GET_PRIVATE (self); + + if (priv->path) + nm_exported_object_unexport (self); + + g_object_unref (self); +} + +/*****************************************************************************/ + GDBusInterfaceSkeleton * nm_exported_object_get_interface_by_type (NMExportedObject *self, GType interface_type) { @@ -726,38 +754,15 @@ nm_exported_object_get_interface_by_type (NMExportedObject *self, GType interfac return NULL; } +/*****************************************************************************/ + void -_nm_exported_object_clear_and_unexport (NMExportedObject **location) +nm_exported_object_class_set_quitting (void) { - NMExportedObject *self; - NMExportedObjectPrivate *priv; - - if (!location || !*location) - return; - - self = *location; - *location = NULL; - - g_return_if_fail (NM_IS_EXPORTED_OBJECT (self)); - - priv = NM_EXPORTED_OBJECT_GET_PRIVATE (self); - - if (priv->path) - nm_exported_object_unexport (self); - - g_object_unref (self); + quitting = TRUE; } -static void -nm_exported_object_init (NMExportedObject *self) -{ - NMExportedObjectPrivate *priv = NM_EXPORTED_OBJECT_GET_PRIVATE (self); - - priv->pending_notifies = g_hash_table_new_full (g_direct_hash, - g_direct_equal, - NULL, - (GDestroyNotify) g_variant_unref); -} +/*****************************************************************************/ typedef struct { const char *property_name; @@ -882,6 +887,19 @@ vtype_found: priv->notify_idle_id = g_idle_add (idle_emit_properties_changed, object); } +/*****************************************************************************/ + +static void +nm_exported_object_init (NMExportedObject *self) +{ + NMExportedObjectPrivate *priv = NM_EXPORTED_OBJECT_GET_PRIVATE (self); + + priv->pending_notifies = g_hash_table_new_full (g_direct_hash, + g_direct_equal, + NULL, + (GDestroyNotify) g_variant_unref); +} + static void constructed (GObject *object) { @@ -933,9 +951,4 @@ nm_exported_object_class_init (NMExportedObjectClass *klass) object_class->dispose = nm_exported_object_dispose; } -void -nm_exported_object_class_set_quitting (void) -{ - quitting = TRUE; -} From 603e6dc006afffcfb01ecf30540aef5c5543547c Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Wed, 30 Mar 2016 16:59:12 +0200 Subject: [PATCH 9/9] exported-object: reorder includes --- src/nm-exported-object.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/nm-exported-object.c b/src/nm-exported-object.c index 7415348042..10f7d23fad 100644 --- a/src/nm-exported-object.c +++ b/src/nm-exported-object.c @@ -15,24 +15,24 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * Copyright 2014-2015 Red Hat, Inc. + * Copyright 2014-2016 Red Hat, Inc. */ #include "nm-default.h" +#include "nm-exported-object.h" + #include #include -#include "nm-exported-object.h" #include "nm-bus-manager.h" -static gboolean quitting = FALSE; - - #if NM_MORE_ASSERTS >= 2 #define _ASSERT_NO_EARLY_EXPORT #endif +static gboolean quitting = FALSE; + G_DEFINE_ABSTRACT_TYPE (NMExportedObject, nm_exported_object, G_TYPE_DBUS_OBJECT_SKELETON); typedef struct {