diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2009-01-26 10:54:45 +0000 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2009-01-29 10:10:41 +0000 |
commit | 0f3e366f8bbbaa80b518eb1b0297a6122901ce66 (patch) | |
tree | d92489fa0947f0f2ad0759303c567bcec73f7949 /src/cairo-toy-font-face.c | |
parent | 312b5680a5754c8e7ee1332206b81449cf9bf8a3 (diff) | |
download | cairo-0f3e366f8bbbaa80b518eb1b0297a6122901ce66.tar.gz |
[font-face] Close a race when resurrecting fonts.
Paul Messmer provided a thorough analysis of a race between destroying the
final reference on a font and a concurrent recreation of the font -
demonstrating how it is possible for the create() to return the font that
was in the process of being freed.
To stop the race, we need to recheck the reference count upon taking the
mutex guarding the hash table.
Diffstat (limited to 'src/cairo-toy-font-face.c')
-rw-r--r-- | src/cairo-toy-font-face.c | 6 |
1 files changed, 6 insertions, 0 deletions
diff --git a/src/cairo-toy-font-face.c b/src/cairo-toy-font-face.c index 5a60b14c8..05ad495db 100644 --- a/src/cairo-toy-font-face.c +++ b/src/cairo-toy-font-face.c @@ -358,6 +358,12 @@ _cairo_toy_font_face_destroy (void *abstract_face) /* All created objects must have been mapped in the hash table. */ assert (hash_table != NULL); + if (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&font_face->base.ref_count)) { + /* somebody recreated the font whilst we waited for the lock */ + _cairo_toy_font_face_hash_table_unlock (); + return; + } + if (font_face->base.hash_entry.hash != 0) _cairo_hash_table_remove (hash_table, &font_face->base.hash_entry); |