Created
September 4, 2015 21:33
-
-
Save elmarco/905241b683fb9c5f2a08 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
commit 6cba14958b198cd9b34d653cab633cdcbe471fbc | |
Author: Marc-André Lureau <[email protected]> | |
Date: Fri Sep 4 21:18:39 2015 +0200 | |
Add object_class_property_add_link | |
Signed-off-by: Marc-André Lureau <[email protected]> | |
diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c | |
index 1556c9c..c78c7fb 100644 | |
--- a/hw/block/virtio-blk.c | |
+++ b/hw/block/virtio-blk.c | |
@@ -955,10 +955,6 @@ static void virtio_blk_instance_init(Object *obj) | |
{ | |
VirtIOBlock *s = VIRTIO_BLK(obj); | |
- object_property_add_link(obj, "iothread", TYPE_IOTHREAD, | |
- (Object **)&s->conf.iothread, | |
- qdev_prop_allow_set_link_before_realize, | |
- OBJ_PROP_LINK_UNREF_ON_RELEASE, NULL); | |
device_add_bootindex_property(obj, &s->conf.conf.bootindex, | |
"bootindex", "/disk@0,0", | |
DEVICE(obj), NULL); | |
@@ -994,6 +990,11 @@ static void virtio_blk_class_init(ObjectClass *klass, void *data) | |
vdc->reset = virtio_blk_reset; | |
vdc->save = virtio_blk_save_device; | |
vdc->load = virtio_blk_load_device; | |
+ | |
+ object_class_property_add_link(klass, "iothread", TYPE_IOTHREAD, | |
+ offsetof(VirtIOBlock, conf.iothread), | |
+ qdev_prop_allow_set_link_before_realize, | |
+ OBJ_PROP_LINK_UNREF_ON_RELEASE, NULL); | |
} | |
static const TypeInfo virtio_device_info = { | |
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c | |
index 9558467..1bd98fb 100644 | |
--- a/hw/i386/pc_piix.c | |
+++ b/hw/i386/pc_piix.c | |
@@ -284,11 +284,6 @@ static void pc_init1(MachineState *machine) | |
&piix4_pm); | |
smbus_eeprom_init(smbus, 8, NULL, 0); | |
- object_property_add_link(OBJECT(machine), PC_MACHINE_ACPI_DEVICE_PROP, | |
- TYPE_HOTPLUG_HANDLER, | |
- (Object **)&pcms->acpi_dev, | |
- object_property_allow_set_link, | |
- OBJ_PROP_LINK_UNREF_ON_RELEASE, &error_abort); | |
object_property_set_link(OBJECT(machine), OBJECT(piix4_pm), | |
PC_MACHINE_ACPI_DEVICE_PROP, &error_abort); | |
} | |
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h | |
index d0cad87..23ead11 100644 | |
--- a/include/hw/i386/pc.h | |
+++ b/include/hw/i386/pc.h | |
@@ -700,6 +700,11 @@ bool e820_get_entry(int, uint32_t, uint64_t *, uint64_t *); | |
optsfn(mc); \ | |
mc->name = namestr; \ | |
mc->init = initfn; \ | |
+ object_class_property_add_link(oc, PC_MACHINE_ACPI_DEVICE_PROP, \ | |
+ TYPE_HOTPLUG_HANDLER, \ | |
+ offsetof(PCMachineState, acpi_dev), \ | |
+ object_property_allow_set_link, \ | |
+ OBJ_PROP_LINK_UNREF_ON_RELEASE, &error_abort); \ | |
} \ | |
static const TypeInfo pc_machine_type_##suffix = { \ | |
.name = namestr TYPE_MACHINE_SUFFIX, \ | |
diff --git a/include/qom/object.h b/include/qom/object.h | |
index 068162e..2f95ab3 100644 | |
--- a/include/qom/object.h | |
+++ b/include/qom/object.h | |
@@ -1321,6 +1321,13 @@ void object_property_add_link(Object *obj, const char *name, | |
ObjectPropertyLinkFlags flags, | |
Error **errp); | |
+void object_class_property_add_link(ObjectClass *klass, const char *name, | |
+ const char *type, size_t offset, | |
+ void (*check)(Object *, const char *, | |
+ Object *, Error **), | |
+ ObjectPropertyLinkFlags flags, | |
+ Error **errp); | |
+ | |
/** | |
* object_property_add_str: | |
* @obj: the object to add a property to | |
diff --git a/qom/object.c b/qom/object.c | |
index 6977b43..e150125 100644 | |
--- a/qom/object.c | |
+++ b/qom/object.c | |
@@ -1341,6 +1341,7 @@ void object_property_allow_set_link(Object *obj, const char *name, | |
typedef struct { | |
Object **child; | |
+ size_t offset; | |
void (*check)(Object *, const char *, Object *, Error **); | |
ObjectPropertyLinkFlags flags; | |
} LinkProperty; | |
@@ -1402,12 +1403,17 @@ static Object *object_resolve_link(Object *obj, const char *name, | |
return target; | |
} | |
+static Object **link_property_get_child(Object *obj, LinkProperty *prop) | |
+{ | |
+ return prop->child ?: (Object **)((char*)obj + prop->offset); | |
+} | |
+ | |
static void object_set_link_property(Object *obj, Visitor *v, void *opaque, | |
const char *name, Error **errp) | |
{ | |
Error *local_err = NULL; | |
LinkProperty *prop = opaque; | |
- Object **child = prop->child; | |
+ Object **child = link_property_get_child(obj, prop); | |
Object *old_target = *child; | |
Object *new_target = NULL; | |
char *path = NULL; | |
@@ -1435,24 +1441,62 @@ static void object_set_link_property(Object *obj, Visitor *v, void *opaque, | |
object_unref(old_target); | |
} | |
-static Object *object_resolve_link_property(Object *parent, void *opaque, const gchar *part) | |
+static Object *object_resolve_link_property(Object *parent, void *opaque, | |
+ const gchar *part) | |
{ | |
LinkProperty *lprop = opaque; | |
- return *lprop->child; | |
+ return *link_property_get_child(parent, lprop); | |
} | |
static void object_release_link_property(Object *obj, const char *name, | |
void *opaque) | |
{ | |
LinkProperty *prop = opaque; | |
+ Object **child = link_property_get_child(obj, prop); | |
if ((prop->flags & OBJ_PROP_LINK_UNREF_ON_RELEASE) && *prop->child) { | |
- object_unref(*prop->child); | |
+ object_unref(*child); | |
} | |
g_free(prop); | |
} | |
+void object_class_property_add_link(ObjectClass *klass, const char *name, | |
+ const char *type, size_t offset, | |
+ void (*check)(Object *, const char *, | |
+ Object *, Error **), | |
+ ObjectPropertyLinkFlags flags, | |
+ Error **errp) | |
+{ | |
+ Error *local_err = NULL; | |
+ LinkProperty *prop = g_malloc(sizeof(*prop)); | |
+ gchar *full_type; | |
+ ObjectProperty *op; | |
+ | |
+ prop->offset = offset; | |
+ prop->check = check; | |
+ prop->flags = flags; | |
+ | |
+ full_type = g_strdup_printf("link<%s>", type); | |
+ | |
+ op = object_class_property_add(klass, name, full_type, | |
+ object_get_link_property, | |
+ check ? object_set_link_property : NULL, | |
+ object_release_link_property, | |
+ prop, | |
+ &local_err); | |
+ if (local_err) { | |
+ error_propagate(errp, local_err); | |
+ g_free(prop); | |
+ goto out; | |
+ } | |
+ | |
+ op->resolve = object_resolve_link_property; | |
+ | |
+out: | |
+ g_free(full_type); | |
+} | |
+ | |
void object_property_add_link(Object *obj, const char *name, | |
const char *type, Object **child, | |
void (*check)(Object *, const char *, |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment