This is similar in concept to "realize", though semantics are a bit more open-ended:
And object might in some cases need a number of properties to be specified before it can be "used"/"started"/etc. This can't always be done via an open-ended new() function, the main example being objects that around created via the command-line by -object. To support these cases we allow a function, ->instance_init_completion, to be registered that will be called by the -object constructor, or can be called at the end of new() constructors and such. Signed-off-by: Michael Roth <mdr...@linux.vnet.ibm.com> --- include/qom/object.h | 19 +++++++++++++++++++ qom/object.c | 21 +++++++++++++++++++++ vl.c | 2 ++ 3 files changed, 42 insertions(+) diff --git a/include/qom/object.h b/include/qom/object.h index d0f99c5..86f1e2e 100644 --- a/include/qom/object.h +++ b/include/qom/object.h @@ -394,6 +394,11 @@ struct Object * @instance_init: This function is called to initialize an object. The parent * class will have already been initialized so the type is only responsible * for initializing its own members. + * @instance_init_completion: This function is used mainly cases where an + * object has been instantiated via the command-line, and is called once all + * properties specified via command-line have been set for the object. This + * is not called automatically, but manually via @object_init_completion once + * the processing of said properties is completed. * @instance_finalize: This function is called during object destruction. This * is called before the parent @instance_finalize function has been called. * An object should only free the members that are unique to its type in this @@ -429,6 +434,7 @@ struct TypeInfo size_t instance_size; void (*instance_init)(Object *obj); + void (*instance_init_completion)(Object *obj); void (*instance_finalize)(Object *obj); bool abstract; @@ -562,6 +568,19 @@ struct InterfaceClass Object *object_new(const char *typename); /** + * object_init_completion: + * @obj: The object to complete initialization of + * + * In cases where an object is instantiated from a command-line with a number + * of properties specified as parameters (generally via -object), or for cases + * where a new()/helper function is used to pass/set some minimal number of + * properties that are required prior to completion of object initialization, + * this function can be called to mark when that occurs to complete object + * initialization. + */ +void object_init_completion(Object *obj); + +/** * object_new_with_type: * @type: The type of the object to instantiate. * diff --git a/qom/object.c b/qom/object.c index 75e6aac..c932f64 100644 --- a/qom/object.c +++ b/qom/object.c @@ -50,6 +50,7 @@ struct TypeImpl void *class_data; void (*instance_init)(Object *obj); + void (*instance_init_completion)(Object *obj); void (*instance_finalize)(Object *obj); bool abstract; @@ -110,6 +111,7 @@ static TypeImpl *type_register_internal(const TypeInfo *info) ti->class_data = info->class_data; ti->instance_init = info->instance_init; + ti->instance_init_completion = info->instance_init_completion; ti->instance_finalize = info->instance_finalize; ti->abstract = info->abstract; @@ -422,6 +424,25 @@ Object *object_new(const char *typename) return object_new_with_type(ti); } + +static void object_init_completion_with_type(Object *obj, TypeImpl *ti) +{ + if (type_has_parent(ti)) { + object_init_completion_with_type(obj, type_get_parent(ti)); + } + + if (ti->instance_init_completion) { + ti->instance_init_completion(obj); + } +} + +void object_init_completion(Object *obj) +{ + TypeImpl *ti = type_get_by_name(object_get_class(obj)->type->name); + + object_init_completion_with_type(obj, ti); +} + Object *object_dynamic_cast(Object *obj, const char *typename) { if (obj && object_class_dynamic_cast(object_get_class(obj), typename)) { diff --git a/vl.c b/vl.c index 6e6225f..d454c86 100644 --- a/vl.c +++ b/vl.c @@ -2831,6 +2831,8 @@ static int object_create(QemuOpts *opts, void *opaque) object_property_add_child(container_get(object_get_root(), "/objects"), id, obj, NULL); + object_init_completion(obj); + return 0; } -- 1.7.9.5