wiki:WebKitGTK/GRefPtrAndFloatingRefs

Version 1 (modified by Carlos Garcia Campos, 5 years ago) (diff)

--

GRefPtr and floating references

g_object_new() returns a floating reference for GObjects derived from GInitiallyUnowned. Those are expected to be consumed (converted to a normal reference) when passed to another class. So, for example, GtkWidgets are all GInitiallyUnowned, since in most of the cases you create a widget and then add it to a container. We don't need to care about widgets refcounting in this case because the container is consuming the floating reference and then taking the ownership of the widget.

GRefPtr always uses g_object_ref_sink() for taking references, so that if the object has a floating reference it will be consumed, and if not, the reference counter will be increased in 1 as expected. We should only use GRefPtr with GInitiallyUnowned objects when we actually want to consume the reference, or if we want to prevent the object from being leaked in case of an early return before someone else has consumed the floating reference. That's why adoptGRef should never be used with GInitiallyUnowned, we either consume the reference or don't use GRefPtr at all.

In summary:

  • If we know the floating reference is going to be consumed, and there's not risk of leaking, we use pointers. For example:
button = gtk_button_new();
gtk_container_add(container, button);
  • If we know the floating reference is not going to be consumed, we use GRefPtr without adopting the reference at all. For example:
GRefPtr<GVariant> variant = g_variant_new("i", 25);
char* serializeVariant = g_variant_print(varaint.get(), TRUE);
  • If the floating reference might be consumed, but there's any early return that could leak the reference we use GRefPtr without adopting the reference. For example:
GRefPtr<WebKitWebView> webView = webkit_web_view_new();
if (cancelled)
    return;

gtk_continer_add(window, webView.get());

Of course we should try to avoid this case, and always create the object right before it is going to be added to a container and use plain pointers in that case.

So, why is adoptGRef() so dangerous for GInitiallyUnowned objects? Let's use the last example. If we adopt the WebKitWebView reference and we don't return early, after the gtk_continer_add() the GObject will still have 1 reference, but both the GRrfPtr and the GtkWindow will call g_object_unref().