From f93a866079364a006189683eaa07f94c867389d1 Mon Sep 17 00:00:00 2001 From: Daniel Veillard Date: Thu, 1 Jul 2004 12:56:30 +0000 Subject: [PATCH] =?UTF-8?q?applied=20patch=20from=20St=E9phane=20Bidoul=20?= =?UTF-8?q?to=20fix=20some=20Python=20bindings?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * python/libxml.c python/generator.py python/libxml.py python/libxml2-python-api.xml python/libxml2class.txt: applied patch from Stéphane Bidoul to fix some Python bindings initialization, then had to change the parserCleanup() to handle memory released there. * xmlmemory.c: added more debugging comments. Daniel --- ChangeLog | 9 ++++++ python/generator.py | 2 ++ python/libxml.c | 53 ++++++++++++++++++++++++++++------- python/libxml.py | 5 ++++ python/libxml2-python-api.xml | 4 +++ python/libxml2class.txt | 2 +- xmlmemory.c | 30 +++++++++++++++++++- 7 files changed, 93 insertions(+), 12 deletions(-) diff --git a/ChangeLog b/ChangeLog index 9c82089e..c2749e12 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +Thu Jul 1 14:53:36 CEST 2004 Daniel Veillard + + * python/libxml.c python/generator.py python/libxml.py + python/libxml2-python-api.xml python/libxml2class.txt: + applied patch from Stéphane Bidoul to fix some Python bindings + initialization, then had to change the parserCleanup() + to handle memory released there. + * xmlmemory.c: added more debugging comments. + Thu Jul 1 13:18:02 CEST 2004 Daniel Veillard * xmlreader.c: seems the reader buffer could be used while not diff --git a/python/generator.py b/python/generator.py index e0f10969..3ae57292 100755 --- a/python/generator.py +++ b/python/generator.py @@ -302,6 +302,8 @@ def skip_function(name): return 1 if name == "xmlFreeParserCtxt": return 1 + if name == "xmlCleanupParser": + return 1 if name == "xmlFreeTextReader": return 1 # if name[0:11] == "xmlXPathNew": diff --git a/python/libxml.c b/python/libxml.c index 4ab69fb8..eb44a2b6 100644 --- a/python/libxml.c +++ b/python/libxml.c @@ -75,6 +75,9 @@ static xmlMallocFunc mallocFunc = NULL; static xmlReallocFunc reallocFunc = NULL; static xmlStrdupFunc strdupFunc = NULL; +static void +libxml_xmlErrorInitialize(void); /* forward declare */ + PyObject * libxml_xmlDebugMemory(ATTRIBUTE_UNUSED PyObject * self, PyObject * args) { @@ -104,13 +107,21 @@ libxml_xmlDebugMemory(ATTRIBUTE_UNUSED PyObject * self, PyObject * args) (strdupFunc == xmlMemoryStrdup)) { libxmlMemoryAllocatedBase = xmlMemUsed(); } else { + /* + * cleanup first, because some memory has been + * allocated with the non-debug malloc in xmlInitParser + * when the python module was imported + */ + xmlCleanupParser(); ret = (long) xmlMemSetup(xmlMemFree, xmlMemMalloc, xmlMemRealloc, xmlMemoryStrdup); if (ret < 0) goto error; libxmlMemoryAllocatedBase = xmlMemUsed(); + /* reinitialize */ + xmlInitParser(); + libxml_xmlErrorInitialize(); } - xmlInitParser(); ret = 0; } else if (libxmlMemoryDebugActivated == 0) { libxmlMemoryAllocatedBase = xmlMemUsed(); @@ -132,6 +143,29 @@ libxml_xmlDebugMemory(ATTRIBUTE_UNUSED PyObject * self, PyObject * args) return (py_retval); } +PyObject * +libxml_xmlPythonCleanupParser(PyObject *self ATTRIBUTE_UNUSED, + PyObject *args ATTRIBUTE_UNUSED) { + + long freed; + + if (libxmlMemoryDebug) { + freed = xmlMemUsed(); + } + + xmlCleanupParser(); + + if (libxmlMemoryDebug) { + freed -= xmlMemUsed(); + libxmlMemoryAllocatedBase -= freed; + if (libxmlMemoryAllocatedBase < 0) + libxmlMemoryAllocatedBase = 0; + } + + Py_INCREF(Py_None); + return(Py_None); +} + PyObject * libxml_xmlDumpMemory(ATTRIBUTE_UNUSED PyObject * self, ATTRIBUTE_UNUSED PyObject * args) @@ -3228,20 +3262,19 @@ void initlibxml2mod(void) { static int initialized = 0; - PyObject *m; if (initialized != 0) return; - /* XXX xmlInitParser does much more than this */ - xmlInitGlobals(); -#ifdef LIBXML_OUTPUT_ENABLED - xmlRegisterDefaultOutputCallbacks(); -#endif /* LIBXML_OUTPUT_ENABLED */ - xmlRegisterDefaultInputCallbacks(); - m = Py_InitModule((char *) "libxml2mod", libxmlMethods); - initialized = 1; + + /* intialize the python extension module */ + Py_InitModule((char *) "libxml2mod", libxmlMethods); + + /* initialize libxml2 */ + xmlInitParser(); libxml_xmlErrorInitialize(); + initialized = 1; + #ifdef MERGED_MODULES initlibxsltmod(); #endif diff --git a/python/libxml.py b/python/libxml.py index 0c3ba6cd..59809747 100644 --- a/python/libxml.py +++ b/python/libxml.py @@ -618,6 +618,11 @@ class xmlTextReaderCore: # assert f is _xmlTextReaderErrorFunc return arg +# +# The cleanup now goes though a wrappe in libxml.c +# +def cleanupParser(): + libxml2mod.xmlPythonCleanupParser() # WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING # diff --git a/python/libxml2-python-api.xml b/python/libxml2-python-api.xml index d5a4cbe6..f6ecd83c 100644 --- a/python/libxml2-python-api.xml +++ b/python/libxml2-python-api.xml @@ -306,5 +306,9 @@ + + Cleanup function for the XML library. It tries to reclaim all parsing related global memory allocated for the library processing. It doesn't deallocate any document related memory. Calling this function should not prevent reusing the library but one should call xmlCleanupParser() only when the process has finished using the library or XML document built with it. + + diff --git a/python/libxml2class.txt b/python/libxml2class.txt index 74798436..6266a9db 100644 --- a/python/libxml2class.txt +++ b/python/libxml2class.txt @@ -104,7 +104,6 @@ nanoHTTPInit() nanoHTTPScanProxy() # functions from module parser -cleanupParser() createDocParserCtxt() initParser() keepBlanksDefault() @@ -151,6 +150,7 @@ dumpMemory() htmlCreatePushParser() htmlSAXParseFile() newNode() +pythonCleanupParser() setEntityLoader() # functions from module relaxng diff --git a/xmlmemory.c b/xmlmemory.c index 84458cfc..a0ed5f4e 100644 --- a/xmlmemory.c +++ b/xmlmemory.c @@ -29,6 +29,7 @@ #include #endif +/* #define DEBUG_MEMORY */ /** * MEM_LIST: @@ -780,6 +781,10 @@ xmlMemoryDump(void) int xmlInitMemory(void) { +#ifdef DEBUG_MEMORY + xmlGenericError(xmlGenericErrorContext, + "xmlInitMemory()\n"); +#endif #ifdef HAVE_STDLIB_H char *breakpoint; #endif @@ -808,7 +813,6 @@ xmlInitMemory(void) xmlGenericError(xmlGenericErrorContext, "xmlInitMemory() Ok\n"); #endif - return(0); } @@ -819,12 +823,20 @@ xmlInitMemory(void) */ void xmlCleanupMemory(void) { +#ifdef DEBUG_MEMORY + xmlGenericError(xmlGenericErrorContext, + "xmlCleanupMemory()\n"); +#endif if (xmlMemInitialized == 0) return; xmlFreeMutex(xmlMemMutex); xmlMemMutex = NULL; xmlMemInitialized = 0; +#ifdef DEBUG_MEMORY + xmlGenericError(xmlGenericErrorContext, + "xmlCleanupMemory() Ok\n"); +#endif } /** @@ -845,6 +857,10 @@ xmlCleanupMemory(void) { int xmlMemSetup(xmlFreeFunc freeFunc, xmlMallocFunc mallocFunc, xmlReallocFunc reallocFunc, xmlStrdupFunc strdupFunc) { +#ifdef DEBUG_MEMORY + xmlGenericError(xmlGenericErrorContext, + "xmlMemSetup()\n"); +#endif if (freeFunc == NULL) return(-1); if (mallocFunc == NULL) @@ -858,6 +874,10 @@ xmlMemSetup(xmlFreeFunc freeFunc, xmlMallocFunc mallocFunc, xmlMallocAtomic = mallocFunc; xmlRealloc = reallocFunc; xmlMemStrdup = strdupFunc; +#ifdef DEBUG_MEMORY + xmlGenericError(xmlGenericErrorContext, + "xmlMemSetup() Ok\n"); +#endif return(0); } @@ -904,6 +924,10 @@ int xmlGcMemSetup(xmlFreeFunc freeFunc, xmlMallocFunc mallocFunc, xmlMallocFunc mallocAtomicFunc, xmlReallocFunc reallocFunc, xmlStrdupFunc strdupFunc) { +#ifdef DEBUG_MEMORY + xmlGenericError(xmlGenericErrorContext, + "xmlGcMemSetup()\n"); +#endif if (freeFunc == NULL) return(-1); if (mallocFunc == NULL) @@ -919,6 +943,10 @@ xmlGcMemSetup(xmlFreeFunc freeFunc, xmlMallocFunc mallocFunc, xmlMallocAtomic = mallocAtomicFunc; xmlRealloc = reallocFunc; xmlMemStrdup = strdupFunc; +#ifdef DEBUG_MEMORY + xmlGenericError(xmlGenericErrorContext, + "xmlGcMemSetup() Ok\n"); +#endif return(0); }