All of lore.kernel.org
 help / color / mirror / Atom feed
From: Liviu Ionescu <ilg@livius.net>
To: QEMU Developers <Qemu-devel@nongnu.org>
Cc: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
Subject: [Qemu-devel] [RFC] QDev explicit constructors & destructors
Date: Mon, 15 Jun 2015 13:48:19 +0300	[thread overview]
Message-ID: <D23DADB3-0154-4EBE-9966-7AF30083D819@livius.net> (raw)

The .instance_init construction method available in the current QOM provides an equivalent of the C++ default constructor, that works just fine as long as there is no need to pass additional data to the construction logic.

One natural solution would be to add an explicit constructor, like in C++. 

Since C++ style multiple constructors can be folded into a single constructor using a pointer to a structure, one single callback would be enough to accommodate any construction logic.

The generic use case would look like this:

   DeviceState *mcu = qdev_alloc(NULL, TYPE_STM32F103RB);
   {
       qdev_prop_set_uint32(mcu, "param1", value1);  /* Optional */
       qdev_prop_set_uint32(mcu, "param2", value2);  /* Optional */
       qdev_construct(mcu, &constructor_data); /* the second pointer may be NULL */

       /* Set the board specific oscillator frequencies. */
       qdev_prop_set_uint32(mcu, "hse-freq-hz", 8000000); /* 8.0 MHz */
       qdev_prop_set_uint32(mcu, "lse-freq-hz", 32768); /* 32 KHz */
   }
   qdev_realize(mcu); /* QDev specific step */



The implementation requires only to: 

- add a "void (*construct)(DeviceState *dev, void *data)" member to the DeviceClass structure
- add a qdev_construct() function, that will run all these callbacks in 'parent first' order

For completeness, although it'll probably be used rarely, a destructor can also be implemented, by adding:

- a "void (*destruct)(DeviceState *dev)" member to the DeviceClass structure, and 
- a qdev_destruct(dev) function, that will run these callbacks in 'child first' order


Notes:
- except for setting statically defined properties, the object returned by qdev_alloc() but not yet constructed, **should not** be used for any other purposes
- inside the "construct" callback any number of children objects can be created, 
- an object is not considered properly constructed before all children object are constructed; in other words, the construct callback should not return as long as it includes objects allocated but not yet constructed
- passing constructor data can be done via standard properties and/or via the more generic 'data' structure, that will be passed up in the hierarchy (similar to the object state structure, each child in the hierarchy can extend this structure with additional members).
- after construction and before freezing the object with realize(), properties that were dynamically added during construction (like aliases to internal objects created during construction), can be set as usual.


Please note that these additions do not break any compatibility with existing code.

The two other functions mentioned are just aliases with more appropriate names for qdev_create() (create is not accurate, since the object is not yet ready to use) and qdev_init_nofail() (this name is deprecated, it is not calling init but realize, and the nofail is confusing, it not only fail, it even exits).


Regards,

Liviu

             reply	other threads:[~2015-06-15 10:48 UTC|newest]

Thread overview: 28+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-06-15 10:48 Liviu Ionescu [this message]
2015-06-15 11:13 ` [Qemu-devel] [RFC] QDev explicit constructors & destructors Liviu Ionescu
2015-06-15 13:35 ` Liviu Ionescu
2015-06-22 20:48   ` Liviu Ionescu
2015-06-23  7:47     ` Markus Armbruster
2015-06-23  9:12       ` Liviu Ionescu
2015-06-23 10:39   ` Andreas Färber
2015-06-23 12:58     ` Liviu Ionescu
2015-06-23 14:25       ` Andreas Färber
2015-06-23 16:15         ` Liviu Ionescu
2015-06-23 18:31         ` Peter Crosthwaite
2015-06-23 19:10           ` Liviu Ionescu
2015-06-23 20:57             ` Peter Crosthwaite
2015-06-23 21:24               ` Liviu Ionescu
2015-06-23 19:27           ` Andreas Färber
2015-06-23 20:10           ` Liviu Ionescu
2015-06-24  7:30             ` Liviu Ionescu
2015-06-24  8:29               ` Peter Crosthwaite
2015-06-24  9:29                 ` Liviu Ionescu
2015-06-24  9:51                   ` Paolo Bonzini
2015-06-24 13:41                     ` Andreas Färber
2015-06-24 13:50                   ` Andreas Färber
2015-06-24 14:11                     ` Liviu Ionescu
2015-06-24 14:18                       ` Andreas Färber
2015-06-24 14:39                         ` Liviu Ionescu
2015-06-24 14:41                           ` Andreas Färber
2015-06-24 20:14                       ` Liviu Ionescu
2015-06-24  8:51             ` Paolo Bonzini

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=D23DADB3-0154-4EBE-9966-7AF30083D819@livius.net \
    --to=ilg@livius.net \
    --cc=Qemu-devel@nongnu.org \
    --cc=peter.crosthwaite@xilinx.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.