RFC: Are toggle references needed for CoglHandle ?



Hi

I've started looking at the Ruby bindings for Clutter and I was
wondering about how best to bind CoglHandles. Currently they are just
wrapped as a boxed type. This has the effect that every time you query a
property that is a CoglHandle then the result appears as a completely
new object to the eyes of the interpreter. For example:

# This creates a new ClutterTexture
irb(main):003:0> tex = Clutter::Texture.new("redhand.png")
=> #<Clutter::Texture:0x86070c0 ptr=0x86580a8>

# This queries the 'cogl_texture' property which returns the boxed
# CoglHandle.
irb(main):005:0> handle1 = tex.cogl_texture
=> #<Cogl::Texture:0x85d8190 ptr=0x8649db8 own=true>

# If we query it a second time we can see that we've got a different
# object
irb(main):006:0> handle2 = tex.cogl_texture
=> #<Cogl::Texture:0x85d4610 ptr=0x8649db8 own=true>
irb(main):008:0> handle1.object_id
=> 70172872
irb(main):009:0> handle2.object_id
=> 70165256

This isn't a major problem but it does mean that you can't attach data
to the Ruby object or subclass it and expect it to survive if you set it
as a property. Eg:

# Create a new Cogl texture
irb(main):010:0> handle = Cogl::Texture.new("redhand.png")
=> #<Cogl::Texture:0x85c574c ptr=0x86400b8 own=true>

# Set some data on it
irb(main):021:0> handle.instance_variable_set(:@some_data, [1,2,3])
=> [1, 2, 3]

# Put it in the ClutterTexture
irb(main):023:0> tex.cogl_texture = handle
=> #<Cogl::Texture:0x85c574c ptr=0x86400b8 own=true>

# If we query it back out then the data is lost
irb(main):024:0> tex.cogl_texture.instance_variable_get(:@some_data)
=> nil

Recently Cogl in git has gained support for attaching arbitrary user
data to any handle using a pointer as a key in much the same way as
Cairo does. We could use this to attach the Ruby proxy object to the
handle so that it could return the same object every time the handle is
seen. However if we do this then we need to resolve the issue that both
the proxy object and the GObject will need to reference each other yet
we still want them to be garbage collected. Most languages that bind
GObject seem to use toggle references to fix this. So my question is,
should we add toggle reference support to CoglHandles?

I think for languages with a mark-sweep garbage collector (like Ruby) we
could get away without toggle references if the reference count on the
handle was publicly visible. I would imagine you would then need to
store a list of all GObjects that Ruby has ever seen and then during the
mark phase you simply need to walk the list and mark any objects that
have a ref count > 1 (meaning something in GLib-land is also using the
object). However my hunch is that this isn't sufficient for languages
that use ref-counting for their own garbage collection because then
there'd be no equivalent of the mark phase.

CoglHandles are pretty similar to GstMiniObjects and cairo's object
system as far as I can tell. How is binding handled for those? As far as
I can tell for cairo Python just creates a new wrapper object each time:

>>> surface = cairo.SVGSurface('out.svg', 100, 100)
>>> cr = cairo.Context(surface)
>>> source1 = cr.get_source()
>>> source2 = cr.get_source()
>>> id(source1)
3078983840L
>>> id(source2)
3078983856L

Ruby seems to use Cairo's user data retain the proxy object, but looking
at the code I can't work out why this doesn't cause a leak (maybe it
does).

irb(main):002:0> surface = Cairo::SVGSurface.new('out.svg', 100, 100)
=> #<Cairo::SVGSurface:0xb764ce4c>
irb(main):003:0> cr = Cairo::Context.new(surface)
=> #<Cairo::Context:0xb764a228>
irb(main):004:0> source1 = cr.source
=> #<Cairo::SolidPattern:0xb7648270>
irb(main):005:0> source2 = cr.source
=> #<Cairo::SolidPattern:0xb7648270>
irb(main):006:0> source1.object_id
=> -609074888
irb(main):007:0> source2.object_id
=> -609074888

Both cairo and GstMiniObject publicly expose the ref count. Would this
be enough for bindings?

Any help is much appreciated.

Regards,
- Neil


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]