lmi
[Top][All Lists]
Advanced

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

[lmi] bad use of xml::init in LMI sources


From: Vaclav Slavik
Subject: [lmi] bad use of xml::init in LMI sources
Date: Wed, 26 Nov 2008 19:56:00 +0100

Hi,

I found what I believe to be a poor way of using xml::init in the LMI
code. I may be missing something, of course, but if I'm not, I'd welcome
any feedback on how to best fix this.

The xml::init class is used to initialize the library before first use
and shut it down after you're done with it. It's usage is described as
follows:

        The xml::init class is used to initialize the XML parser. For
        thread safety it should be instantiated one time in the main
        thread before any other threads use xmlwrapp. Non-threaded
        programs should instantiate a xml::init class before using
        xmlwrapp as well, at least for consistency.
         
        If you want to use and of the xml::init member functions, do so
        before you start any threads or use any other part of xmlwrapp.
        The member functions may alter global and/or static variables.
        In other words, this class is not thread safe.

But LMI doesn't use it like that, it creates instances in constructors
of xml_lmi::dom_parser and xml_lmi::xml_document classes. That defeats
the purpose of xml::init as MT-safe initializer (which doesn't matter
for LMI) and -- more importantly for us -- it means that libxml2 parser
is shut down every time a document is destroyed and re-initialized for a
new document. And it means this usage is broken:

        xml_lmi::xml_document *d1 = new xml_document(...);
        xml_lmi::xml_document *d2 = new xml_document(...);
        ...
        delete d1; // libxml2 shut down
        ...
        // cannot safely use d2 here!

The simplest fix would be to simply not use xml::init at all, because
LMI doesn't use threads and so doesn't need it.

Another would be, of course, to use xml::init as intended, by creating
an instance in main(). But I understand why you wouldn't want to do
that. In fact, this problem is more general: it makes it impractical to
use xmlwrapp internally in any library [that doesn't expose its use of
xmlwrapp in its public API].

So I'm thinking that a better fix would be to make it possible to create
multiple instances of xml::init, as long as they are all created before
any threads are launched. We could than safely create a global xml::init
object in xml_lmi.cpp to initialize xmlwrapp at app startup (and
similarly for xslt::init -- the latter derives from xml::init and so
we'd have two xml::init instances in practice). Can you see any problem
with doing that, or even a better solution?

The obvious problem is that it triggers libxml2 initialization very
early, before main() starts. This means slower startup, but I think that
after the product files are converted into XML format, LMI will get to
loading an XML file soon after starting anyway...

Thanks,
Vaclav

reply via email to

[Prev in Thread] Current Thread [Next in Thread]