On Mon, 29 Jun 2026 at 09:18, Akihiko Odaki <[email protected]> wrote: > > The distinction of instantiation and realization was vague in the old > documentation so this change clarifies it. > > The old documentation said: > > The former may not fail (and must not abort or exit, since it is > > called during device introspection already), and the latter may return > > error information to the caller and must be re-entrant. > > Trivial field initializations should go into #TypeInfo.instance_init. > > Operations depending on @props static properties should go into > > @realize. > > The first problem with the old documentation is that it is unclear what > "trivial field initializations" means and why triviality makes > initialization appropriate for #TypeInfo.instance_init. Another problem > is that the documentation is not comprehensive enough; for example, it > mentions @props static properties, but it does not say anything about > the other properties. > > The keys to distinguish instantiation and realization are property > setting and device introspection. The fact that property setting happens > after #TypeInfo.instance_init and before realization implies that > operations depending on properties should go into @realize. > > The fact that instantiation happens during device introspection but > realization does not implies: > - Instance properties should be added in #TypeInfo.instance_init. > - Instantiation must not have any side effect not contained in the > instance. > - Any operations without special requirements should go into @realize so > that they can be skipped during device introspection. > > Note these two facts to guide appropriate instantiation and realization.
Thanks for sending this. I think we definitely need to try to be clearer about what to do in instance_init and what to do in realize. > Signed-off-by: Akihiko Odaki <[email protected]> > * Realization > * ----------- > * > - * Devices are constructed in two stages: > - * > - * 1) object instantiation via object_initialize() and > - * 2) device realization via the #DeviceState.realized property > - * > - * The former may not fail (and must not abort or exit, since it is called > - * during device introspection already), and the latter may return error > - * information to the caller and must be re-entrant. > - * Trivial field initializations should go into #TypeInfo.instance_init. > - * Operations depending on @props static properties should go into @realize. > + * Devices are constructed in the following order: > + * > + * 1) #TypeInfo.instance_init > + * 2) pre-realize property value setting > + * 3) device realization via the #DeviceState.realized property > + * > + * #TypeInfo.instance_init may not fail, and realization may return > + * error information to the caller and must be re-entrant. I know this is in the existing text, but what do we mean by "must be re-entrant" here ? Does this mean "even if you return a failure from your realize method you must be able to handle the caller retrying the realize operation" ? (I'm not sure why that's a useful thing for the caller to be able to do...) I assume we don't mean "even if you successfully realize you must handle (and treat as a no-op) a second call to realize", because none of our devices do that :-) > + * #TypeInfo.instance_init should add instance properties but must not > + * have any side effect not contained in the instance, since it happens > + * during device introspection already. Any operations without special > + * requirements should go @realize so that they can be skipped during > + * device introspection. > * After successful realization, setting static properties will fail. > * > * As an interim step, the #DeviceState.realized property can also be > @@ -40,9 +43,8 @@ > * point in time will be deferred to machine creation, so that values > * set in @realize will not be introspectable beforehand. Therefore > * devices must not create children during @realize; they should > - * initialize them via object_initialize() in their own > - * #TypeInfo.instance_init and forward the realization events > - * appropriately. > + * initialize them via #TypeInfo.instance_init and forward the > + * realization events appropriately. This change doesn't seem to me to match the paragraph it's in. The intent of the paragraph is clearly "initialize child objects in your own instance_init method", so we want to say "in" the method. "via" here is for "how you do it"; we could make that say "initialize them (e.g. by calling object_initialize())" to be a bit clearer, something like: "Therefore devices must not create children during @realize; they should initialize them (e.g. by calling object_initialize_child()) in their own #TypeInfo.instance_init method, and then realize them (e.g. by calling qdev_realize()) in their own #DeviceClass.realize method." This whole paragraph is one of those we sometimes like to put in, which is sketching out a design idea or direction we have not actually managed to achieve. So it's part aspiration and part reality. In particular, the flat "must not create children during realize" statement clashes with "operations depending on static properties should go into realize", because occasionally we need to create or not create children based on the value of a property... thanks -- PMM
