[cairo] reference counting vs garbage collection

Owen Taylor otaylor at redhat.com
Mon Jan 3 14:10:29 PST 2005


On Mon, 2005-01-03 at 13:48 -0800, Keith Packard wrote:
> Around 15 o'clock on Jan 3, Owen Taylor wrote:
> 
> > What I'm saying is that the whole fact of having a "PNG surface" with a
> > persistant FILE * is an artifact of doing the API in a weird way and that
> > if we simply take advantage of being pre-1.0 and rework the API to avoid
> > that then we avoid the problem.
> 
> Sure, but we'd like a consistent API for PNG, PDF, PS, MNG etc.  One
> possibility suggested here is the 'cairo_surface_close' API which
> 'finalizes' a surface but leaves it allocated.  That would dump the image
> to the file (when copy_page or show_page hadn't been called) and leave it
> ready to close.

I don't see a consistent API as being worth complicating the single
image case. It obscures the fact that you are just taking an image and 
saving it somewhere in a single operation.

(MNG/APNG, shrug. I think fitting that into the PDF/PS model is just
something cool you could do rather than hugely useful.)

For the PDF/PS case, it wouldn't be crazy (IMO) to just store the whole
thing in memory. A random big PDF I have around (ia32 instruction
reference
is only 7meg.) But say we don't want to do that, then as I said earlier,
a FILE * is in this uncomfortable middle ground between convenient and
flexible. It doesn't work for vfs's, it doesn't really work well for
language bindings.

You want a simple 'const char * filename' API for convenience. No memory
management issues there. And then you need a more flexible "write
another
chunk of bytes" API. Something along the lines of:

 cairo_pdf_surface_set_output_func (cairo_surface_t       *surface,
                                    cairo_write_func_t     func,
                                    void *                 data,
                                    cairo_destroy_notify_t destroy);

Note that you make the callback on done tied to the output function,
not to the lifetime of the object. If someone sets another output
function, the callback gets called. Reentrancy on the destroy notify
is not a big issue here; you just hold the data/destroy around until 
you've released all the locks. 

Reentrancy on the write_func is perhaps more of an issue; but it's
certainly possible with a little bit of programming to never call
it with any internal locks held. You just have to determine what
thread safety guarantees you want to make.

There is some argument that tying close() on a stream to destruction
of that stream is wrong; that they should be separate operations. If 
you want to support that, then I think all you need to add is an finish
() ... 
let the caller worry about ordering finish() (which flushes) close() 
(not via cairo) and cairo_surface_destroy().

Regards,
				Owen

-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: This is a digitally signed message part
Url : http://lists.freedesktop.org/archives/cairo/attachments/20050103/62318de0/attachment.pgp


More information about the cairo mailing list