]> granicus.if.org Git - php/commitdiff
Allow libxml DomNodes to remain persistent when requested by other extensions
authorSara Golemon <pollita@php.net>
Mon, 8 Jan 2007 20:01:23 +0000 (20:01 +0000)
committerSara Golemon <pollita@php.net>
Mon, 8 Jan 2007 20:01:23 +0000 (20:01 +0000)
ext/libxml/libxml.c
ext/libxml/php_libxml.h

index ee66d3d8b19e90cc6b940c996945ce279d325a2a..cbbc4f52d1ccda080bb6164393b25bbbc3a2b442 100644 (file)
@@ -947,7 +947,9 @@ int php_libxml_increment_doc_ref(php_libxml_node_object *object, xmlDocPtr docp
                ret_refcount = object->document->refcount;
        } else if (docp != NULL) {
                ret_refcount = 1;
-               object->document = emalloc(sizeof(php_libxml_ref_obj));
+               object->document = pemalloc(sizeof(php_libxml_ref_obj), 0);
+               object->document->persistent = 0;
+               object->document->external_owner = 0;
                object->document->ptr = docp;
                object->document->refcount = ret_refcount;
                object->document->doc_props = NULL;
@@ -972,9 +974,23 @@ int php_libxml_decrement_doc_ref(php_libxml_node_object *object TSRMLS_DC) {
                                }
                                efree(object->document->doc_props);
                        }
-                       efree(object->document);
+                       pefree(object->document, object->document->persistent);
                        object->document = NULL;
-               }
+               } else if (ret_refcount == 1 && object->document->external_owner) {
+                       /* PHP is done with this object, but someone else owns the DomNodes,
+                        * Kill the non-persistent bits, but leave the persistable php_libxml_ref_obj around */
+                       if (object->document->doc_props != NULL) {
+                               if (object->document->doc_props->classmap) {
+                                       zend_hash_destroy(object->document->doc_props->classmap);
+                                       FREE_HASHTABLE(object->document->doc_props->classmap);
+                               }
+                               efree(object->document->doc_props);
+                               object->document->doc_props = NULL;
+                       }
+                       /* Don't worry about the fact that this memory is left unfreed,
+                        * Whoever else owns it has the pointer stored somewhere */
+                       object->document = NULL;
+               }                       
        }
 
        return ret_refcount;
index 2984fc9608b8d573d14d2494a4e752002fcba5fb..fc4ca2e11cd0e0c4ca646a8e614306d9371cfef0 100644 (file)
@@ -58,6 +58,8 @@ typedef struct _php_libxml_ref_obj {
        void *ptr;
        int   refcount;
        libxml_doc_props *doc_props;
+       zend_bool persistent;
+       zend_bool external_owner;
 } php_libxml_ref_obj;
 
 typedef struct _php_libxml_node_ptr {