[cairo] reference counting vs garbage collection
Bill Spitzak
spitzak at d2.com
Wed Jan 5 11:44:44 PST 2005
On Wednesday 05 January 2005 11:03 am, Keith Packard wrote:
> Around 13 o'clock on Jan 5, Carl Worth wrote:
> > Regardless, it does seem easy enough to remove the conflation:
> >
> > _create Allocate object. refcnt = 1. Connect dependent objects
> > _reference refcnt++
> > _finish Finalize dependent objects
> > _destroy if (--refcnt = 0) { _finish; Free object }
>
> (I believe the term 'close' was used instead of 'finish' in the last
> message proposing this design).
>
> This will work just fine for me, but loses some of the symmetry in the
> create/destroy ref/unref model.
It is symmetric, because "unref" and "destroy" are exactly the same function.
Perhaps one of them can be some kind of alias for the other, by using a macro
or inline function.
I think also there can be many "finish" functions, quite dependent on the
class of object. After calling one of them some other subset of methods will
not work and produce unpredictable results (ie crash), only unref and destroy
are guaranteed to still work. Because of this normal programs should not call
the finish function, you have to really know what you are doing to call it.
You could also do "if refcount==1 finish()" to do it slightly more safely.
Some people are complaining that "finish" should be called "close". In fact
it can be called anything it wants, it is not a virtual function. There can
be a whole set of different "finish" functions. For the ones taking a FILE,
one of them can close, another can flush, another can seek back to the start,
etc.
I do not think destroy should free data allocated by the caller. This has
been shown many times to be a very bad idea. Thus the FILE argument that
started this whole argument should NOT be closed by destroy. However finish
can do this. In this example the "finish" function (called close to make it
more clear what it does) is optional. If not called, the file is flushed by
the destroy, but left open:
FILE* f = fopen(...);
surface = create_png_surface(f);
draw_things(surface);
close_png_surface(surface); // optional, does fclose(file)
destroy(surface);
I know this does not allow reference counting to close the output file, but I
cannot see any realistic scenario where this is a problem. Can somebody
explain where this would happen in a real program? It seems most uses of the
png surface by references would be functions that should continue to work
after the close, so there is no problem having the creator close it.
More information about the cairo
mailing list