Skip to content
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

Object property reference leak #82

Open
kugel- opened this issue Nov 6, 2016 · 9 comments
Open

Object property reference leak #82

kugel- opened this issue Nov 6, 2016 · 9 comments
Labels

Comments

@kugel-
Copy link

kugel- commented Nov 6, 2016

I'm trying to create an instance of a GObject-derived type (defined in Ruby) in C code. If that type has a property of type GObject (i..e reference counted) the reference seems to leak after freeing the type. To be clear, references to the property object are leaking, not the reference to the object that has the property.

Here's a small program that reproduces the problem:

https://gist.github.com/kugel-/0b051d9a22516ea53b48d33009d11175

@mvz
Copy link
Owner

mvz commented Nov 12, 2016

GirFFI is not really intended to be used in this way: The set up of finalizers probably isn't triggered if you intantiate the object from C.

@mvz
Copy link
Owner

mvz commented Nov 12, 2016

Incidentally, can you get this to work with Ruby-GNOME2?

@kugel-
Copy link
Author

kugel- commented Nov 12, 2016

ruby-gnome2 doesn't support interfaces at this time. My focus went to GirFFI after I found that (although I was able to bring interface support with a quick hack).

Regarding the leak: I don't think it's related finalization at all. I can see that in value.rb, Value#get_value (via set_instance_enhanced) increments the ref_count (when assigning a gobject property). But that is never decremented again. The finalizer just decrements the ref count of the container object which does by itself not unref properties. IMO Value#get_value should not increment the ref_count, why is this done?

Regarding the setup of finalizers (this issue is orthogonal)
I experimented a bit, there are two possible ways:

  1. There are more class methods we can attach to, e.g. GObjectClass->constructed and GObjectClass->dispose(). Using these we can hook into the construction/destruction even if native code does g_object_new() Especially constructed seems useful as it allows to get rid of predefining initialize on the Ruby side. What do you think?

  2. I can setup this so that the instance is created with Ruby but that complicates passing construct properties.

PS: For I'm struggling wih #63 which is a show-stopper for my project (libpeas support for ruby)

@mvz
Copy link
Owner

mvz commented Nov 12, 2016

Value#get_value needs to increment the ref_count because it creates a new Ruby object that needs to have ownership of the GObject object, while at the same time it needs to hold on to its own reference.

@mvz
Copy link
Owner

mvz commented Nov 12, 2016

However, I don't think any of the Ruby implementation of Value is called in your example. I'm investigating further to see what's happening exactly.

@kugel-
Copy link
Author

kugel- commented Nov 12, 2016

It is, I tracked it. set_instance_enhanced is called for the object property.

gobjects aren't ref'd by default when it is assigned to a property. Maybe here's some confusion?

@mvz
Copy link
Owner

mvz commented Nov 12, 2016

Ah yes, #get_value is in fact called in the setter.

The only solution I can see is for me to extend the finalizer for Value to also lower the reference count of any object it holds.

@mvz
Copy link
Owner

mvz commented Nov 12, 2016

By the way, do you have an example of what currently doesn't work in ruby-gnome2?

@kugel-
Copy link
Author

kugel- commented Nov 12, 2016

ruby-gnome2 doesn't setup vfuncs when implementing an interface. in fact it doesn't handle include MyInterface at all yet. I have a quick hack to add that but it needs more work to be acceptable.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants