exported-object: set object path after skeleton creation
authorBeniamino Galvani <bgalvani@redhat.com>
Thu, 11 Feb 2016 10:58:51 +0000 (11:58 +0100)
committerThomas Haller <thaller@redhat.com>
Thu, 11 Feb 2016 11:55:21 +0000 (12:55 +0100)
When exporting an object, we first set the object path and then create
GDBus interface skeletons. While doing this, a signal can be generated
[1] and then nm_exported_object_signal_hook() can trigger the failed
assertion "interface != NULL" because the object is already exported
(priv->path != NULL) but the interface has not been registered yet.

To fix this, set the object path only after skeletons have been
created.

[1] This happens here every time I disable networking and restart NM:
    #0  _g_log_abort (libglib-2.0.so.0)
    #1  g_log (libglib-2.0.so.0)
    #2  nm_exported_object_signal_hook (NetworkManager)
    #3  signal_emit_unlocked_R (libgobject-2.0.so.0)
    #4  g_signal_emit_valist (libgobject-2.0.so.0)
    #5  g_signal_emit (libgobject-2.0.so.0)
    #6  set_state (NetworkManager)
    #7  nm_manager_update_state (NetworkManager)
    #8  get_property (NetworkManager)
    #9  object_get_property (libgobject-2.0.so.0)
    #10 on_source_notify (libgobject-2.0.so.0)
    #11 g_object_bind_property_full (libgobject-2.0.so.0)
    #12 g_object_bind_property (libgobject-2.0.so.0)
    #13 nm_exported_object_skeleton_create (NetworkManager)
    #14 nm_exported_object_create_skeletons (NetworkManager)
    #15 nm_exported_object_export (NetworkManager)
    #16 nm_manager_setup (NetworkManager)
    #17 main (NetworkManager)
    #18 __libc_start_main (libc.so.6)
    #19 _start (NetworkManager)

https://mail.gnome.org/archives/networkmanager-list/2016-February/msg00041.html

src/nm-exported-object.c

index ca3187e..8155bab 100644 (file)
@@ -538,6 +538,7 @@ 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);
@@ -568,12 +569,9 @@ nm_exported_object_export (NMExportedObject *self)
                        g_hash_table_insert (prefix_counters, g_strdup (class_export_path), counter);
                }
 
-               priv->path = g_strdup_printf (class_export_path, (*counter)++);
+               path = g_strdup_printf (class_export_path, (*counter)++);
        } else
-               priv->path = g_strdup (class_export_path);
-
-       _LOGT ("export: \"%s\"", priv->path);
-       g_dbus_object_skeleton_set_object_path (G_DBUS_OBJECT_SKELETON (self), priv->path);
+               path = g_strdup (class_export_path);
 
        type = G_OBJECT_TYPE (self);
        while (type != NM_TYPE_EXPORTED_OBJECT) {
@@ -581,6 +579,10 @@ nm_exported_object_export (NMExportedObject *self)
                type = g_type_parent (type);
        }
 
+       priv->path = path;
+       _LOGT ("export: \"%s\"", priv->path);
+       g_dbus_object_skeleton_set_object_path (G_DBUS_OBJECT_SKELETON (self), priv->path);
+
        /* Important: priv->path and priv->interfaces must not change while
         * the object is registered. */