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 730967 - Bind g_binding_unbind
Bind g_binding_unbind
Status: RESOLVED FIXED
Product: vala
Classification: Core
Component: Bindings
0.24.x
Other Linux
: Normal normal
: ---
Assigned To: Vala maintainers
Vala maintainers
Depends on:
Blocks:
 
 
Reported: 2014-05-30 00:11 UTC by Jim Nelson
Modified: 2014-05-31 11:01 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
Adds unbind() to Binding (372 bytes, patch)
2014-05-30 18:54 UTC, Jim Nelson
none Details | Review

Description Jim Nelson 2014-05-30 00:11:24 UTC
Right now the only way I know of to drop a property binding is to unref the Binding object twice:

Binding b = o.bind_property(...);
b.unref();
b = null;

The assignment to null being the second unref.  This strikes me as error-prone and not particularly discoverable.

I'm not sure of the most elegant solution to this, but I would think that (this is going to be confusing) binding g_binding_unbind() to Binding is bound to make more sense, i.e. Binding.unbind().
Comment 1 Luca Bruno 2014-05-30 06:56:48 UTC
I don't know why bind_property is marked as unowned. In C they say it's transfer none, but g_object_bind_property_full returns a gobject instance and it does not seem that "glib" owns that reference.
Should it be transfer full instead of transfer none?
Comment 2 Emmanuele Bassi (:ebassi) 2014-05-30 09:09:48 UTC
no, the annotation for g_object_bind_property* is correct: the Binding instance returned is automagically memory managed: you *can* unref the returned value, or call unbind()+unref(), but the binding instance itself goes away if either source or target go away as well. this way, it's possible to completely ignore the returned GBinding instance without leaking it.

language bindings without ref/unref access can expose g_binding_unbind() in case the developer wants to keep a reference to the GBinding instance for later.
Comment 3 Luca Bruno 2014-05-30 09:13:17 UTC
Thanks Emmanuele. Therefore this is the correct behavior in Vala. If you want to unbind, you have to call .unref() (or .unbind() if I understood correctly).
The fact that you have to assign = null it's because you are assigning the binding to an owned variable. The following would not require the additional null assignment:

unowned Binding b = o.bind_property(...);
b.unref();

Closing, please reopen if needed.
Comment 4 Jim Nelson 2014-05-30 18:53:47 UTC
I'm reopening because my original intention was to get g_binding_unbind() bound in Vala.  Right now it's not, so double unref() is the only way to do it, which I find error-prone.  What I'm proposing is for g_binding_unbind() to be bound to Binding.unbind(), which is currently unavailable.

I'll attach a patch that adds this binding.
Comment 5 Jim Nelson 2014-05-30 18:54:13 UTC
Created attachment 277582 [details] [review]
Adds unbind() to Binding
Comment 6 Emmanuele Bassi (:ebassi) 2014-05-30 22:58:03 UTC
why double unref? a single unref should be enough to dispose of the binding through the GBinding instance (the binding itself will go away if either objects involved in the binding will go away). unless vala is holding a reference by its own, obviously.

from a C perspective, g_binding_unbind() works exactly like g_object_unref() - in fact, g_binding_unbind() is called from the finalize() implementation of the GBinding class: https://git.gnome.org/browse/glib/tree/gobject/gbinding.c#n478
Comment 7 Jim Nelson 2014-05-31 01:21:32 UTC
(In reply to comment #6)
> why double unref? a single unref should be enough to dispose of the binding
> through the GBinding instance (the binding itself will go away if either
> objects involved in the binding will go away). unless vala is holding a
> reference by its own, obviously.

Ah, my mistake.  My original code was like this:

Binding b = o.bind_property(...);

b is an owned reference, but bind_property() returns an unowned reference, so Vala is adding its own reference.  It takes one unref() to drop that reference and another to drop the one held by the binding.  This is how it should be:

unowned Binding b = o.bind_property(...);

Then a single unref() would do the trick.

Anyway, I hope my patch lands -- I think it clears the situation and makes the semantics simpler for coders.
Comment 8 Luca Bruno 2014-05-31 11:01:01 UTC
commit c72f0ce11f641f30ef334aaa43d925f480692375
Author: Luca Bruno <lucabru@src.gnome.org>
Date:   Sat May 31 12:59:04 2014 +0200

    gobject: Add Binding.unbind
    
    Fixes bug 730967

This problem has been fixed in the development version. The fix will be available in the next major software release. Thank you for your bug report.