[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[RFC PATCH 02/40] qom: Introduce class_late_init
From: |
Richard Henderson |
Subject: |
[RFC PATCH 02/40] qom: Introduce class_late_init |
Date: |
Tue, 3 Jan 2023 10:16:08 -0800 |
Create a new class initialization hook, to be called immediately
before creation of the first instance. Most class initialization
happens quite early, which makes interaction between classes
difficult. E.g. cpu objects often depend on the accellerator,
or the global properties coming from the command-line.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
include/qom/object.h | 4 ++++
qom/object.c | 55 +++++++++++++++++++++++++++++++++++++-------
2 files changed, 51 insertions(+), 8 deletions(-)
diff --git a/include/qom/object.h b/include/qom/object.h
index ef7258a5e1..86958abe15 100644
--- a/include/qom/object.h
+++ b/include/qom/object.h
@@ -402,6 +402,9 @@ struct Object
* parent class initialization has occurred, but before the class itself
* is initialized. This is the function to use to undo the effects of
* memcpy from the parent class to the descendants.
+ * @class_late_init: This function is called for all base classes just
+ * before the first object is created. This is the function to use to
+ * apply properties (which are interpreted quite late).
* @class_data: Data to pass to the @class_init,
* @class_base_init. This can be useful when building dynamic
* classes.
@@ -425,6 +428,7 @@ struct TypeInfo
void (*class_init)(ObjectClass *klass, void *data);
void (*class_base_init)(ObjectClass *klass, void *data);
+ bool (*class_late_init)(ObjectClass *klass, Error **errp);
void *class_data;
InterfaceInfo *interfaces;
diff --git a/qom/object.c b/qom/object.c
index e25f1e96db..82a5c7d36e 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -56,6 +56,7 @@ struct TypeImpl
void (*class_init)(ObjectClass *klass, void *data);
void (*class_base_init)(ObjectClass *klass, void *data);
+ bool (*class_late_init)(ObjectClass *klass, Error **errp);
void *class_data;
@@ -64,6 +65,7 @@ struct TypeImpl
void (*instance_finalize)(Object *obj);
bool abstract;
+ bool object_created;
const char *parent;
TypeImpl *parent_type;
@@ -121,6 +123,7 @@ static TypeImpl *type_new(const TypeInfo *info)
ti->class_init = info->class_init;
ti->class_base_init = info->class_base_init;
+ ti->class_late_init = info->class_late_init;
ti->class_data = info->class_data;
ti->instance_init = info->instance_init;
@@ -367,6 +370,26 @@ static void type_initialize(TypeImpl *ti)
}
}
+static bool type_late_initialize(TypeImpl *ti, ObjectClass *cls, Error **errp)
+{
+ TypeImpl *pi = type_get_parent(ti);
+ if (pi && !type_late_initialize(pi, cls, errp)) {
+ return false;
+ }
+
+ for (GSList *e = ti->class->interfaces; e ; e = e->next) {
+ InterfaceClass *ic = e->data;
+ if (!type_late_initialize(ic->interface_type, cls, errp)) {
+ return false;
+ }
+ }
+
+ if (ti->class_late_init) {
+ return ti->class_late_init(cls, errp);
+ }
+ return true;
+}
+
static void object_init_with_type(Object *obj, TypeImpl *ti)
{
if (type_has_parent(ti)) {
@@ -502,7 +525,8 @@ static void object_class_property_init_all(Object *obj)
}
}
-static void object_initialize_with_type(Object *obj, size_t size, TypeImpl
*type)
+static bool object_initialize_with_type(Object *obj, size_t size,
+ TypeImpl *type, Error **errp)
{
type_initialize(type);
@@ -510,6 +534,13 @@ static void object_initialize_with_type(Object *obj,
size_t size, TypeImpl *type
g_assert(type->abstract == false);
g_assert(size >= type->instance_size);
+ if (!type->object_created) {
+ type->object_created = true;
+ if (!type_late_initialize(type, type->class, errp)) {
+ return false;
+ }
+ }
+
memset(obj, 0, type->instance_size);
obj->class = type->class;
object_ref(obj);
@@ -518,6 +549,7 @@ static void object_initialize_with_type(Object *obj, size_t
size, TypeImpl *type
NULL, object_property_free);
object_init_with_type(obj, type);
object_post_init_with_type(obj, type);
+ return true;
}
void object_initialize(void *data, size_t size, const char *typename)
@@ -540,7 +572,7 @@ void object_initialize(void *data, size_t size, const char
*typename)
abort();
}
- object_initialize_with_type(data, size, type);
+ object_initialize_with_type(data, size, type, &error_fatal);
}
bool object_initialize_child_with_props(Object *parentobj,
@@ -712,7 +744,7 @@ typedef union {
} qemu_max_align_t;
#endif
-static Object *object_new_with_type(Type type)
+static Object *object_new_with_type(Type type, Error **errp)
{
Object *obj;
size_t size, align;
@@ -736,22 +768,25 @@ static Object *object_new_with_type(Type type)
obj_free = qemu_vfree;
}
- object_initialize_with_type(obj, size, type);
- obj->free = obj_free;
+ if (!object_initialize_with_type(obj, size, type, errp)) {
+ obj_free(obj);
+ return NULL;
+ }
+ obj->free = obj_free;
return obj;
}
Object *object_new_with_class(ObjectClass *klass)
{
- return object_new_with_type(klass->type);
+ return object_new_with_type(klass->type, &error_fatal);
}
Object *object_new(const char *typename)
{
TypeImpl *ti = type_get_by_name(typename);
- return object_new_with_type(ti);
+ return object_new_with_type(ti, &error_fatal);
}
@@ -792,7 +827,11 @@ Object *object_new_with_propv(const char *typename,
error_setg(errp, "object type '%s' is abstract", typename);
return NULL;
}
- obj = object_new_with_type(klass->type);
+
+ obj = object_new_with_type(klass->type, errp);
+ if (!obj) {
+ return NULL;
+ }
if (!object_set_propv(obj, errp, vargs)) {
goto error;
--
2.34.1
- [RFC PATCH 16/40] target/arm: Represent the entire MPIDR_EL1, (continued)
[RFC PATCH 18/40] target/arm: Create cpreg definition functions with GHashTable arg, Richard Henderson, 2023/01/03
[RFC PATCH 05/40] target/arm: Create arm_cpu_register_parent, Richard Henderson, 2023/01/03
[RFC PATCH 07/40] target/arm: Create TYPE_ARM_V7M_CPU, Richard Henderson, 2023/01/03
[RFC PATCH 02/40] qom: Introduce class_late_init,
Richard Henderson <=
[RFC PATCH 08/40] target/arm: Pass ARMCPUClass to ARMCPUInfo.class_init, Richard Henderson, 2023/01/03
[RFC PATCH 14/40] target/arm: Rename arm_cpu_mp_affinity, Richard Henderson, 2023/01/03
[RFC PATCH 10/40] target/arm: Copy dtb_compatible from ARMCPUClass, Richard Henderson, 2023/01/03
[RFC PATCH 13/40] hw/arm/bcm2836: Set mp-affinity property in realize, Richard Henderson, 2023/01/03
[RFC PATCH 15/40] target/arm: Create arm_cpu_mp_affinity, Richard Henderson, 2023/01/03