-
-
Notifications
You must be signed in to change notification settings - Fork 103
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Missing support for floating references #367
Comments
If you apply the pull request, the testcase from the gist prints 0 (and accesses freed memory while doing so). Without the pull request it prints 1 and the button is leaked. |
Thanks for explanation and fix. |
Keep in mind though that the printing of the final reference count (0) is an invalid memory access (to already freed memory).
Now we just need to decide whether you want to generate different code for GObject and GInitiallyUnowned (i.e. g_object_ref() vs. g_object_ref_sink()). The performance penalty of the latter should be minimal, but it would be cleaner. However that would require some changes to the parser, code generator and the macro. E.g. it could use Let me know if you want me to update everything according to that, or if the fix from the pull request is enough for now. |
IMHO your fix is enough. I don't think |
Also I don't like introduce |
Compare https://git.gnome.org/browse/glib/tree/gobject/gobject.c#n2972 (calling https://git.gnome.org/browse/glib/tree/gobject/gobject.c#n2912 ) and https://git.gnome.org/browse/glib/tree/gobject/gobject.c#n3174 . Shouldn't matter for any GTK code really. I also wouldn't introduce InitiallyUnowned into Rust code, just that the identifier is there for the macro so that the macro can decide on the correct ref-function... and then map both to Object for all other purposes. |
Basically having the glib_wrapper!() macro also match on pub struct $name:ident(InitiallyUnowned<$ffi_name:path>): $($implements:path),+; etc., and map that to glib_object_wrapper!() with just some argument or so to let it us a different ref-function. |
Oh nevermind, this all works a bit different via the ObjectRef. So we would have to map those to some InitiallyUnownedRef instead, exposing that in the Rust API. But if that is acceptable, I can do the changes. Your call in the end :) |
IMHO even if we decide that we need separate ObjectRef this better not do in current PR pack |
Fine with me, just let me know if you want that at a later time and I can work on it :) |
Requires gtk-rs/gir#365 gtk-rs/gir#364 to be merged for autogeneration of the bindings. Requires gtk-rs/gir#367 for fixing memory leaks.
Let's close this for now then? |
We generally wait for the PR to get merged. |
That happened already, or am I missing something? :) |
Euh... I think I missed something haha. Time to sleep I think. Thanks again for doing it! :) |
Requires gtk-rs/gir#365 gtk-rs/gir#364 to be merged for autogeneration of the bindings. Requires gtk-rs/gir#367 for fixing memory leaks.
See this for background: https://developer.gnome.org/gobject/stable/gobject-The-Base-Object-Type.html#floating-ref
Everything inheriting from GInitiallyUnowned (+ corner cases) allow "floating references". This affects GtkWidgets and GstElements for example. tl;dr is the following:
This is all for some "C programming convenience" (aka footgun often enough). As you can see, this can easily cause leaks or crashes. E.g. gst_bin_add(), gst_bin_remove(), gst_bin_add() will cause the first add() to not increase reference count (it's owned by the bin now), remove() will cause refcount-- (which might destroy the object), the second add() will refcount++ in any case.
What all other bindings are doing is that everything that arrives on the bindings side gets its floating flag removed (as it's just "C convenience"), and then normal reference counting happens. Which means that things like the functions in 2) would be "transfer none" (bug in gst_bin_add(), see https://bugzilla.gnome.org/show_bug.cgi?id=782499), and all kinds of constructors of such objects are also "transfer none" (aka "transfer floating"). You call g_object_ref_sink() whenever getting such object as "transfer none", and from there on all just works as usual.
What I would propose now is one of two options, but both result in not having any floating references ever at the gtk-rs level:
Functionally both are the same, but g_object_ref_sink() is minimally more expensive than g_object_ref(). I think we should not care about that for now and just fix the memory leaks (see e.g. https://gist.github.com/sdroege/13459c559040c11b23733ac55d7aa9a7).
In addition double-checking has to happen that all wrappers around GInitiallyUnowned _new() functions use from_glib_none() correctly.
The text was updated successfully, but these errors were encountered: