]> granicus.if.org Git - poly2tri-c/commitdiff
cherry-pick the relevant parts of commit dd3660fd4418 from the GEGL copy of
authorawaw fumin <awawfumin@gmail.com>
Wed, 2 Apr 2014 23:41:28 +0000 (02:41 +0300)
committerBarak Itkin <lightningismyname@gmail.com>
Wed, 2 Apr 2014 23:46:56 +0000 (02:46 +0300)
the library

[PATCH] operations: Fix memory leaks in seamless clone

The leaks detected and fixed herein were discovered using the
"Leaks" template in Apple's "Instruments" tool.
At least according to Instruments, there are completely no leaks anymore
after applying the fixes in this commit.

poly2tri-c/refine/cdt.c
poly2tri-c/refine/cluster.c
poly2tri-c/refine/delaunay-terminator.c
poly2tri-c/refine/mesh.c

index 7dc1d113ce47092db79f1f3d67bf874b1fbbcdd4..4929d344c39f09a496d9ba1a407ba957655e4526 100644 (file)
@@ -319,6 +319,8 @@ p2tr_cdt_insert_point (P2trCDT           *self,
           GList *parts = p2tr_cdt_split_edge (self, edge, pt), *eIter;
           for (eIter = parts; eIter != NULL; eIter = eIter->next)
             p2tr_edge_unref ((P2trEdge*)eIter->data);
+          g_list_free(parts);
+
           inserted = TRUE;
           break;
         }
index 3e6ce25567edddfb281c68948493cb491ea07f5f..ba04435d7dcfc4f5edf685ec6a33ded91e040b54 100644 (file)
@@ -81,7 +81,7 @@ p2tr_cluster_get_for (P2trPoint   *P,
 
   g_queue_push_head (&cluster->edges, p2tr_edge_ref (E));
 
-  current = E;
+  current = p2tr_edge_ref (E);
   next = p2tr_point_edge_cw (P, current);
   
   while (next != g_queue_peek_head (&cluster->edges)
@@ -89,22 +89,29 @@ p2tr_cluster_get_for (P2trPoint   *P,
       && p2tr_cluster_cw_tri_between_is_in_domain (current, next))
     {
       g_queue_push_tail (&cluster->edges, p2tr_edge_ref (next));
+      p2tr_edge_unref (current);
       current = next;
       next = p2tr_point_edge_cw (P, current);
       cluster->min_angle = MIN (cluster->min_angle, temp_angle);
     }
+  p2tr_edge_unref (current);
+  p2tr_edge_unref (next);
 
-  current = E;
+  current = p2tr_edge_ref (E);
   next = p2tr_point_edge_ccw(P, current);
+  p2tr_edge_unref(next);
   while (next != g_queue_peek_tail (&cluster->edges)
       && (temp_angle = p2tr_edge_angle_between (current->mirror, next)) <= P2TR_CLUSTER_LIMIT_ANGLE
       && p2tr_cluster_cw_tri_between_is_in_domain (next, current))
     {
       g_queue_push_head (&cluster->edges, p2tr_edge_ref (next));
+      p2tr_edge_unref (current);
       current = next;
       next = p2tr_point_edge_ccw (P, current);
       cluster->min_angle = MIN(cluster->min_angle, temp_angle);
     }
+  p2tr_edge_unref (current);
+  p2tr_edge_unref (next);
 
   return cluster;
 }
index 48ff030798f64386fa1cd1dce049fe7ec0d5a9e2..1de1fea5da224126834d9624de923c41ff4180e5 100644 (file)
@@ -105,6 +105,8 @@ p2tr_cdt_get_segments_encroached_by (P2trCDT   *self,
        * since it's still faster */
       if (e->constrained && p2tr_cdt_is_encroached (e))
         p2tr_vedge_set_add2 (encroached, p2tr_vedge_new2 (e));
+
+      p2tr_edge_unref(e);
     }
 
   return encroached;
@@ -431,6 +433,9 @@ SplitEncroachedSubsegments (P2trDelaunayTerminator *self, gdouble theta, P2trTri
               p2tr_dt_enqueue_segment (self, e);
             p2tr_edge_unref (e);
           }
+
+        g_list_free(parts);
+        p2tr_point_unref(Pv);
       }
     p2tr_edge_unref (s);
   }
index bbeadd3fc8e95015c999f71d03d64c80c8503f17..7fc192f9c7187cdd4d67e3163f7d96026ffc5f5f 100644 (file)
@@ -200,11 +200,11 @@ p2tr_mesh_action_group_commit (P2trMesh *self)
 
   g_assert (self->record_undo);
 
+  self->record_undo = FALSE;
+
   for (iter = self->undo.head; iter != NULL; iter = iter->next)
     p2tr_mesh_action_unref ((P2trMeshAction*)iter->data);
   g_queue_clear (&self->undo);
-
-  self->record_undo = FALSE;
 }
 
 void
@@ -214,14 +214,16 @@ p2tr_mesh_action_group_undo (P2trMesh *self)
 
   g_assert (self->record_undo);
 
+  /* Set the record_undo flag to FALSE before p2tr_mesh_action_undo, so that
+   * we don't create zombie objects therein. */
+  self->record_undo = FALSE;
+
   for (iter = self->undo.tail; iter != NULL; iter = iter->prev)
     {
       p2tr_mesh_action_undo ((P2trMeshAction*)iter->data, self);
       p2tr_mesh_action_unref ((P2trMeshAction*)iter->data);
     }
   g_queue_clear (&self->undo);
-
-  self->record_undo = FALSE;
 }
 
 void