[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH 05 of 16] libxl: generate destructors for each libxl defined type
# HG changeset patch # User Ian Campbell <ian.campbell@xxxxxxxxxx> # Date 1282143677 -3600 # Node ID 1ee0c9db536b4af2a8543a80d2a939a3b5ec76e7 # Parent ec0d4b02e9c270b2a3e328b5b5e62e3a05aa6b1e libxl: generate destructors for each libxl defined type I chose the name "_destroy" rather than "_free" because the destructor functions will free only the members of a type recursively but will not free the actual type structure itself. The allocation of the type is typically done by the caller and may not be a single allocation, e.g. lists/arrays of types or embedded in other structures etc. The exceptions to this rule are libxl_string_list_destroy and libxl_key_value_list_destroy but I'm not 100% convinced they are exceptions (since they are kind-of opaque) and I couldn't see a cleanerway to express this concept. I have made a best effort attempt to implement these functions sanely but since as far as I can tell nothing in the current code base ever sets libxl_domain_create_info.{xsdata,platformdata} I'm flying somewhat blind. Signed-off-by: Ian Campbell <ian.campbell@xxxxxxxxxx> diff -r ec0d4b02e9c2 -r 1ee0c9db536b .hgignore --- a/.hgignore Wed Aug 18 16:01:17 2010 +0100 +++ b/.hgignore Wed Aug 18 16:01:17 2010 +0100 @@ -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 -r ec0d4b02e9c2 -r 1ee0c9db536b tools/libxl/Makefile --- a/tools/libxl/Makefile Wed Aug 18 16:01:17 2010 +0100 +++ b/tools/libxl/Makefile Wed Aug 18 16:01:17 2010 +0100 @@ -25,6 +25,7 @@ endif 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 -r ec0d4b02e9c2 -r 1ee0c9db536b tools/libxl/gentypes.py --- a/tools/libxl/gentypes.py Wed Aug 18 16:01:17 2010 +0100 +++ b/tools/libxl/gentypes.py Wed Aug 18 16:01:17 2010 +0100 @@ -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 -r ec0d4b02e9c2 -r 1ee0c9db536b tools/libxl/libxl.c --- a/tools/libxl/libxl.c Wed Aug 18 16:01:17 2010 +0100 +++ b/tools/libxl/libxl.c Wed Aug 18 16:01:17 2010 +0100 @@ -71,6 +71,33 @@ int libxl_ctx_free(libxl_ctx *ctx) do_free_version_info(&ctx->version_info); if (ctx->xsh) xs_daemon_close(ctx->xsh); 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); } /******************************************************************************/ diff -r ec0d4b02e9c2 -r 1ee0c9db536b tools/libxl/libxl.h --- a/tools/libxl/libxl.h Wed Aug 18 16:01:17 2010 +0100 +++ b/tools/libxl/libxl.h Wed Aug 18 16:01:17 2010 +0100 @@ -142,8 +142,10 @@ typedef uint8_t libxl_mac[6]; 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 -r ec0d4b02e9c2 -r 1ee0c9db536b tools/libxl/libxl.idl --- a/tools/libxl/libxl.idl Wed Aug 18 16:01:17 2010 +0100 +++ b/tools/libxl/libxl.idl Wed Aug 18 16:01:17 2010 +0100 @@ -12,10 +12,10 @@ libxl_disk_phystype = Builtin("disk_phys 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 -r ec0d4b02e9c2 -r 1ee0c9db536b tools/libxl/libxltypes.py --- a/tools/libxl/libxltypes.py Wed Aug 18 16:01:17 2010 +0100 +++ b/tools/libxl/libxltypes.py Wed Aug 18 16:01:17 2010 +0100 @@ -1,9 +1,16 @@ import sys 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 @@ -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 BitField(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 Reference(Type): 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) _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |