Message ID | 1367597032-28934-2-git-send-email-mdroth@linux.vnet.ibm.com |
---|---|
State | New |
Headers | show |
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 <mdroth@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; > } > >
On Mon, May 06, 2013 at 09:45:22AM +0200, Paolo Bonzini wrote: > 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... I seem to recall some other conditions like properties not being modifiable after being realized? In this case though I think event loops should be startable/stoppable via properties (post-migration, for instance, or maybe testing/debugging) with simple qom-set commands. Not too sure honestly, mainly I just recalled realize() being pushed down into DeviceState for specific reasons, and didn't want to confuse this with being the same thing (even though it does seem very similar). I'm not sure what the best approach is here. > > Paolo > > > Signed-off-by: Michael Roth <mdroth@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; > > } > > > > >
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; }
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 <mdroth@linux.vnet.ibm.com> --- include/qom/object.h | 19 +++++++++++++++++++ qom/object.c | 21 +++++++++++++++++++++ vl.c | 2 ++ 3 files changed, 42 insertions(+)