Re: [xml] Global error (xmlLastError) not cleaned up if xmlCleanupParser() is called on a different thread!



On Tue, Jun 10, 2014 at 09:50:13AM +0200, Martin Ba wrote:
On 09.06.2014 16:19, Daniel Veillard wrote:
On Thu, Apr 10, 2014 at 01:27:30PM +0200, Martin Ba wrote:
Hi all!

It would appear that when you have a scenario like this

+ + + +
// Thread 1:
xmlInitParser();
// ...
// anything that sets the last error, e.g.:
xmlReadFile("file isn't there", NULL, XML_PARSE_NOBLANKS);  

// Thread 2:
xmlCleanupParser();
+ + + +

even if (in Thread_2) you correctly call xmlCleanupParser() (once) at the
very end and don't do anything with libxml2 afterwards, the global error
will be leaked.

(I also tried with the latest Windows binaries I could find -- 2.9.1 -- same
problem.)

Is this a known problem? Any fix for this?

Note the workaround for me is to call xmlResetLastError() after processing
any error received from libxml, in which case the global last error is
immediately cleaned up.


cheers,
Martin

p.s.: Why would anyone do this?:
* Once scenario is when DLL's are loaded/unloaded dynamically.
* Where I actually hit this is we have a .NET/C# application that loads a
C++ module that contains a global initialization object for libxml2 that
does init and cleanup. In a managed application, destructors of global
objects are not necessarily executed on the same thread as their
constructors.

  Yes that's a known limitation, and why I suggest to run
xmlInitParser() in the main thread. Also note of the danger of running
xmlCleanupParser() on unloading, as some of the libraries you linked to
(possibly indirectly)  could also run libxml2. So something to do only
in a very controlled context, i have had the case of extension mechanism
are being used, and then those use libxml2 in turn and havoc follows.
  If I were redoing libxml2 now (or had been in last 10 years) there
would be no global state, but with the API as-is and the need to keep
ABI we are stuck with it :-\ mistake done back in 98 ....



Thanks for this info. At least I now know that there isn't much I can do
with the current version.

I would like to note a few points:

* In this case, running xmlInitParser() on the main thread doesn't help --
in fact it *is* run on the main thread -- the problem is that unloading
potentially happens on a different thread when loaded into a .NET process.
* Yes, the global Init/Cleanup is a problem, I understand.
* I would like to observe that -- for those Windows applications I maintain
and know -- ABI compatibility is a non-issue, as the libxml2.dll is part of
the app distribution anyway.
* For this specific case (error cleanup), I strongly believe that the
problem could be corrected without affecting either the API or ABI, but I
don't have time to investigate more since the workaround `xmlResetLastError`
does work OK for me, as I only make libxml2 calls from C++ wrappers anyway.

Windows may have special ways to reclaim the memory, the problem is that
there is no safe way to do the cleanup in general. It's thread local
storage too, and then behaviour is OS dependent (possibly compiler
dependant). I take patches but it's a very difficult area....

daniel

-- 
Daniel Veillard      | Open Source and Standards, Red Hat
veillard redhat com  | libxml Gnome XML XSLT toolkit  http://xmlsoft.org/
http://veillard.com/ | virtualization library  http://libvirt.org/


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]