mvz / gir_ffi

Auto-generate bindings for GObject based libraries at run time using FFI

Home Page:https://github.com/mvz/gir_ffi/wiki

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Object property reference leak

kugel- opened this issue · comments

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

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.

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

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)

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.

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.

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?

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.

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

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.