[cairo] cairo_current_xxx, reference or not?
Bill Spitzak
spitzak at d2.com
Fri Nov 5 09:28:16 PST 2004
On Friday 05 November 2004 08:23 am, Gustavo J. A. M. Carneiro wrote:
> > Either always or never--there are arguments for both sides, and I don't
> > know which side I come down on just yet.
>
> IMHO, it has to be "always". Say you have a function returning a new
> object, which the function doesn't need (it is created specifically for
> the caller). If you return a shared reference, when is the owner of the
> initial reference going to unref? Next call to the same function? That
> would mean storing a pointer somewhere, like in a static variable. What
> if the function doesn't get called again soon? Surely you can see this
> path leads to confusion...
I just want to put in my argument for "never".
The main reason for "never" is so you can write
function(cairo_get_something(cairo_t)).
If you have to deallocate then you need to do this:
Something* temp = cairo_get_something(cairo_t);
function(temp);
cairo_deallocate_something(cairo_t, temp);
This often makes the code harder to understand and is just a pain in many
cases, and Cairo is trying to be a programmer-friendly interface.
Also there is the obvious overhead of allocating the copy. This annoys people
who really are interested in getting things to run as fast as possible.
Demonstrations that the overhead is minor does not convince anybody, since no
matter how small, they know it can be less.
The return values should be stored in per-cairo_t static locations. It should
be clear that the next call on that cairo_t that would change the result, or
the next call to get the same type of data, may destroy or overwrite the
returned data. Yes, I know this is bad programming practice, but this is a
graphics API, the typical length of an interaction is quite short and
consists of many sequential calls, and it is easy for a programmer to keep
track of. Probably easier than keeping track of the temporary values.
Calls to different cairo_t's will *not* destroy the data, each has it's own
static storage. Carl has already said that sharing a cairo_t between threads
is not going to be thread-safe, so this in no way reduces thread safety.
Anybody wanting a copy can copy the return value themselves. Things that
cannot be copied like surfaces can have a reference counter but there should
be a seperate call to increment it. This puts the increment/decrement calls
in the same part of the code. Destroying the cairo_t will destroy everything
irregardless of the reference count.
The use of const to indicate this is a good idea. The "increment reference
count" function could take a const pointer and return a non-const one, and
decrement only takes a non-const one.
More information about the cairo
mailing list