GNOME Bugzilla – Bug 693800
Problem with ref counter in adding/removing element to/from bin more than once
Last modified: 2013-02-15 14:31:24 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.
This is as designed, what's the problem?
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);
Can this be closed then?
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