[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