接前一篇文章: QEMU源码全解析23 —— QOM介绍(12)
本文内容参考:
《 QEMU /KVM》源码解析与应用 —— 李强,机械工业出版社
特此致谢!
前文依次讲解了 QEMU QOM的三部分:类型的构造(类型的注册)、类型的初始化、类对象的构造(对象的初始化)。虽然过程比较曲折复杂,但到这一步也只是构造出了对象并且调用了对象的初始化函数而已。但是,EduState中的数据并没有填充,此时的edu设备的状态并不是可用的。对设备而言,还需要设置其realized属性为true(真)才行。由此引出来本回的题目—— 属性。
属性
QOM实现了类似于C++的基于类的多态,一个对象按照继承体系,可以是Object、DeviceState、PCIDevice等等。在QOM中为了便于管理对象,还为每种类型以及对象增加了属性。类属性存在于ObjectClass的properties域中,这个域是在类型初始化函数type_initialize中构造的。
为了便于理解,再次贴出include/qom/object.h中ObjectClass类的定义、qom/object.c中TypeImpl的定义以及qom/object.c中的type_initialize函数:
- /**
- * struct ObjectClass:
- *
- * The base for all classes. The only thing that #ObjectClass contains is an
- * integer type handle.
- */
- struct ObjectClass
- {
- /* private: */
- Type type;
- GSList *interfaces;
-
- const char *object_cast_cache[OBJECT_CLASS_CAST_CACHE];
- const char *class_cast_cache[OBJECT_CLASS_CAST_CACHE];
-
- ObjectUnparent *unparent;
-
- GHashTable *properties;
- };
- struct TypeImpl
- {
- const char *name;
-
- size_t class_size;
-
- size_t instance_size;
- size_t instance_align;
-
- void (*class_init)(ObjectClass *klass, void *data);
- void (*class_base_init)(ObjectClass *klass, void *data);
-
- void *class_data;
-
- void (*instance_init)(Object *obj);
- void (*instance_post_init)(Object *obj);
- void (*instance_finalize)(Object *obj);
-
- bool abstract;
-
- const char *parent;
- TypeImpl *parent_type;
-
- ObjectClass *class;
-
- int num_interfaces;
- InterfaceImpl interfaces[MAX_INTERFACES];
- };
- static void type_initialize(TypeImpl *ti)
- {
- TypeImpl *parent;
-
- if (ti->class) {
- return;
- }
-
- ti->class_size = type_class_get_size(ti);
- ti->instance_size = type_object_get_size(ti);
- /* Any type with zero instance_size is implicitly abstract.
- * This means interface types are all abstract.
- */
- if (ti->instance_size == 0) {
- ti->abstract = true;
- }
- if (type_is_ancestor(ti, type_interface)) {
- assert(ti->instance_size == 0);
- assert(ti->abstract);
- assert(!ti->instance_init);
- assert(!ti->instance_post_init);
- assert(!ti->instance_finalize);
- assert(!ti->num_interfaces);
- }
- ti->class = g_malloc0(ti->class_size);
-
- parent = type_get_parent(ti);
- if (parent) {
- type_initialize(parent);
- GSList *e;
- int i;
-
- g_assert(parent->class_size <= ti->class_size);
- g_assert(parent->instance_size <= ti->instance_size);
- memcpy(ti->class, parent->class, parent->class_size);
- ti->class->interfaces = NULL;
-
- for (e = parent->class->interfaces; e; e = e->next) {
- InterfaceClass *iface = e->data;
- ObjectClass *klass = OBJECT_CLASS(iface);
-
- type_initialize_interface(ti, iface->interface_type, klass->type);
- }
-
- for (i = 0; i < ti->num_interfaces; i++) {
- TypeImpl *t = type_get_by_name(ti->interfaces[i].typename);
- if (!t) {
- error_report("missing interface '%s' for object '%s'",
- ti->interfaces[i].typename, parent->name);
- abort();
- }
- for (e = ti->class->interfaces; e; e = e->next) {
- TypeImpl *target_type = OBJECT_CLASS(e->data)->type;
-
- if (type_is_ancestor(target_type, t)) {
- break;
- }
- }
-
- if (e) {
- continue;
- }
-
- type_initialize_interface(ti, t, t);
- }
- }
-
- ti->class->properties = g_hash_table_new_full(g_str_hash, g_str_equal, NULL,
- object_property_free);
-
- ti->class->type = ti;
-
- while (parent) {
- if (parent->class_base_init) {
- parent->class_base_init(ti->class, ti->class_data);
- }
- parent = type_get_parent(parent);
- }
-
- if (ti->class_init) {
- ti->class_init(ti->class, ti->class_data);
- }
- }
对象属性存放在Object的properties域中,这个域是在对象的初始化函数ubject_initialize_with_type中构造的。
为了便于理解,再次贴出include/qom/object.h中Object类的定义以及qom/object.c中的type_initialize函数:
- /**
- * struct Object:
- *
- * The base for all objects. The first member of this object is a pointer to
- * a #ObjectClass. Since C guarantees that the first member of a structure
- * always begins at byte 0 of that structure, as long as any sub-object places
- * its parent as the first member, we can cast directly to a #Object.
- *
- * As a result, #Object contains a reference to the objects type as its
- * first member. This allows identification of the real type of the object at
- * run time.
- */
- struct Object
- {
- /* private: */
- ObjectClass *class;
- ObjectFree *free;
- GHashTable *properties;
- uint32_t ref;
- Object *parent;
- };
- static void object_initialize_with_type(Object *obj, size_t size, TypeImpl *type)
- {
- type_initialize(type);
-
- g_assert(type->instance_size >= sizeof(Object));
- g_assert(type->abstract == false);
- g_assert(size >= type->instance_size);
-
- memset(obj, 0, type->instance_size);
- obj->class = type->class;
- object_ref(obj);
- object_class_property_init_all(obj);
- obj->properties = g_hash_table_new_full(g_str_hash, g_str_equal,
- NULL, object_property_free);
- object_init_with_type(obj, type);
- object_post_init_with_type(obj, type);
- }
类的属性和对象的属性都为GHashTable类型,即两者皆为一个哈希表,在表中存着属性名到ObjectProperty的映射。
属性由ObjectProperty表示。下一回对其做深入讲解。