mirror of
https://gitlab.freedesktop.org/cairo/cairo.git
synced 2026-05-08 05:38:02 +02:00
[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.
This commit is contained in:
parent
312b5680a5
commit
0f3e366f8b
2 changed files with 12 additions and 0 deletions
|
|
@ -513,6 +513,12 @@ _cairo_ft_unscaled_font_destroy (void *abstract_font)
|
|||
/* All created objects must have been mapped in the font map. */
|
||||
assert (font_map != NULL);
|
||||
|
||||
if (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&unscaled->base.ref_count)) {
|
||||
/* somebody recreated the font whilst we waited for the lock */
|
||||
_cairo_ft_unscaled_font_map_unlock ();
|
||||
return;
|
||||
}
|
||||
|
||||
_cairo_hash_table_remove (font_map->hash_table,
|
||||
&unscaled->base.hash_entry);
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue