QEMU源码全解析28 —— QOM介绍(17)

88 篇文章 19 订阅
本文详细介绍了QEMU中类属性的添加过程,通过`object_class_property_add`函数实现,该函数避免了重复属性的添加,通过`object_class_property_find`检查属性是否存在。此外,对比了类属性与对象属性的处理流程。
摘要由CSDN通过智能技术生成

接前一篇文章: QEMU源码全解析27 —— QOM介绍(16)

本文内容参考:

《趣谈 Linux操作系统 》 —— 刘超, 极客时间

QEMU /KVM》源码解析与应用 —— 李强,机械工业出版社

特此致谢!

QEMU源码全解析25 —— QOM介绍(14) 中讲到属性的添加分为类属性的添加和对象属性的添加。而后就一直沿着对象属性的添加这一支走下来了,现在我们翻回头来讲解另外一支 —— 类属性的添加。

对于对象属性来说,其属性添加是通过qom/object.c中的object_property_add接口完成的。那么与之对应,类的属性的添加函数为object_class_property_add,也在qom/object.c中(实际就在object_property_add函数的下边),代码如下:

  1. ObjectProperty *
  2. object_class_property_add(ObjectClass *klass,
  3. const char *name,
  4. const char *type,
  5. ObjectPropertyAccessor *get,
  6. ObjectPropertyAccessor *set,
  7. ObjectPropertyRelease *release,
  8. void *opaque)
  9. {
  10. ObjectProperty *prop;
  11. assert(!object_class_property_find(klass, name));
  12. prop = g_malloc0(sizeof(*prop));
  13. prop->name = g_strdup(name);
  14. prop->type = g_strdup(type);
  15. prop->get = get;
  16. prop->set = set;
  17. prop->release = release;
  18. prop->opaque = opaque;
  19. g_hash_table_insert(klass->properties, prop->name, prop);
  20. return prop;
  21. }

这个函数倒没有像object_property_add函数那样又调用了一层object_property_try_add函数,而是直接在本函数中就实现了与object_property_try_add函数中类似的功能(代码很类似)。对比一下object_property_try_add函数代码:

  1. ObjectProperty *
  2. object_property_try_add(Object *obj, const char *name, const char *type,
  3. ObjectPropertyAccessor *get,
  4. ObjectPropertyAccessor *set,
  5. ObjectPropertyRelease *release,
  6. void *opaque, Error **errp)
  7. {
  8. ObjectProperty *prop;
  9. size_t name_len = strlen(name);
  10. ……
  11. if (object_property_find(obj, name) != NULL) {
  12. error_setg(errp, "attempt to add duplicate property '%s' to object (type '%s')",
  13. name, object_get_typename(obj));
  14. return NULL;
  15. }
  16. prop = g_malloc0(sizeof(*prop));
  17. prop->name = g_strdup(name);
  18. prop->type = g_strdup(type);
  19. prop->get = get;
  20. prop->set = set;
  21. prop->release = release;
  22. prop->opaque = opaque;
  23. g_hash_table_insert(obj->properties, prop->name, prop);
  24. return prop;
  25. }

可以看到,相似度很高,说明对象和类的属性的处理流程是差不多的,无非就是将Object *obj换成了ObjectClass *klass。

首先调用object_class_property_find函数来确认所插入的类属性是否已经存在。如果已存在,则报错返回,确保不会添加重复的属性。

随后分配一个ObjectProperty结构并使用函数参数进行初始化。代码片段如下(这一步与object_property_try_add中完全一样):

  1. prop = g_malloc0(sizeof(*prop));
  2. prop->name = g_strdup(name);
  3. prop->type = g_strdup(type);
  4. prop->get = get;
  5. prop->set = set;
  6. prop->release = release;
  7. prop->opaque = opaque;

最后,调用以下代码将其插入到对象的properties域中,并返回此prop:

g_hash_table_insert(obj->properties, prop->name, prop);

回过头来,看一下object_class_property_find函数的具体实现。object_class_property_find函数在同文件(qom/object.c)中,代码如下:

  1. ObjectProperty *object_class_property_find(ObjectClass *klass, const char *name)
  2. {
  3. ObjectClass *parent_klass;
  4. parent_klass = object_class_get_parent(klass);
  5. if (parent_klass) {
  6. ObjectProperty *prop =
  7. object_class_property_find(parent_klass, name);
  8. if (prop) {
  9. return prop;
  10. }
  11. }
  12. return g_hash_table_lookup(klass->properties, name);
  13. }

其实类的属性的添加反倒比对象的属性的添加简单,因为对象的属性添加中还是调用的这里的object_class_property_find函数。这个函数的作用之前也讲过,确保自己所属的类以及所有父类都不存在这个属性。

下一回讲解类的属性的设置和获取。

举报

选择你想要举报的内容(必选)
  • 内容涉黄
  • 政治相关
  • 内容抄袭
  • 涉嫌广告
  • 内容侵权
  • 侮辱谩骂
  • 样式问题
  • 其他