Skip to content

Instantly share code, notes, and snippets.

@elmarco
Created September 4, 2015 21:33
Show Gist options
  • Save elmarco/905241b683fb9c5f2a08 to your computer and use it in GitHub Desktop.
Save elmarco/905241b683fb9c5f2a08 to your computer and use it in GitHub Desktop.
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