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.
This commit is contained in:
@@ -104,8 +104,6 @@ nm_dhcp4_config_init (NMDhcp4Config *self)
|
|||||||
{
|
{
|
||||||
NMDhcp4ConfigPrivate *priv = NM_DHCP4_CONFIG_GET_PRIVATE (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);
|
priv->options = g_variant_new_array (G_VARIANT_TYPE ("{sv}"), NULL, 0);
|
||||||
g_variant_ref_sink (priv->options);
|
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));
|
g_type_class_add_private (config_class, sizeof (NMDhcp4ConfigPrivate));
|
||||||
|
|
||||||
exported_object_class->export_path = NM_DBUS_PATH "/DHCP4Config/%u";
|
exported_object_class->export_path = NM_DBUS_PATH "/DHCP4Config/%u";
|
||||||
|
exported_object_class->export_on_construction = TRUE;
|
||||||
|
|
||||||
/* virtual methods */
|
/* virtual methods */
|
||||||
object_class->get_property = get_property;
|
object_class->get_property = get_property;
|
||||||
|
@@ -104,8 +104,6 @@ nm_dhcp6_config_init (NMDhcp6Config *self)
|
|||||||
{
|
{
|
||||||
NMDhcp6ConfigPrivate *priv = NM_DHCP6_CONFIG_GET_PRIVATE (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);
|
priv->options = g_variant_new_array (G_VARIANT_TYPE ("{sv}"), NULL, 0);
|
||||||
g_variant_ref_sink (priv->options);
|
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));
|
g_type_class_add_private (config_class, sizeof (NMDhcp6ConfigPrivate));
|
||||||
|
|
||||||
exported_object_class->export_path = NM_DBUS_PATH "/DHCP6Config/%u";
|
exported_object_class->export_path = NM_DBUS_PATH "/DHCP6Config/%u";
|
||||||
|
exported_object_class->export_on_construction = TRUE;
|
||||||
|
|
||||||
/* virtual methods */
|
/* virtual methods */
|
||||||
object_class->get_property = get_property;
|
object_class->get_property = get_property;
|
||||||
|
@@ -29,6 +29,10 @@
|
|||||||
|
|
||||||
static GHashTable *prefix_counters;
|
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,
|
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);
|
prefix_counters = g_hash_table_new (g_str_hash, g_str_equal);
|
||||||
)
|
)
|
||||||
@@ -41,6 +45,10 @@ typedef struct {
|
|||||||
|
|
||||||
GVariantBuilder pending_notifies;
|
GVariantBuilder pending_notifies;
|
||||||
guint notify_idle_id;
|
guint notify_idle_id;
|
||||||
|
|
||||||
|
#ifdef _ASSERT_NO_EARLY_EXPORT
|
||||||
|
gboolean _constructed;
|
||||||
|
#endif
|
||||||
} NMExportedObjectPrivate;
|
} NMExportedObjectPrivate;
|
||||||
|
|
||||||
#define NM_EXPORTED_OBJECT_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_EXPORTED_OBJECT, 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->path, priv->path);
|
||||||
g_return_val_if_fail (!priv->bus_mgr, NULL);
|
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;
|
class_export_path = NM_EXPORTED_OBJECT_GET_CLASS (self)->export_path;
|
||||||
p = strchr (class_export_path, '%');
|
p = strchr (class_export_path, '%');
|
||||||
if (p) {
|
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);
|
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
|
static void
|
||||||
nm_exported_object_dispose (GObject *object)
|
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));
|
g_type_class_add_private (object_class, sizeof (NMExportedObjectPrivate));
|
||||||
|
|
||||||
|
object_class->constructed = constructed;
|
||||||
object_class->notify = nm_exported_object_notify;
|
object_class->notify = nm_exported_object_notify;
|
||||||
object_class->dispose = nm_exported_object_dispose;
|
object_class->dispose = nm_exported_object_dispose;
|
||||||
}
|
}
|
||||||
|
@@ -40,6 +40,7 @@ typedef struct {
|
|||||||
GObjectClass parent;
|
GObjectClass parent;
|
||||||
|
|
||||||
const char *export_path;
|
const char *export_path;
|
||||||
|
char export_on_construction;
|
||||||
} NMExportedObjectClass;
|
} NMExportedObjectClass;
|
||||||
|
|
||||||
GType nm_exported_object_get_type (void);
|
GType nm_exported_object_get_type (void);
|
||||||
|
Reference in New Issue
Block a user