Il 03/05/2013 18:03, Michael Roth ha scritto: > 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.
This seems a lot like a realize property that cannot be set back to false... Paolo > 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; > } > >