[cairo] Returning cached erroneous patterns
behdad at behdad.org
Fri Mar 23 09:12:07 PDT 2007
On Thu, 2007-03-22 at 14:12 -0400, Baz wrote:
> On 22/03/07, Chris Wilson <chris at chris-wilson.co.uk> wrote:
> > Behdad's already fixed the primary case where we created a pattern
> > and explicity put it into an error state. However, it also possible for
> > a user to set an error status on a solid pattern, for example by using
> > it as an argument where a gradient was expected. That has some rather
> > unfortunate side-effects on a widely shared pattern...
> Doesn't this mean it's possible for two threads to have already
> fetched the pattern from the cache, before one of them manages to set
> it to an error state? Even after this patch, I think you can do this
> by calling cairo_pattern_add_color_stop_rgba on a solid pattern
> fetched from the cache twice.
> You can get similar behaviour in user applications by sharing
> gradients then adding color stops. Both threads will see the colour
> stops, and eventually both will see a pattern with an out of memory
> All of this comes from patterns being mutable, for adding color stops,
> and setting user data. Should those operations should even be possible
> on patterns with more than one reference?
Ok, thanks for raising the issue. The problem is that solid patterns
are not immutable as we expected. Giving away the same mutable object
multiple times is definitely wrong.
I wanted to say we should back out the cache, but then I found that the
fix is really easy: instead of reusing patterns from the cache, keep a
pool of freed solid patterns. That is: when using a pattern from the
cache, remove it from the cache, and when freeing a solid pattern of
refcount 1, set its error status to SUCCESS and add it to the cache.
> (waits to be shot down)
"Those who would give up Essential Liberty to purchase a little
Temporary Safety, deserve neither Liberty nor Safety."
-- Benjamin Franklin, 1759
More information about the cairo