[cairo] cairo_current_xxx, reference or not?

Gustavo J. A. M. Carneiro gjc at inescporto.pt
Fri Nov 5 09:53:11 PST 2004


Sex, 2004-11-05 às 09:28 -0800, Bill Spitzak escreveu:
> 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".

  Yes, I agree with your arguments, but I know my arguments are also
valid :)

  Storing data in the cairo_t is not very nice.  Suppose you do this:

   Something *s1;
   s1 = cairo_get_something(cairo_t);
   cairo_do_something_else(cairo_t);
   x = s1->x;
   y = s1->y;

  Now suppose function cairo_do_something_else calls
cairo_get_something.  In that case the object s1 points to gets
unreffed/deallocated, and when the function returns and the caller
evaluates s1->x, it segfaults or reads garbage.  Same could happen if
you replace cairo_do_something_else with your own function.  This
approach leads to ugly problems, sooner or later.

  Maybe the right way to go is to _not_ have a single return ownership
rule, and just document ownership semantics in every function.  Python C
API seems to get this right, for instance.

  Best regards.

> 
> 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.
> 
-- 
Gustavo J. A. M. Carneiro
<gjc at inescporto.pt> <gustavo at users.sourceforge.net>
The universe is always one step beyond logic.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/x-pkcs7-signature
Size: 3086 bytes
Desc: not available
Url : http://lists.freedesktop.org/archives/cairo/attachments/20041105/6ea0b9c6/smime.bin


More information about the cairo mailing list