nlecomposition: ensure elements pending to be added are not leaked
authorAurélien Zanelli <aurelien.zanelli@darkosphere.fr>
Sat, 7 May 2016 18:29:22 +0000 (20:29 +0200)
committerThibault Saunier <tsaunier@gnome.org>
Sat, 14 May 2016 23:50:16 +0000 (20:50 -0300)
When nlecomposition is finalized with pending add action or io,
associated elements are not unreffed as they should since caller gives
us the reference when calling gst_bin_add causing them to be leaked.
So to make sure we don't leak a reference on element when adding one to
the bin, each stage (action and pending_io) hold a reference on element
and release it when stage is done.

https://bugzilla.gnome.org/show_bug.cgi?id=766455

plugins/nle/nlecomposition.c

index 06a5cbad128485160998a4de339b0d0c3f5d0609..f5856dcd08ec6d349a4cdf25359a279831e27667 100644 (file)
@@ -584,7 +584,9 @@ _process_pending_entries (NleComposition * comp)
 
       _nle_composition_remove_object (comp, object);
     } else {
-      _nle_composition_add_object (comp, object);
+      /* take a new ref on object as the current one will be released when
+       * object is removed from pending_io */
+      _nle_composition_add_object (comp, gst_object_ref (object));
     }
   }
 
@@ -688,7 +690,7 @@ _remove_object_func (NleComposition * comp, ChildIOData * childio)
     return;
   }
 
-  g_hash_table_add (priv->pending_io, object);
+  g_hash_table_add (priv->pending_io, gst_object_ref (object));
 
   return;
 }
@@ -738,7 +740,9 @@ _add_object_func (NleComposition * comp, ChildIOData * childio)
     return;
   }
 
-  g_hash_table_add (priv->pending_io, object);
+  /* current reference is hold by the action and will be released with it,
+   * so take a new one */
+  g_hash_table_add (priv->pending_io, gst_object_ref (object));
 }
 
 static void
@@ -765,8 +769,12 @@ _free_action (gpointer udata, Action * action)
 
     gst_event_unref (seekd->event);
     g_slice_free (SeekData, seekd);
-  } else if (ACTION_CALLBACK (action) == _remove_object_func ||
-      ACTION_CALLBACK (action) == _add_object_func) {
+  } else if (ACTION_CALLBACK (action) == _add_object_func) {
+    ChildIOData *iodata = (ChildIOData *) udata;
+
+    gst_object_unref (iodata->object);
+    g_slice_free (ChildIOData, iodata);
+  } else if (ACTION_CALLBACK (action) == _remove_object_func) {
     g_slice_free (ChildIOData, udata);
   } else if (ACTION_CALLBACK (action) == _update_pipeline_func ||
       ACTION_CALLBACK (action) == _commit_func ||
@@ -974,7 +982,8 @@ nle_composition_init (NleComposition * comp)
   g_mutex_init (&priv->actions_lock);
   g_cond_init (&priv->actions_cond);
 
-  priv->pending_io = g_hash_table_new (g_direct_hash, g_direct_equal);
+  priv->pending_io = g_hash_table_new_full (g_direct_hash, g_direct_equal,
+      gst_object_unref, NULL);
 
   comp->priv = priv;