summaryrefslogtreecommitdiff
path: root/src/cairo-toy-font-face.c
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2009-01-26 10:54:45 +0000
committerChris Wilson <chris@chris-wilson.co.uk>2009-01-29 10:10:41 +0000
commit0f3e366f8bbbaa80b518eb1b0297a6122901ce66 (patch)
treed92489fa0947f0f2ad0759303c567bcec73f7949 /src/cairo-toy-font-face.c
parent312b5680a5754c8e7ee1332206b81449cf9bf8a3 (diff)
downloadcairo-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.c6
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);