Re: Thread-safety and library versions
Uli Schlachter <[email protected]>
| Newsgroups | gmane.comp.lib.cairo |
|---|---|
| Message-ID | <[email protected]> |
Hi,
On 17.09.2013 14:16, Weeble wrote:
[...]
> More specifically, I'm running libcairo 1.12.14 and libfontconfig
> 2.10.2. When Mono repeatedly creates cairo drawing contexts, calls
> cairo_select_font_face, and destroys the drawing contexts; (with each
> context accessed only from a single thread, but more than one thread
> running at once;) sooner or later it crashes when
> _cairo_toy_font_face_destroy calls _cairo_hash_table_remove and raises
> an assertion, apparently because the key is missing from the hash
> table.
I was thinking "it can't be that simple" and produced the attached test program
which does exactly this. The result with current cairo from git:
a.out: cairo-hash.c:506: _cairo_hash_table_lookup_exact_key: Assertion
`!"reached"' failed.
Could someone with more clue about how things are supposed to work take a look
at this? Chris? Behdad?
> Could this crash be caused by having an old version of
> fontconfig? There's no obvious involvement of fontconfig in this stack
> trace, but if this combination of libraries is known to have
> thread-safety issues I wonder if it could be due to memory corruption.
Just my 5c, but I don't think that this is due to fontconfig either.
> (Much more rarely, it crashes in FcPatternDestroy, with an assertion
> about a double-free or memory corruption, so I do have reason to
> suspect fontconfig, although I am not certain these crashes have the
> same cause.)
[...]
Haven't seen such a crash yet.
Cheers,
Uli
--
<alanc> I think someone had a Xprint version of glxgears at one point,
but benchmarking how many GL pages you can print per second
was deemed too silly to merge
--
cairo mailing list
[email protected]
http://lists.cairographics.org/mailman/listinfo/cairo
test.c
(text/x-csrc, 732 B)
#include <cairo.h>
#include <stdio.h>
#include <pthread.h>
#define NTHREADS 2
static cairo_surface_t *surf;
static void *thread_start(void *unused)
{
while (1) {
cairo_t *cr = cairo_create(surf);
cairo_select_font_face(cr, "serif", CAIRO_FONT_SLANT_NORMAL,
CAIRO_FONT_WEIGHT_NORMAL);
cairo_destroy(cr);
}
}
int main(void)
{
int i;
pthread_t threads[NTHREADS];
surf = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 100, 100);
for (i = 0; i < NTHREADS; i++) {
if (pthread_create(&threads[i], NULL, thread_start, NULL) != 0)
perror("pthread_create");
}
for (i = 0; i < NTHREADS; i++) {
if (pthread_join(threads[i], NULL) != 0)
perror("pthread_join");
}
cairo_surface_destroy(surf);
return 0;
}