[Lxml-checkins] r44654 - in lxml/branch/lxml-1.3: . src/lxml

scoder at codespeak.net scoder at codespeak.net
Sun Jul 1 15:19:00 CEST 2007


Author: scoder
Date: Sun Jul  1 15:18:59 2007
New Revision: 44654

Modified:
   lxml/branch/lxml-1.3/CHANGES.txt
   lxml/branch/lxml-1.3/src/lxml/etree.pyx
   lxml/branch/lxml-1.3/src/lxml/proxy.pxi
   lxml/branch/lxml-1.3/src/lxml/python.pxd
Log:
merged in proxy deallocation update from trunk

Modified: lxml/branch/lxml-1.3/CHANGES.txt
==============================================================================
--- lxml/branch/lxml-1.3/CHANGES.txt	(original)
+++ lxml/branch/lxml-1.3/CHANGES.txt	Sun Jul  1 15:18:59 2007
@@ -14,6 +14,8 @@
 Bugs fixed
 ----------
 
+* Better way to prevent crashes in Element proxy cleanup code
+
 * objectify.DataElement didn't set up None value correctly
 
 * objectify.DataElement didn't check the value against the provided type hints

Modified: lxml/branch/lxml-1.3/src/lxml/etree.pyx
==============================================================================
--- lxml/branch/lxml-1.3/src/lxml/etree.pyx	(original)
+++ lxml/branch/lxml-1.3/src/lxml/etree.pyx	Sun Jul  1 15:18:59 2007
@@ -243,8 +243,8 @@
         #displayNode(<xmlNode*>self._c_doc, 0)
         #print <long>self._c_doc, self._c_doc.dict is __GLOBAL_PARSER_CONTEXT._c_dict
         #print <long>self._c_doc, canDeallocateChildNodes(<xmlNode*>self._c_doc)
-        #tree.xmlFreeDoc(c_doc)
-        _deallocDocument(self._c_doc)
+        tree.xmlFreeDoc(self._c_doc)
+        #_deallocDocument(self._c_doc)
 
     cdef getroot(self):
         cdef xmlNode* c_node

Modified: lxml/branch/lxml-1.3/src/lxml/proxy.pxi
==============================================================================
--- lxml/branch/lxml-1.3/src/lxml/proxy.pxi	(original)
+++ lxml/branch/lxml-1.3/src/lxml/proxy.pxi	Sun Jul  1 15:18:59 2007
@@ -27,6 +27,8 @@
     #print "registering for:", <int>proxy._c_node
     assert c_node._private is NULL, "double registering proxy!"
     c_node._private = <void*>proxy
+    # additional INCREF to make sure _Document is GC-ed LAST!
+    python.Py_INCREF(proxy._doc)
 
 cdef unregisterProxy(_Element proxy):
     """Unregister a proxy for the node it's proxying for.
@@ -35,6 +37,7 @@
     c_node = proxy._c_node
     assert c_node._private is <void*>proxy, "Tried to unregister unknown proxy"
     c_node._private = NULL
+    python.Py_DECREF(proxy._doc)
 
 ################################################################################
 # temporarily make a node the root node of its document
@@ -170,19 +173,6 @@
     tree.END_FOR_EACH_ELEMENT_FROM(c_node)
     return 1
 
-cdef void _deallocDocument(xmlDoc* c_doc):
-    """We cannot rely on Python's GC to *always* dealloc the _Document *after*
-    all proxies it contains => traverse the document and mark all its proxies
-    as dead by deleting their xmlNode* reference.
-    """
-    cdef xmlNode* c_node
-    c_node = c_doc.children
-    tree.BEGIN_FOR_EACH_ELEMENT_FROM(<xmlNode*>c_doc, c_node, 1)
-    if c_node._private is not NULL:
-        (<_Element>c_node._private)._c_node = NULL
-    tree.END_FOR_EACH_ELEMENT_FROM(c_node)
-    tree.xmlFreeDoc(c_doc)
-
 ################################################################################
 # fix _Document references and namespaces when a node changes documents
 
@@ -303,6 +293,8 @@
             if c_element._private is not NULL:
                 element = <_Element>c_element._private
                 if element._doc is not doc:
+                    python.Py_INCREF(doc)
+                    python.Py_DECREF(element._doc)
                     element._doc = doc
 
             if c_element is c_start_node:
@@ -321,7 +313,11 @@
 
                 # fix _Document reference (may dealloc the original document!)
                 if c_element._private is not NULL:
-                    (<_Element>c_element._private)._doc = doc
+                    element = <_Element>c_element._private
+                    if element._doc is not doc:
+                        python.Py_INCREF(doc)
+                        python.Py_DECREF(element._doc)
+                        element._doc = doc
 
                 if c_element is c_start_node:
                     break

Modified: lxml/branch/lxml-1.3/src/lxml/python.pxd
==============================================================================
--- lxml/branch/lxml-1.3/src/lxml/python.pxd	(original)
+++ lxml/branch/lxml-1.3/src/lxml/python.pxd	Sun Jul  1 15:18:59 2007
@@ -9,6 +9,7 @@
     cdef int PY_SSIZE_T_MAX
 
     cdef void Py_INCREF(object o)
+    cdef void Py_DECREF(object o)
 
     cdef FILE* PyFile_AsFile(object p)
     cdef int PyFile_Check(object p)


More information about the lxml-checkins mailing list