|
Re: LibXSLT / XPathContext interaction: msg#00018lang.perl.xml
Robin Berjon <robin.berjon@xxxxxxxxx> writes: > Matt Sergeant wrote: >> On 3 Dec 2003, at 11:55, Robin Berjon wrote: >>> I thought Python had a simple refcounted GC just like Perl's, and >>> that libxslt works there, am I wrong? If not, the way they've done >>> it could surely help us. >> I'm pretty sure the Python API for libxslt (and libxml) is a >> straight port of the C library, including having to free things >> yourself. Looking back, that might have been a better fit to the >> library, but it wouldn't have been a better fit to perl. > > I don't mind having to free things myself if it means they don't > segfault ;) I think these two things don't fit well. Manually freeing also means you have to check what can be dereferenced to prevent segfaults. By freeing a document you also free all its nodes and you should avoid dereferencing them after that. The only clean solution leads you back to reference counting, as ingeniously implemented by Christian and Matt in LibXML. Although LibXML's MM works generaly very for DOM operations (if anyone knows of a bug, tell me), the situation with user-defined XPath extension functions is more complex (this applies both to LibXSLT and XPathContext). If the extension function creates and returns new node(s), it goes as follows 1) the node it is referenced by Perl and LibXML's own refcounting machinery 2) a XS wrapper gets the nodes from the Perl callback and wants to pass them to libxslt/xpath. But: unless some extra action is taken, Perl will try to free the nodes as soon as wrapper ends because the XS wrapper was the last one who holds a Perl reference to them (unless the app itself holds an extra reference). There are two approaches: Matt's way in LibXSLT: create a (deep) copy of the node, pass it to libxslt and let Perl/LibXML free the created node in the usual way. Problem: the copy looses its parent node as well as all its relation to other nodes within the nodeset, document, etc. It is basically a very different node (although it looks quite the same). My way in XPathContext: postpone Perl's/LibXML's freeing machinery by storing a reference to the nodes in a special "pool". This way, the refcounts are artificially increased for the time the XPath expression is being evaluated. The pool is emptied when XPath processing is done. This works very well for XPath. For XSLT processing, you would probably have to keep the pool filled during the whole transformation. A small puddle would grow to a lake, then to a see, then to an ocean,... Ok, suppose for a while this part is solved in some other way (without having to make a copy of each node or storing a reference in a pool). You pass new node objects to libxslt/xpath and you want it to free them as soon as they're of no use. For example, if new-node() in //body[@background=new-node()] creates a new node, it should be freed after the equality test is done, because it is not of any use and you don't want libxslt/xpath to leak. Libxslt/xpath uses a boolean flag on a node-set for this purpose. BUT: what if the node created by new-node() is still referenced somewhere in the Perl APP? Ok, LibXSLT could examine the refcounts first, and only set the flag if apropriate. But what if only some of the nodes within the node-set are referenced on the Perl level? Conclusion: The XPathContext's way of doing it is very well unless there are too many nodes being created within evaluation of one XPath. LibXSLT's approach is memory-considerate, but doesn't pass to XSLT exactly the nodes that the extension function created. There might be some other way out of this, but I don't see it. But AFAIK, both approaches do prevent segfaults (except maybe for some implementation bugs). Am I wrong here? -- Petr _______________________________________________ Perl-XML mailing list Perl-XML@xxxxxxxxxxxxxxxxxxxxxxxx To unsubscribe: http://listserv.ActiveState.com/mailman/mysubs
|
|
| <Prev in Thread] | Current Thread | [Next in Thread> |
|---|---|---|
| Previous by Date: | Re: LibXSLT / XPathContext interaction, Robin Berjon |
|---|---|
| Next by Date: | XML::DOM::XPath, Michel Rodriguez |
| Previous by Thread: | Re: LibXSLT / XPathContext interaction, Robin Berjon |
| Next by Thread: | Reading ExcelSheet and Writing XML, Dominik . Grupp |
| Indexes: | [Date] [Thread] [Top] [All Lists] |
| News | FAQ | advertise |