diff --git a/xml.c b/xml.c index 34ec50e21..19e53594d 100644 --- a/xml.c +++ b/xml.c @@ -478,3 +478,47 @@ struct iio_context * xml_create_context_mem(const char *xml, size_t len) xmlFreeDoc(doc); return ctx; } + + +static void cleanup_libxml2_stuff(void) +{ + /* + * This function will be called only when the libiio library is + * unloaded (e.g. when the program exits). + * + * Cleanup libxml2 so that memory analyzer tools like Valgrind won't + * detect a memory leak. + */ + xmlCleanupParser(); + xmlMemoryDump(); +} + +#if defined(_MSC_BUILD) +#pragma section(".CRT$XCU", read) +#define __CONSTRUCTOR(f, p) \ + static void f(void); \ + __declspec(allocate(".CRT$XCU")) void (*f##_)(void) = f; \ + __pragma(comment(linker,"/include:" p #f "_")) \ + static void f(void) +#ifdef _WIN64 +#define _CONSTRUCTOR(f) __CONSTRUCTOR(f, "") +#else +#define _CONSTRUCTOR(f) __CONSTRUCTOR(f, "_") +#endif +#elif defined(__GNUC__) +#define _CONSTRUCTOR(f) static void __attribute__((constructor)) f(void) +#else +#define _CONSTRUCTOR(f) static void f(void) +#endif + +_CONSTRUCTOR(initialize) +{ + /* + * When the library loads, register our destructor. + * Do it here and not in the context creation function, + * as it could otherwise end up registering the destructor + * many times. + */ + atexit(cleanup_libxml2_stuff); +} +#undef _CONSTRUCTOR