Signed-off-by: Marc-André Lureau <marcandre.lur...@redhat.com> --- include/qom/object.h | 9 +++++++++ qom/object.c | 46 +++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 54 insertions(+), 1 deletion(-)
diff --git a/include/qom/object.h b/include/qom/object.h index 5b02be68ec..ead9129ac8 100644 --- a/include/qom/object.h +++ b/include/qom/object.h @@ -1531,6 +1531,7 @@ typedef enum { /* private */ OBJ_PROP_LINK_DIRECT = 0x2, + OBJ_PROP_LINK_CLASS = 0x4, } ObjectPropertyLinkFlags; /** @@ -1579,6 +1580,14 @@ void object_property_add_link(Object *obj, const char *name, ObjectPropertyLinkFlags flags, Error **errp); +ObjectProperty *object_class_property_add_link(ObjectClass *oc, + const char *name, + const char *type, ptrdiff_t offset, + void (*check)(const Object *obj, const char *name, + Object *val, Error **errp), + 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 09d960f254..04f2991716 100644 --- a/qom/object.c +++ b/qom/object.c @@ -1723,6 +1723,7 @@ typedef struct { union { Object **targetp; Object *target; /* if OBJ_PROP_LINK_DIRECT, when holding the pointer */ + ptrdiff_t offset; /* if OBJ_PROP_LINK_CLASS */ }; void (*check)(const Object *, const char *, Object *, Error **); ObjectPropertyLinkFlags flags; @@ -1733,6 +1734,8 @@ object_link_get_targetp(Object *obj, LinkProperty *lprop) { if (lprop->flags & OBJ_PROP_LINK_DIRECT) { return &lprop->target; + } else if (lprop->flags & OBJ_PROP_LINK_CLASS) { + return (void *)obj + lprop->offset; } else { return lprop->targetp; } @@ -1848,7 +1851,9 @@ static void object_release_link_property(Object *obj, const char *name, if ((prop->flags & OBJ_PROP_LINK_STRONG) && *targetp) { object_unref(*targetp); } - g_free(prop); + if (!(prop->flags & OBJ_PROP_LINK_CLASS)) { + g_free(prop); + } } static void object_add_link_prop(Object *obj, const char *name, @@ -1901,6 +1906,45 @@ void object_property_add_link(Object *obj, const char *name, object_add_link_prop(obj, name, type, targetp, check, flags, errp); } +ObjectProperty * +object_class_property_add_link(ObjectClass *oc, + const char *name, + const char *type, ptrdiff_t offset, + void (*check)(const Object *obj, const char *name, + Object *val, Error **errp), + ObjectPropertyLinkFlags flags, + Error **errp) +{ + Error *local_err = NULL; + LinkProperty *prop = g_new0(LinkProperty, 1); + gchar *full_type; + ObjectProperty *op; + + prop->offset = offset; + prop->check = check; + prop->flags = flags | OBJ_PROP_LINK_CLASS; + + full_type = g_strdup_printf("link<%s>", type); + + op = object_class_property_add(oc, 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); + return op; +} + void object_property_add_const_link(Object *obj, const char *name, Object *target, Error **errp) { -- 2.25.0.rc1.20.g2443f3f80d.dirty