Commit 8a8ecc46 authored by Thomas Haller's avatar Thomas Haller

core: fix wrongly exporting object before instance is fully constructed

Exporting the object already in the *_init() function will later
break because the object is not yet fully initialized at that point.

Add a convenient flag so that the NMExportedObject parent implementation
automatically can export itself. This saves the derived class from
overwriting the constructed() method.

Also add an assertion to catch such bugs.
parent ae5cfba0
......@@ -104,8 +104,6 @@ nm_dhcp4_config_init (NMDhcp4Config *self)
{
NMDhcp4ConfigPrivate *priv = NM_DHCP4_CONFIG_GET_PRIVATE (self);
nm_exported_object_export (NM_EXPORTED_OBJECT (self));
priv->options = g_variant_new_array (G_VARIANT_TYPE ("{sv}"), NULL, 0);
g_variant_ref_sink (priv->options);
}
......@@ -145,6 +143,7 @@ nm_dhcp4_config_class_init (NMDhcp4ConfigClass *config_class)
g_type_class_add_private (config_class, sizeof (NMDhcp4ConfigPrivate));
exported_object_class->export_path = NM_DBUS_PATH "/DHCP4Config/%u";
exported_object_class->export_on_construction = TRUE;
/* virtual methods */
object_class->get_property = get_property;
......
......@@ -104,8 +104,6 @@ nm_dhcp6_config_init (NMDhcp6Config *self)
{
NMDhcp6ConfigPrivate *priv = NM_DHCP6_CONFIG_GET_PRIVATE (self);
nm_exported_object_export (NM_EXPORTED_OBJECT (self));
priv->options = g_variant_new_array (G_VARIANT_TYPE ("{sv}"), NULL, 0);
g_variant_ref_sink (priv->options);
}
......@@ -145,6 +143,7 @@ nm_dhcp6_config_class_init (NMDhcp6ConfigClass *config_class)
g_type_class_add_private (config_class, sizeof (NMDhcp6ConfigPrivate));
exported_object_class->export_path = NM_DBUS_PATH "/DHCP6Config/%u";
exported_object_class->export_on_construction = TRUE;
/* virtual methods */
object_class->get_property = get_property;
......
......@@ -29,6 +29,10 @@
static GHashTable *prefix_counters;
#if NM_MORE_ASSERTS >= 2
#define _ASSERT_NO_EARLY_EXPORT
#endif
G_DEFINE_ABSTRACT_TYPE_WITH_CODE (NMExportedObject, nm_exported_object, G_TYPE_OBJECT,
prefix_counters = g_hash_table_new (g_str_hash, g_str_equal);
)
......@@ -41,6 +45,10 @@ typedef struct {
GVariantBuilder pending_notifies;
guint notify_idle_id;
#ifdef _ASSERT_NO_EARLY_EXPORT
gboolean _constructed;
#endif
} NMExportedObjectPrivate;
#define NM_EXPORTED_OBJECT_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_EXPORTED_OBJECT, NMExportedObjectPrivate))
......@@ -490,6 +498,10 @@ nm_exported_object_export (NMExportedObject *self)
g_return_val_if_fail (!priv->path, priv->path);
g_return_val_if_fail (!priv->bus_mgr, NULL);
#ifdef _ASSERT_NO_EARLY_EXPORT
nm_assert (priv->_constructed);
#endif
class_export_path = NM_EXPORTED_OBJECT_GET_CLASS (self)->export_path;
p = strchr (class_export_path, '%');
if (p) {
......@@ -731,6 +743,23 @@ nm_exported_object_notify (GObject *object, GParamSpec *pspec)
priv->notify_idle_id = g_idle_add (idle_emit_properties_changed, object);
}
static void
constructed (GObject *object)
{
NMExportedObjectClass *klass;
G_OBJECT_CLASS (nm_exported_object_parent_class)->constructed (object);
#ifdef _ASSERT_NO_EARLY_EXPORT
NM_EXPORTED_OBJECT_GET_PRIVATE (object)->_constructed = TRUE;
#endif
klass = NM_EXPORTED_OBJECT_GET_CLASS (object);
if (klass->export_on_construction)
nm_exported_object_export ((NMExportedObject *) object);
}
static void
nm_exported_object_dispose (GObject *object)
{
......@@ -752,6 +781,7 @@ nm_exported_object_class_init (NMExportedObjectClass *klass)
g_type_class_add_private (object_class, sizeof (NMExportedObjectPrivate));
object_class->constructed = constructed;
object_class->notify = nm_exported_object_notify;
object_class->dispose = nm_exported_object_dispose;
}
......@@ -40,6 +40,7 @@ typedef struct {
GObjectClass parent;
const char *export_path;
char export_on_construction;
} NMExportedObjectClass;
GType nm_exported_object_get_type (void);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment