@@ -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
@@ -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
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 <aliguori@us.ibm.com> --- include/qemu/plug.h | 2 + qom/plug.c | 64 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+), 0 deletions(-)