aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.hgignore1
-rw-r--r--tools/libxl/Makefile7
-rw-r--r--tools/libxl/gentypes.py78
-rw-r--r--tools/libxl/libxl.c27
-rw-r--r--tools/libxl/libxl.h2
-rw-r--r--tools/libxl/libxl.idl6
-rw-r--r--tools/libxl/libxltypes.py32
7 files changed, 142 insertions, 11 deletions
diff --git a/.hgignore b/.hgignore
index d39427946b..2ab5724a29 100644
--- a/.hgignore
+++ b/.hgignore
@@ -182,6 +182,7 @@
^tools/libxen/test/test_bindings$
^tools/libxen/test/test_event_handling$
^tools/libxl/_.*\.h$
+^tools/libxl/_.*\.c$
^tools/libxl/libxlu_cfg_y\.output$
^tools/libxl/xl$
^tools/libaio/src/.*\.ol$
diff --git a/tools/libxl/Makefile b/tools/libxl/Makefile
index 3abb12dd5c..04fd9f335e 100644
--- a/tools/libxl/Makefile
+++ b/tools/libxl/Makefile
@@ -25,6 +25,7 @@ LIBXL_OBJS-y += libxl_noblktap2.o
endif
LIBXL_OBJS = flexarray.o libxl.o libxl_pci.o libxl_dom.o libxl_exec.o libxl_xshelp.o libxl_device.o libxl_internal.o xenguest.o libxl_utils.o $(LIBXL_OBJS-y)
+LIBXL_OBJS += _libxl_types.o
AUTOINCS= libxlu_cfg_y.h libxlu_cfg_l.h
AUTOSRCS= libxlu_cfg_y.c libxlu_cfg_l.c
@@ -64,9 +65,10 @@ libxl.h: _libxl_types.h
$(LIBXL_OBJS:%.o=%.c) $(LIBXLU_OBJS:%.o=%.c) $(XL_OBJS:%.o=%.c): libxl.h
-_libxl_types.h: libxl.idl gentypes.py libxltypes.py
- python gentypes.py libxl.idl __libxl_types.h
+_libxl_types.h _libxl_types.c: libxl.idl gentypes.py libxltypes.py
+ python gentypes.py libxl.idl __libxl_types.h __libxl_types.c
mv __libxl_types.h _libxl_types.h
+ mv __libxl_types.c _libxl_types.c
libxenlight.so: libxenlight.so.$(MAJOR)
ln -sf $< $@
@@ -116,6 +118,7 @@ install: all
.PHONY: clean
clean:
$(RM) -f _*.h *.o *.so* *.a $(CLIENTS) $(DEPS)
+ $(RM) -f _*.c
# $(RM) -f $(AUTOSRCS) $(AUTOINCS)
distclean: clean
diff --git a/tools/libxl/gentypes.py b/tools/libxl/gentypes.py
index 5053d8dea7..e4762d3767 100644
--- a/tools/libxl/gentypes.py
+++ b/tools/libxl/gentypes.py
@@ -59,16 +59,53 @@ def libxl_C_type_define(ty, indent = ""):
raise NotImplementedError("%s" % type(ty))
return s.replace("\n", "\n%s" % indent)
+def libxl_C_type_destroy(ty, v, reference, indent = " ", parent = None):
+ if reference:
+ deref = v + "->"
+ else:
+ deref = v + "."
+
+ s = ""
+ if isinstance(ty, libxltypes.KeyedUnion):
+ if parent is None:
+ raise Exception("KeyedUnion type must have a parent")
+ for f in ty.fields:
+ keyvar_expr = f.keyvar_expr % (parent + ty.keyvar_name)
+ s += "if (" + keyvar_expr + ") {\n"
+ s += libxl_C_type_destroy(f.type, deref + f.name, False, indent + " ", deref)
+ s += "}\n"
+ elif isinstance(ty, libxltypes.Reference):
+ s += libxl_C_type_destroy(ty.ref_type, v, True, indent, v)
+ elif isinstance(ty, libxltypes.Struct) and (parent is None or ty.destructor_fn is None):
+ for f in [f for f in ty.fields if not f.const]:
+
+ if f.name is None: # Anonynous struct
+ s += libxl_C_type_destroy(f.type, deref, False, "", deref)
+ else:
+ s += libxl_C_type_destroy(f.type, deref + f.name, False, "", deref)
+ else:
+ if ty.passby == libxltypes.PASS_BY_REFERENCE and not reference:
+ makeref = "&"
+ else:
+ makeref = ""
+
+ if ty.destructor_fn is not None:
+ s += "%s(%s);\n" % (ty.destructor_fn, makeref + v)
+
+ if s != "":
+ s = indent + s
+ return s.replace("\n", "\n%s" % indent).rstrip(indent)
+
if __name__ == '__main__':
- if len(sys.argv) < 3:
- print >>sys.stderr, "Usage: gentypes.py <idl> <header>"
+ if len(sys.argv) < 4:
+ print >>sys.stderr, "Usage: gentypes.py <idl> <header> <implementation>"
sys.exit(1)
idl = sys.argv[1]
(_,types) = libxltypes.parse(idl)
header = sys.argv[2]
- print "outputting libxl types to %s" % header
+ print "outputting libxl type definitions to %s" % header
f = open(header, "w")
@@ -84,8 +121,39 @@ if __name__ == '__main__':
""" % " ".join(sys.argv))
- for t in types:
- f.write(libxl_C_type_define(t) + ";\n")
+ for ty in types:
+ f.write(libxl_C_type_define(ty) + ";\n")
+ if ty.destructor_fn is not None:
+ f.write("void %s(%s *p);\n" % (ty.destructor_fn, ty.typename))
f.write("\n")
f.write("""#endif /* __LIBXL_TYPES_H */\n""")
+ f.close()
+
+ impl = sys.argv[3]
+ print "outputting libxl type implementations to %s" % impl
+
+ f = open(impl, "w")
+ f.write("""
+/* DO NOT EDIT.
+ *
+ * This file is autogenerated by
+ * "%s"
+ */
+
+#include "libxl_osdeps.h"
+
+#include <stdint.h>
+#include <stdlib.h>
+
+#include "libxl.h"
+
+""" % " ".join(sys.argv))
+
+ for ty in [t for t in types if t.autogenerate_destructor]:
+ f.write("void %s(%s *p)\n" % (ty.destructor_fn, ty.typename))
+ f.write("{\n")
+ f.write(libxl_C_type_destroy(ty, "p", True))
+ f.write("}\n")
+ f.write("\n")
+ f.close()
diff --git a/tools/libxl/libxl.c b/tools/libxl/libxl.c
index c31c659d09..531590ce7a 100644
--- a/tools/libxl/libxl.c
+++ b/tools/libxl/libxl.c
@@ -73,6 +73,33 @@ int libxl_ctx_free(libxl_ctx *ctx)
return 0;
}
+void libxl_string_list_destroy(libxl_string_list sl)
+{
+ int i;
+
+ if (!sl)
+ return;
+
+ for (i = 0; sl[i] != NULL; i++)
+ free(sl[i]);
+ free(sl);
+}
+
+void libxl_key_value_list_destroy(libxl_key_value_list kvl)
+{
+ int i;
+
+ if (!kvl)
+ return;
+
+ for (i = 0; kvl[i] != NULL; i += 2) {
+ free(kvl[i]);
+ if (kvl[i + 1])
+ free(kvl[i + 1]);
+ }
+ free(kvl);
+}
+
/******************************************************************************/
int libxl_domain_make(libxl_ctx *ctx, libxl_domain_create_info *info,
diff --git a/tools/libxl/libxl.h b/tools/libxl/libxl.h
index 9742f4b1de..566da1455a 100644
--- a/tools/libxl/libxl.h
+++ b/tools/libxl/libxl.h
@@ -142,8 +142,10 @@ typedef uint8_t libxl_uuid[16];
typedef uint8_t libxl_mac[6];
typedef char **libxl_string_list;
+void libxl_string_list_destroy(libxl_string_list sl);
typedef char **libxl_key_value_list;
+void libxl_key_value_list_destroy(libxl_key_value_list kvl);
typedef uint64_t *libxl_cpumap;
diff --git a/tools/libxl/libxl.idl b/tools/libxl/libxl.idl
index c424286a7a..ea425de6b3 100644
--- a/tools/libxl/libxl.idl
+++ b/tools/libxl/libxl.idl
@@ -12,10 +12,10 @@ libxl_console_constype = Builtin("console_constype")
libxl_disk_phystype = Builtin("disk_phystype")
libxl_nic_type = Builtin("nic_type")
-libxl_string_list = Builtin("string_list")
-libxl_key_value_list = Builtin("key_value_list")
+libxl_string_list = Builtin("string_list", destructor_fn="libxl_string_list_destroy")
+libxl_key_value_list = Builtin("key_value_list", destructor_fn="libxl_key_value_list_destroy")
-libxl_cpumap = Builtin("cpumap")
+libxl_cpumap = Builtin("cpumap", destructor_fn="free")
libxl_hwcap = Builtin("hwcap")
diff --git a/tools/libxl/libxltypes.py b/tools/libxl/libxltypes.py
index f08ee22c4b..5caff9c2e1 100644
--- a/tools/libxl/libxltypes.py
+++ b/tools/libxl/libxltypes.py
@@ -1,10 +1,17 @@
import sys
+PASS_BY_VALUE = 1
+PASS_BY_REFERENCE = 2
+
class Type(object):
def __init__(self, typename, **kwargs):
self.comment = kwargs.setdefault('comment', None)
self.namespace = kwargs.setdefault('namespace', "libxl_")
+ self.passby = kwargs.setdefault('passby', PASS_BY_VALUE)
+ if self.passby not in [PASS_BY_VALUE, PASS_BY_REFERENCE]:
+ raise ValueError
+
if typename is None: # Anonymous type
self.typename = None
elif self.namespace is None: # e.g. system provided types
@@ -12,14 +19,23 @@ class Type(object):
else:
self.typename = self.namespace + typename
+ if self.typename is not None:
+ self.destructor_fn = kwargs.setdefault('destructor_fn', self.typename + "_destroy")
+ else:
+ self.destructor_fn = kwargs.setdefault('destructor_fn', None)
+
+ self.autogenerate_destructor = kwargs.setdefault('autogenerate_destructor', True)
+
class Builtin(Type):
"""Builtin type"""
def __init__(self, typename, **kwargs):
+ kwargs.setdefault('destructor_fn', None)
Type.__init__(self, typename, **kwargs)
class UInt(Type):
def __init__(self, w, **kwargs):
kwargs.setdefault('namespace', None)
+ kwargs.setdefault('destructor_fn', None)
Type.__init__(self, "uint%d_t" % w, **kwargs)
self.width = w
@@ -27,6 +43,7 @@ class UInt(Type):
class BitField(Type):
def __init__(self, ty, w, **kwargs):
kwargs.setdefault('namespace', None)
+ kwargs.setdefault('destructor_fn', None)
Type.__init__(self, ty.typename, **kwargs)
self.width = w
@@ -63,10 +80,16 @@ class Aggregate(Type):
class Struct(Aggregate):
def __init__(self, name, fields, **kwargs):
+ kwargs.setdefault('passby', PASS_BY_REFERENCE)
Aggregate.__init__(self, "struct", name, fields, **kwargs)
class Union(Aggregate):
def __init__(self, name, fields, **kwargs):
+ # Generally speaking some intelligence is required to free a
+ # union therefore any specific instance of this class will
+ # need to provide an explicit destructor function.
+ kwargs.setdefault('passby', PASS_BY_REFERENCE)
+ kwargs.setdefault('destructor_fn', None)
Aggregate.__init__(self, "union", name, fields, **kwargs)
class KeyedUnion(Aggregate):
@@ -87,7 +110,14 @@ class KeyedUnion(Aggregate):
class Reference(Type):
"""A reference to another type"""
def __init__(self, ty, **kwargs):
+ self.ref_type = ty
+
# Ugh
+
+ kwargs.setdefault('destructor_fn', "free")
+ kwargs.setdefault('autogenerate_destructor', False)
+ kwargs.setdefault('passby', PASS_BY_VALUE)
+
kwargs.setdefault('namespace', ty.namespace)
typename = ty.typename[len(kwargs['namespace']):]
Type.__init__(self, typename + " *", **kwargs)
@@ -112,7 +142,7 @@ uint64 = UInt(64)
domid = UInt(32)
-string = Builtin("char *", namespace = None)
+string = Builtin("char *", namespace = None, destructor_fn = "free")
inaddr_ip = Builtin("struct in_addr", namespace = None)