[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 5/9] object: add support for nullable child properti
From: |
Anthony Liguori |
Subject: |
[Qemu-devel] [PATCH 5/9] object: add support for nullable child properties |
Date: |
Sun, 26 Aug 2012 10:51:34 -0500 |
A nullable child can be detached from its parent by setting the property to
NULL. This provides a mechanism for a management tool to delete certain
types of objects.
Signed-off-by: Anthony Liguori <address@hidden>
object: link<>: release reference on finalize, externalize getter/setter
Reported-by: Ping Fan
Signed-off-by: Anthony Liguori <address@hidden>
---
include/qemu/object.h | 9 +++++
qom/object.c | 78 ++++++++++++++++++++++++++++++++++++++++++------
2 files changed, 77 insertions(+), 10 deletions(-)
diff --git a/include/qemu/object.h b/include/qemu/object.h
index 8bc9935..5bb62dd 100644
--- a/include/qemu/object.h
+++ b/include/qemu/object.h
@@ -907,6 +907,9 @@ Object *object_resolve_path_component(Object *parent, gchar
*part);
void object_property_add_child(Object *obj, const char *name,
Object *child, struct Error **errp);
+void object_property_add_nullable_child(Object *obj, const char *name,
+ Object *child, struct Error **errp);
+
/**
* object_property_add_link:
* @obj: the object to add a property to
@@ -925,6 +928,12 @@ void object_property_add_link(Object *obj, const char
*name,
const char *type, Object **child,
struct Error **errp);
+void object_get_link_property(Object *obj, struct Visitor *v, void *opaque,
+ const char *name, struct Error **errp);
+
+void object_set_link_property(Object *obj, struct Visitor *v, void *opaque,
+ const char *name, struct 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 1144f79..61fa40f 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -744,8 +744,17 @@ char *object_property_get_str(Object *obj, const char
*name,
void object_property_set_link(Object *obj, Object *value,
const char *name, Error **errp)
{
- object_property_set_str(obj, object_get_canonical_path(value),
- name, errp);
+ char *str;
+
+ if (value == NULL) {
+ str = g_strdup("");
+ } else {
+ str = object_get_canonical_path(value);
+ }
+
+ object_property_set_str(obj, str, name, errp);
+
+ g_free(str);
}
Object *object_property_get_link(Object *obj, const char *name,
@@ -882,6 +891,27 @@ static void object_get_child_property(Object *obj, Visitor
*v, void *opaque,
g_free(path);
}
+static void object_set_child_property(Object *obj, Visitor *v, void *opaque,
+ const char *name, Error **errp)
+{
+ gchar *path = NULL;
+ Error *local_err = NULL;
+
+ visit_type_str(v, &path, name, &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ return;
+ }
+
+ if (path && *path) {
+ error_set(errp, ERROR_CLASS_GENERIC_ERROR,
+ "Cannot set child properties to anything but empty string");
+ return;
+ }
+
+ object_property_del(obj, name, errp);
+}
+
static void object_finalize_child_property(Object *obj, const char *name,
void *opaque)
{
@@ -890,15 +920,17 @@ static void object_finalize_child_property(Object *obj,
const char *name,
object_unref(child);
}
-void object_property_add_child(Object *obj, const char *name,
- Object *child, Error **errp)
+static void object_property_add_child_full(Object *obj, const char *name,
+ Object *child, bool writable,
+ Error **errp)
{
gchar *type;
type = g_strdup_printf("child<%s>", object_get_typename(OBJECT(child)));
object_property_add(obj, name, type, object_get_child_property,
- NULL, object_finalize_child_property, child, errp);
+ writable ? object_set_child_property : NULL,
+ object_finalize_child_property, child, errp);
object_ref(child);
g_assert(child->parent == NULL);
@@ -907,8 +939,20 @@ void object_property_add_child(Object *obj, const char
*name,
g_free(type);
}
-static void object_get_link_property(Object *obj, Visitor *v, void *opaque,
- const char *name, Error **errp)
+void object_property_add_child(Object *obj, const char *name,
+ Object *child, Error **errp)
+{
+ object_property_add_child_full(obj, name, child, false, errp);
+}
+
+void object_property_add_nullable_child(Object *obj, const char *name,
+ Object *child, Error **errp)
+{
+ object_property_add_child_full(obj, name, child, true, errp);
+}
+
+void object_get_link_property(Object *obj, Visitor *v, void *opaque,
+ const char *name, Error **errp)
{
Object **child = opaque;
gchar *path;
@@ -923,8 +967,8 @@ static void object_get_link_property(Object *obj, Visitor
*v, void *opaque,
}
}
-static void object_set_link_property(Object *obj, Visitor *v, void *opaque,
- const char *name, Error **errp)
+void object_set_link_property(Object *obj, Visitor *v, void *opaque,
+ const char *name, Error **errp)
{
Object **child = opaque;
Object *old_target;
@@ -970,6 +1014,16 @@ static void object_set_link_property(Object *obj, Visitor
*v, void *opaque,
}
}
+static void object_finalize_link_property(Object *obj, const char *name,
+ void *opaque)
+{
+ Object **child = opaque;
+
+ if (*child != NULL) {
+ object_unref(*child);
+ }
+}
+
void object_property_add_link(Object *obj, const char *name,
const char *type, Object **child,
Error **errp)
@@ -981,7 +1035,11 @@ void object_property_add_link(Object *obj, const char
*name,
object_property_add(obj, name, full_type,
object_get_link_property,
object_set_link_property,
- NULL, child, errp);
+ object_finalize_link_property, child, errp);
+
+ if (*child) {
+ object_ref(*child);
+ }
g_free(full_type);
}
--
1.7.5.4