[cogl] cogl-pipeline: Fix reference counting on promoting weak parents



commit 17a558a386d41444b926f9e8bec46f74d437745a
Author: Neil Roberts <neil linux intel com>
Date:   Wed Jul 6 12:28:07 2011 +0100

    cogl-pipeline: Fix reference counting on promoting weak parents
    
    When a copy is made of a weak pipeline it tries to promote the weak
    parent by taking a reference on that weak pipeline's parent. However
    promote_weak_ancestors was instead always taking a reference on the
    first parent, regardless of whether it was weak. The corresponding
    revert_weak_ancestors function which is supposed to undo the effect of
    promote_weak_ancestors only unref'd the parent if was weak. This meant
    that any non-weak pipeline copy would end up leaking a reference on
    its parent.
    
    This patch changes both functions to have a similar loop. It loops
    through all of the parents of the pipeline until it finds one that is
    not weak and refs or unrefs the *parent* of that pipeline instead of
    the pipeline itself.
    
    Signed-off-by: Robert Bragg <robert linux intel com>

 cogl/cogl-pipeline.c |   39 +++++++++++++++++++++------------------
 1 files changed, 21 insertions(+), 18 deletions(-)
---
diff --git a/cogl/cogl-pipeline.c b/cogl/cogl-pipeline.c
index db9d29b..ce08203 100644
--- a/cogl/cogl-pipeline.c
+++ b/cogl/cogl-pipeline.c
@@ -375,37 +375,40 @@ _cogl_pipeline_promote_weak_ancestors (CoglPipeline *strong)
 
   g_return_if_fail (!strong->is_weak);
 
-  for (n = COGL_PIPELINE_NODE (strong)->parent; n; n = n->parent)
-    {
-      CoglPipeline *pipeline = COGL_PIPELINE (n);
+  /* If the parent of strong is weak, then we want to promote it by
+     taking a reference on strong's grandparent. We don't need to take
+     a reference on strong's direct parent */
 
-      cogl_object_ref (pipeline);
+  if (COGL_PIPELINE_NODE (strong)->parent == NULL)
+    return;
 
-      if (!pipeline->is_weak)
-        return;
-    }
+  for (n = COGL_PIPELINE_NODE (strong)->parent;
+       /* We can assume that all weak pipelines have a parent */
+       COGL_PIPELINE (n)->is_weak;
+       n = n->parent)
+    /* 'n' is weak so we take a reference on its parent */
+    cogl_object_ref (n->parent);
 }
 
 static void
 _cogl_pipeline_revert_weak_ancestors (CoglPipeline *strong)
 {
-  CoglPipeline *parent = _cogl_pipeline_get_parent (strong);
   CoglPipelineNode *n;
 
   g_return_if_fail (!strong->is_weak);
 
-  if (!parent || !parent->is_weak)
-    return;
-
-  for (n = COGL_PIPELINE_NODE (strong)->parent; n; n = n->parent)
-    {
-      CoglPipeline *pipeline = COGL_PIPELINE (n);
+  /* This reverts the effect of calling
+     _cogl_pipeline_promote_weak_ancestors */
 
-      cogl_object_unref (pipeline);
+  if (COGL_PIPELINE_NODE (strong)->parent == NULL)
+    return;
 
-      if (!pipeline->is_weak)
-        return;
-    }
+  for (n = COGL_PIPELINE_NODE (strong)->parent;
+       /* We can assume that all weak pipelines have a parent */
+       COGL_PIPELINE (n)->is_weak;
+       n = n->parent)
+    /* 'n' is weak so we unref its parent */
+    cogl_object_unref (n->parent);
 }
 
 /* XXX: Always have an eye out for opportunities to lower the cost of



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]