Commits

ElDiabolo  committed 9967285

More tests for reference counting

  • Participants
  • Parent commits 3825a47

Comments (0)

Files changed (3)

     OUTPUT:
         RETVAL
 
+int 
+refcnt( n )
+        void *n
+    CODE:
+        xmlNode *node = n;
+        RETVAL = PmmREFCNT(((ProxyNode *)(node->_private)));
+    OUTPUT:
+        RETVAL
+
 int
 fix_owner( n, p )
         void * n

File lib/XML/LibXML/Devel.pm

   node_from_perl
   refcnt_inc
   refcnt_dec
+  refcnt
   fix_owner
   mem_used
 ) ] );
 subtree, refcnt_dec will fix the reference counts and delete
 the subtree if it is not required any more.
 
-=item refcnt_dec
+=item refcnt
+
+  refcnt($raw_node);
+
+Returns the value of the reference counter. 
+
+=item fix_owner
 
   fix_owner($raw_node, $raw_parent);
 
 use Test::More;
-BEGIN { plan tests => 3 };
+BEGIN { plan tests => 18 };
 
 use warnings;
 use strict;
 
 # Base line
 {
+  my $doc = XML::LibXML::Document->new();
+
   my $raw;
-  my $doc = XML::LibXML::Document->new();
   my $mem_before = mem_used();
   {
     my $node = $doc->createTextNode("Hello");
   
     $raw = node_from_perl($node);
     refcnt_inc($raw);
+  } 
+  cmp_ok(mem_used(), '>', $mem_before);
+  is(refcnt_dec($raw), 1);
+  is(mem_used(), $mem_before);
+
+  # Next group of checks - multiple nodes
+  my ($rawT, $rawN);
+  $mem_before = mem_used();
+  {
+    my $node = XML::LibXML::Element->new( 'text' );
+    my $text = $doc->createTextNode( "Hello" );
+
+    $rawN = node_from_perl($node);
+    $rawT = node_from_perl($text);
+
+    refcnt_inc($rawN);
+    refcnt_inc($rawT);
+
+    $node->appendChild($text);
+
+    # Done by appendChild
+    # fix_owner($rawT, $rawN);
   }
+  cmp_ok(mem_used(), '>', $mem_before);
+  is(refcnt_dec($rawN), 2);
+  is(refcnt_dec($rawT), 1);
+  is(mem_used(), $mem_before);
+
+  # The owner node remains until the last node is gone 
+  my ($rawR, $rawD);
+  $mem_before = mem_used();
+  {
+    my $dom = XML::LibXML->load_xml(string => <<'EOT');
+<?xml version="1.0"?>
+<test>
+  <text>Hello</text>
+</test>
+EOT
+    my ($root) = $dom->getElementsByTagName('test'); 
+    $rawR = node_from_perl($root);
+    $rawD = node_from_perl($dom);
+
+    is(refcnt($rawR), 1);
+    is(refcnt($rawD), 2);
+
+    my ($node) = $dom->getElementsByTagName('text'); 
+    $rawN = node_from_perl($node);
+    
+    is(refcnt($rawN), 1);
+    is(refcnt($rawR), 1);
+    is(refcnt($rawD), 3);      
+
+    refcnt_inc($rawN);
+
+    is(refcnt($rawD), 3);      
+
+    my $child = $node->firstChild;
+
+    is(refcnt($rawD), 4);      
+  }
+  cmp_ok(mem_used(), '>', $mem_before);
+  # $rawR's proxy node is no longer accessible
+  # but $rawD still has one
+  is(refcnt($rawD), 1);      
+  is(refcnt_dec($rawN), 1);
+  is(mem_used(), $mem_before);
   
-  cmp_ok(mem_used(), '>', $mem_before);
-
-  is(1, refcnt_dec($raw));
-
-  is($mem_before, mem_used());
-
 }