[cairo] Thoughts on thread safety of user-data

Behdad Esfahbod behdad at behdad.org
Thu Jul 24 11:22:51 PDT 2008


Hi,

The more I thought about how to use cairo user-data from Pango and be
thread safe, the more I think it's impossible without introducing a
mutex in the Pango code just for that.  And that's not optimal.  I'm not
proposing any changes here, just thought I share and see if others have
any better solutions.

The problem I want to solve is to attaach a user data to a cairo object
on demand.  I don't care if an extra user data is created and destroyed
immediately as a side effect of multiple threads trying to do it.  So I
expect something like this:

  if (!cairo_get_user_data (cr, key)) {
    void *p = create_user_data ();
    cairo_set_user_data (cr, key, p, user_data_destroy);
  }

  user_data = cairo_get_user_data (cr, key);
  ...

However, this doesn't work as if two threads try to initialize the user
data at the same time, one of them may fetch a user_data and try to use
it, while the other one frees that user data as a side effect of
resetting it.  I don't see any way to fix this other than also accepting
a copy/ref callback.  Or wrap the if check in a mutex block.  Humm,
guess this may also work:

  if (!cairo_get_user_data (cr, key)) {
    LOCK (mutex);
    if (!cairo_get_user_data (cr, key)) {
      void *p = create_user_data ();
      cairo_set_user_data (cr, key, p, user_data_destroy);
    }
    UNLOCK (mutex);
  }

  user_data = cairo_get_user_data (cr, key);
  ...

But then again, Owen keeps telling me that double-check locking is
dangerous and I keep overlooking the reason.


Cheers,

-- 
behdad
http://behdad.org/

"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 mailing list