From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([140.186.70.92]:42283) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QlAEC-0003j8-B4 for qemu-devel@nongnu.org; Sun, 24 Jul 2011 21:45:05 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1QlAEB-0005Sz-67 for qemu-devel@nongnu.org; Sun, 24 Jul 2011 21:45:04 -0400 Received: from e9.ny.us.ibm.com ([32.97.182.139]:52997) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QlAEA-0005Se-Fp for qemu-devel@nongnu.org; Sun, 24 Jul 2011 21:45:02 -0400 Received: from d01relay06.pok.ibm.com (d01relay06.pok.ibm.com [9.56.227.116]) by e9.ny.us.ibm.com (8.14.4/8.13.1) with ESMTP id p6P1CZVE024291 for ; Sun, 24 Jul 2011 21:12:35 -0400 Received: from d01av04.pok.ibm.com (d01av04.pok.ibm.com [9.56.224.64]) by d01relay06.pok.ibm.com (8.13.8/8.13.8/NCO v10.0) with ESMTP id p6P1j1GJ1454296 for ; Sun, 24 Jul 2011 21:45:01 -0400 Received: from d01av04.pok.ibm.com (loopback [127.0.0.1]) by d01av04.pok.ibm.com (8.14.4/8.13.1/NCO v10.0 AVout) with ESMTP id p6P1j1Sb007108 for ; Sun, 24 Jul 2011 21:45:01 -0400 From: Anthony Liguori Date: Sun, 24 Jul 2011 20:44:38 -0500 Message-Id: <1311558293-5855-7-git-send-email-aliguori@us.ibm.com> In-Reply-To: <1311558293-5855-1-git-send-email-aliguori@us.ibm.com> References: <1311558293-5855-1-git-send-email-aliguori@us.ibm.com> Subject: [Qemu-devel] [PATCH 06/21] plug: add socket property type List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: Anthony Liguori Sockets form back links in the object graph. From the object's perspective, a socket just looks like a pointer to an object. The socket property type provides a generic mechanism to set those pointers to other objects while providing strong type checking. It's also useful to lock sockets, particularly after realize. This allows for an object to enforce that a socket is programmed prior to realize and then not modified afterwards. Signed-off-by: Anthony Liguori --- include/qemu/plug.h | 2 + qom/plug.c | 64 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+), 0 deletions(-) diff --git a/include/qemu/plug.h b/include/qemu/plug.h index fdefa04..a7ca985 100644 --- a/include/qemu/plug.h +++ b/include/qemu/plug.h @@ -72,6 +72,8 @@ void plug_add_property_plug(Plug *plug, Plug *value, const char *typename, const Plug *plug_get_property_plug(Plug *plug, Error **errp, const char *name, ...); +void plug_add_property_socket(Plug *plug, const char *name, Plug **value, const char *typename); + #include "qemu/plug-proptypes.h" #endif diff --git a/qom/plug.c b/qom/plug.c index 725cac2..a9d8154 100644 --- a/qom/plug.c +++ b/qom/plug.c @@ -261,6 +261,70 @@ Plug *plug_get_property_plug(Plug *plug, Error **errp, const char *name, ...) return value; } +typedef struct SocketData +{ + const char *typename; + Plug **value; +} SocketData; + +static void plug_get_property__socket(Plug *plug, const char *name, Visitor *v, void *opaque, Error **errp) +{ + SocketData *data = opaque; + const char *value = ""; + + if (*data->value) { + value = TYPE_INSTANCE(*data->value)->id; + } + + visit_type_str(v, (char **)&value, name, errp); +} + +static void plug_set_property__socket(Plug *plug, const char *name, Visitor *v, void *opaque, Error **errp) +{ + char *value = NULL; + Error *local_err = NULL; + SocketData *data = opaque; + TypeInstance *obj; + + visit_type_str(v, &value, name, &local_err); + if (local_err) { + error_propagate(errp, local_err); + return; + } + + obj = type_find_by_id(value); + assert(obj != NULL); + + *data->value = PLUG(type_dynamic_cast_assert(obj, data->typename)); + + qemu_free(value); +} + +static void plug_del_property__socket(Plug *plug, const char *name, void *opaque) +{ + SocketData *data = opaque; + + qemu_free(data); +} + +void plug_add_property_socket(Plug *plug, const char *name, Plug **value, const char *typename) +{ + SocketData *data = qemu_mallocz(sizeof(*data)); + char fulltype[33]; + + data->typename = typename; + data->value = value; + + snprintf(fulltype, sizeof(fulltype), "socket<%s>", typename); + + plug_add_property_full(plug, name, + plug_get_property__socket, + plug_set_property__socket, + plug_del_property__socket, + data, + fulltype, PROP_F_READWRITE); +} + void plug_realize_all(Plug *plug) { /* This doesn't loop infinitely because the callbacks are only called when -- 1.7.4.1