summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRob Bradford <rob@linux.intel.com>2010-08-19 12:08:05 +0100
committerRob Bradford <rob@linux.intel.com>2010-08-19 14:24:20 +0100
commitb0a8504ebeabac2943e3ef632f900f2ea6ad9556 (patch)
tree8a3decdd6611f8fbd2baa691d0173bbdda8cd307
parentd944eebee6cf4200d547648b5fd6d022cc3e9208 (diff)
downloadlibrest-b0a8504ebeabac2943e3ef632f900f2ea6ad9556.tar.gz
xml-parser: Fix rest_xml_node_unref so that is correctly unrefs siblings
-rw-r--r--rest/rest-xml-parser.c56
1 files changed, 28 insertions, 28 deletions
diff --git a/rest/rest-xml-parser.c b/rest/rest-xml-parser.c
index 55b73fa..98c9b48 100644
--- a/rest/rest-xml-parser.c
+++ b/rest/rest-xml-parser.c
@@ -141,40 +141,40 @@ rest_xml_node_ref (RestXmlNode *node)
void
rest_xml_node_unref (RestXmlNode *node)
{
+ GList *l;
+ RestXmlNode *next = NULL;
g_return_if_fail (node);
g_return_if_fail (node->ref_count > 0);
- if (g_atomic_int_dec_and_test (&node->ref_count)) {
- GList *l;
- RestXmlNode *next = NULL;
-
- while (node)
- {
- /*
- * Save this pointer now since we are going to free the structure it
- * contains soon.
- */
- next = node->next;
-
- l = g_hash_table_get_values (node->children);
- while (l)
- {
- rest_xml_node_unref ((RestXmlNode *)l->data);
- l = g_list_delete_link (l, l);
- }
-
- g_hash_table_unref (node->children);
- g_hash_table_unref (node->attrs);
- g_free (node->content);
- g_slice_free (RestXmlNode, node);
-
+ /* Try and unref the chain, this is equivalent to being tail recursively
+ * unreffing the next pointer
+ */
+ while (node && g_atomic_int_dec_and_test (&node->ref_count))
+ {
/*
- * Free the next in the chain by updating node. If we're at the end or
- * there are no siblings then the next = NULL definition deals with this
- * case
+ * Save this pointer now since we are going to free the structure it
+ * contains soon.
*/
- node = next;
+ next = node->next;
+
+ l = g_hash_table_get_values (node->children);
+ while (l)
+ {
+ rest_xml_node_unref ((RestXmlNode *)l->data);
+ l = g_list_delete_link (l, l);
}
+
+ g_hash_table_unref (node->children);
+ g_hash_table_unref (node->attrs);
+ g_free (node->content);
+ g_slice_free (RestXmlNode, node);
+
+ /*
+ * Free the next in the chain by updating node. If we're at the end or
+ * there are no siblings then the next = NULL definition deals with this
+ * case
+ */
+ node = next;
}
}