<html>
<head>
<style>
.hmmessage P
{
margin:0px;
padding:0px
}
body.hmmessage
{
font-size: 10pt;
font-family:Verdana
}
</style>
</head>
<body class='hmmessage'>
<br>I'm using Cairo 1.6.4 (though the code at issue seemed basically the same in 1.8.6) in a multi-threaded application and am seeing heap corruption.&nbsp; The heap corruption went away when stuffed a mutex around the usage of Cairo, so I've been investigating.&nbsp; It looks like there is a race condition in the management of toy font faces.&nbsp; The following scenario seems troublesome:<br><br>Suppose Thread 1 is using a context with some font (e.g. Helvetica) selected into it.&nbsp; Suppose it's destroying the context, and cairo_destory calls _cairo_gstate_fini which calls cairo_font_face_destroy with Helvetica.<br><br>So Thread 1 enters cairo_font_face_destory (cairo-font-face.c, line 124 in 1.6.4).<br>1. The reference is positive (1)<br>2. So _cairo_reference_count_dec_and_test drops the reference count to 0, returning true.<br>Now let's suspend Thread 1 at this point, before font_face-&gt;backend-&gt;destroy is executed on line 135.<br><br>Now let's have Thread 2 try to use Helvetica in another context for the first time.<br><br>Thread 2 enters _cairo_toy_font_face_create (cairo-font-face.c, .line 384).<br>3.&nbsp; It locks the hash table, does a lookup on Helvetica, and finds it, since Thread 1 hasn't removed it yet.<br>4.&nbsp; It unlocks the hash table, and is about to return &amp;font_face-&gt;base on line 408.<br>Let's suspend Thread 2 as it's about to return from _cairo_toy_font_face_create with the existing object<br><br>Back in Thread 1:<br><br>5.&nbsp; font_face-&gt;backend-&gt;destroy() is called.<br>6.&nbsp; This calls _cairo_toy_font_face_destroy which removes the font from the hash table, and calls _cairo_toy_font_face_fini<br>7.&nbsp; _cairo_toy_font_face_fini calls "free ((char *) font_face-&gt;family)" on line 355.&nbsp; That seems bad (?) because this object isn't quite dead yet.&nbsp; Thread 2 is about to return it from _cairo_toy_font_face_create.<br>8.&nbsp; _cairo_toy_font_face_fini returns.<br>9.&nbsp; _cairo_toy_font_face_destroy returns.<br>10.&nbsp; cairo_font_face_destroy (line 141) sees the non-zero reference count and returns without destroying the base part of the font.<br><br>Now let's return to Thread 2:<br><br>11.&nbsp; _cairo_toy_font_face_create returns this partially-deleted object.&nbsp; It's no longer in the hash table so it won't be found again, but presumably at some later point its reference count goes to zero in Thread 2, and there's a double free of memory (possibly now allocated to some new block) when _cairo_toy_font_face_fini calls "free ((char *) font_face-&gt;family)" on line 355 again for the orphaned object.<br><br><br>If I add the line "if (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&amp;font_face-&gt;base.ref_count)) return;" after the hash table unlock but before _cairo_toy_font_face_fini in _cairo_toy_font_face_destroy my heap problem seems to go away.<br><br><br>Does anyone have a feel for whether Cairo is well tested in multi-threaded environments?&nbsp; Or is it just more likely that the toy text API isn't used with any seriousness?<br><br>Thanks,<br>-- Paul<br></body>
</html>