After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 693800 - Problem with ref counter in adding/removing element to/from bin more than once
Problem with ref counter in adding/removing element to/from bin more than once
Status: RESOLVED NOTABUG
Product: GStreamer
Classification: Platform
Component: gstreamer (core)
1.x
Other Linux
: Normal normal
: git master
Assigned To: GStreamer Maintainers
GStreamer Maintainers
Depends on:
Blocks:
 
 
Reported: 2013-02-14 14:41 UTC by Alexander Schrab
Modified: 2013-02-15 14:31 UTC
See Also:
GNOME target: ---
GNOME version: ---



Description Alexander Schrab 2013-02-14 14:41:32 UTC
This case:

  GstElement *element = gst_element_factory_make("fakesink", NULL);
  GstBin *bin = (GstBin*)gst_bin_new("test");
  g_print("refcount: %u\n", GST_OBJECT_REFCOUNT(element));
  gst_bin_add(bin, gst_object_ref(element));
  g_print("refcount: %u\n", GST_OBJECT_REFCOUNT(element));
  gst_bin_remove(bin, element);
  g_print("refcount: %u\n", GST_OBJECT_REFCOUNT(element));
  gst_bin_add(bin, gst_object_ref(element));
  g_print("refcount: %u\n", GST_OBJECT_REFCOUNT(element));
  gst_bin_remove(bin, element);

Should result in the refcount being 'stable' since gst_bin_add has a full transfer and to keep the ref outside you need to ref once more. This is not the case however, the ref increases. The scary part is that it does not increase the first time. The reason is that part of the operation is gst_object_set_parent, which takes the floating reference. The first time we do this the element is indeed floating and the ref count is not changed, the rest of the time it will increase the ref by one.

If we do indeed want the floating ref to behave as it does then we need to unref when setting parent to NULL in bin_remove (we just set the variable to NULL right now). This will however cause the ref count to drop to zero since we 'steal' a reference count from the outside when doing that (the floating one). I will take a look at a possible solution tomorrow.
Comment 1 Wim Taymans 2013-02-14 14:44:09 UTC
This is as designed, what's the problem?
Comment 2 Alexander Schrab 2013-02-14 17:59:08 UTC
Ok, after reading up on the initially unknown and looking around I realize this is as designed. So in my case the correct form would be:
  
  GstElement *element = gst_ref_sink(gst_element_factory_make("fakesink", NULL));
  GstBin *bin = (GstBin*)gst_bin_new("test");
  g_print("refcount: %u\n", GST_OBJECT_REFCOUNT(element));
  gst_bin_add(bin, element);
  g_print("refcount: %u\n", GST_OBJECT_REFCOUNT(element));
  gst_bin_remove(bin, element);
  g_print("refcount: %u\n", GST_OBJECT_REFCOUNT(element));
  gst_bin_add(bin, element);
  g_print("refcount: %u\n", GST_OBJECT_REFCOUNT(element));
  gst_bin_remove(bin, element);
Comment 3 Tim-Philipp Müller 2013-02-15 12:47:46 UTC
Can this be closed then?
Comment 4 Alexander Schrab 2013-02-15 14:31:24 UTC
Yes... It's closed :)

But I must say the use of initially unowned seems error prone and I don't really see any benefit. But I guess it's a matter of taste :P