[cairo] New per-scaled_font mutex to fix locking bugs

Jan Slupski jslupski at juljas.net
Tue Feb 6 19:07:32 PST 2007

On Mon, 5 Feb 2007, Carl Worth wrote:

> The patch below is an attempt to fix the locking bugs identified here:
> 	text rendering lacking locking in multithreaded apps [PATCH]
> 	https://bugs.freedesktop.org/show_bug.cgi?id=8801

Hi Carl,

I have tried this patch with following configurations:
Cairo 1.2.6 + the patch
Cairo 1.2.6 + 8081 both patches + the patch
git://git.cairographics.org/git/cairo + the patch
git://people.freedesktop.org/~cworth/cairo + 8801-attachments + the patch
git://git.cairographics.org/git/cairo (again, just now, with patch already merged)

In each case my original test program fails quickly with the following:

threads: cairo-hash.c:477: _cairo_hash_table_insert: Assertion `NOT_REACHED' failed.

Sometimes more or less random crashes happen too (eg. in malloc())

If the 8081 patches are not applied, old asserts happens too:

threads: cairo-hash.c:196: _cairo_hash_table_destroy: Assertion `hash_table->live_entries == 0' failed.
threads: cairo-ft-font.c:562: _cairo_ft_unscaled_font_unlock_face: Assertion `unscaled->lock > 0' failed.

I've been able to reproduce earlier (8801), and above assert with
attached simple example. (Sorry, just standalone, not in cairo 'make test' format)

Hope that helps,
Jan Slupski

-------------- next part --------------
#include <pthread.h>
#include <cairo.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>

#define MAX_THREAD 2
#define LOOP_COUNT 500

void * Draw(void *p);

int main(void) {
  const int nThreads = MAX_THREAD;
	int i;

  pthread_t threads[MAX_THREAD];

		for(i =0; i<nThreads; i++)
			int err = pthread_create(&threads[i],NULL,Draw,(void*)i);
			if(err) printf("error creating thread %d\n",i);

		for(i =0; i<nThreads; i++)
			pthread_join(threads[i], NULL);

  return 0;

void * Draw(void *p)
  int thread_no = (int)p;
	int loop = 0;

	while (loop<=LOOP_COUNT)
			printf("t%03d loop %4d\n",thread_no, loop);

			//char name[200];
			//sprintf(name, "th%03d.img%04d.png", thread_no, loop);

			cairo_surface_t *surface;
			cairo_t *cr;

			char string[] = "Hello";
			cairo_text_extents_t size;
			double fontsize = 100.0;

			surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 400, 300);
			cr = cairo_create (surface);

			cairo_select_font_face (cr, "Serif", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
			cairo_set_font_size (cr, fontsize);
			cairo_text_extents(cr, string, &size);
			cairo_show_text (cr, string);

			//cairo_surface_write_to_png (surface, "rotlabel.png");
			cairo_destroy (cr);
			cairo_surface_destroy (surface);


	return NULL;


More information about the cairo mailing list