diff --git a/include/qom/object.h b/include/qom/object.h index a163adc7c5..24d6ebe675 100644 --- a/include/qom/object.h +++ b/include/qom/object.h @@ -1511,6 +1511,9 @@ void object_property_add_child(Object *obj, const char *name, typedef enum { /* Unref the link pointer when the property is deleted */ OBJ_PROP_LINK_STRONG = 0x1, + + /* private */ + OBJ_PROP_LINK_DIRECT = 0x2, } ObjectPropertyLinkFlags; /** diff --git a/qom/object.c b/qom/object.c index bb5b739c61..a9760d5276 100644 --- a/qom/object.c +++ b/qom/object.c @@ -1713,17 +1713,30 @@ void object_property_allow_set_link(const Object *obj, const char *name, } typedef struct { - Object **targetp; + union { + Object **targetp; + Object *target; /* if OBJ_PROP_LINK_DIRECT, when holding the pointer */ + }; void (*check)(const Object *, const char *, Object *, Error **); ObjectPropertyLinkFlags flags; } LinkProperty; +static Object ** +object_link_get_targetp(Object *obj, LinkProperty *lprop) +{ + if (lprop->flags & OBJ_PROP_LINK_DIRECT) { + return &lprop->target; + } else { + return lprop->targetp; + } +} + static void object_get_link_property(Object *obj, Visitor *v, const char *name, void *opaque, Error **errp) { LinkProperty *lprop = opaque; - Object **targetp = lprop->targetp; + Object **targetp = object_link_get_targetp(obj, lprop); gchar *path; if (*targetp) { @@ -1782,7 +1795,7 @@ static void object_set_link_property(Object *obj, Visitor *v, { Error *local_err = NULL; LinkProperty *prop = opaque; - Object **targetp = prop->targetp; + Object **targetp = object_link_get_targetp(obj, prop); Object *old_target = *targetp; Object *new_target = NULL; char *path = NULL; @@ -1816,16 +1829,17 @@ static Object *object_resolve_link_property(Object *parent, void *opaque, const { LinkProperty *lprop = opaque; - return *lprop->targetp; + return *object_link_get_targetp(parent, lprop); } static void object_release_link_property(Object *obj, const char *name, void *opaque) { LinkProperty *prop = opaque; + Object **targetp = object_link_get_targetp(obj, prop); - if ((prop->flags & OBJ_PROP_LINK_STRONG) && *prop->targetp) { - object_unref(*prop->targetp); + if ((prop->flags & OBJ_PROP_LINK_STRONG) && *targetp) { + object_unref(*targetp); } g_free(prop); }