From 0fbae3d42c372f1fcc79dce52bd2b76dd44c646f Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Mon, 26 Feb 2007 02:35:41 +0100 Subject: [PATCH] Add code to debug mutex deadlocks This is somewhat unportable as it relies on non-POSIX error-checking mutexes. Go go gadget _GNU_SOURCE\! --- src/Makefile.am | 2 +- src/cairo-scaled-font.c | 12 ++++++++++++ src/cairoint.h | 16 +++++++++++++--- 3 files changed, 26 insertions(+), 4 deletions(-) diff --git a/src/Makefile.am b/src/Makefile.am index 4a24ac2..47b5823 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -243,7 +243,7 @@ libcairo_la_SOURCES = \ libcairo_la_LDFLAGS = -version-info @VERSION_INFO@ -no-undefined $(export_symbols) -INCLUDES = -I$(srcdir) -I$(top_srcdir)/pixman/src $(CAIRO_CFLAGS) +INCLUDES = -D_GNU_SOURCE -I$(srcdir) -I$(top_srcdir)/pixman/src $(CAIRO_CFLAGS) libcairo_la_LIBADD = $(top_builddir)/pixman/src/libpixman.la $(CAIRO_LIBS) $(noinst_LTLIBRARIES) diff --git a/src/cairo-scaled-font.c b/src/cairo-scaled-font.c index 02af487..6638c70 100755 --- a/src/cairo-scaled-font.c +++ b/src/cairo-scaled-font.c @@ -678,6 +678,10 @@ cairo_scaled_font_text_extents (cairo_scaled_font_t *scaled_font, free (glyphs); } +const char * CAIRO_MUTEX_LOCK_FILE; +int CAIRO_MUTEX_LOCK_LINE; +int CAIRO_MUTEX_LOCK_ERR; + /** * cairo_scaled_font_glyph_extents: * @scaled_font: a #cairo_scaled_font_t @@ -702,6 +706,7 @@ cairo_scaled_font_glyph_extents (cairo_scaled_font_t *scaled_font, int num_glyphs, cairo_text_extents_t *extents) { + int err; cairo_status_t status = CAIRO_STATUS_SUCCESS; int i; double min_x = 0.0, min_y = 0.0, max_x = 0.0, max_y = 0.0; @@ -712,6 +717,13 @@ cairo_scaled_font_glyph_extents (cairo_scaled_font_t *scaled_font, return; CAIRO_MUTEX_LOCK (scaled_font->mutex); + if (CAIRO_MUTEX_LOCK_ERR == EDEADLK) { + fprintf (stderr, + "Deadlock occurred in cairo_scaled_font_glyph_extents.\n" + "The original locker was %s:%d\n", + CAIRO_MUTEX_LOCK_FILE, CAIRO_MUTEX_LOCK_LINE); + exit (1); + } for (i = 0; i < num_glyphs; i++) { double left, top, right, bottom; diff --git a/src/cairoint.h b/src/cairoint.h index 2c145e0..7279239 100755 --- a/src/cairoint.h +++ b/src/cairoint.h @@ -46,6 +46,8 @@ #ifndef _CAIROINT_H_ #define _CAIROINT_H_ +#include + #if HAVE_CONFIG_H #include "config.h" #endif @@ -134,11 +136,19 @@ CAIRO_BEGIN_DECLS #define __attribute__(x) #endif +extern const char * CAIRO_MUTEX_LOCK_FILE; +extern int CAIRO_MUTEX_LOCK_LINE; +extern int CAIRO_MUTEX_LOCK_ERR; + #if HAVE_PTHREAD_H # include -# define CAIRO_MUTEX_DECLARE(name) static pthread_mutex_t name = PTHREAD_MUTEX_INITIALIZER -# define CAIRO_MUTEX_DECLARE_GLOBAL(name) pthread_mutex_t name = PTHREAD_MUTEX_INITIALIZER -# define CAIRO_MUTEX_LOCK(name) pthread_mutex_lock (&name) +# define CAIRO_MUTEX_DECLARE(name) static pthread_mutex_t name = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP +# define CAIRO_MUTEX_DECLARE_GLOBAL(name) pthread_mutex_t name = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP +# define CAIRO_MUTEX_LOCK(name) do { \ + CAIRO_MUTEX_LOCK_ERR = pthread_mutex_lock (&name); \ + CAIRO_MUTEX_LOCK_FILE = __FILE__; \ + CAIRO_MUTEX_LOCK_LINE = __LINE__; \ +} while (0) # define CAIRO_MUTEX_UNLOCK(name) pthread_mutex_unlock (&name) typedef pthread_mutex_t cairo_mutex_t; # define CAIRO_MUTEX_INIT(mutex) pthread_mutex_init ((mutex), NULL) -- 1.5.0.rc1.gf4b6c