From d11014386f739f43ec5f290714d7c51cc638f172 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 5 Oct 2007 13:37:07 +0100 Subject: [PATCH] Add support for lockdep. lockdep is a valgrind skin which performs pthread locking correctness validation. In particular it allows one to write assert(HOLDS_LOCK(mutex)) which both documents the preconditions for a function and enforces them when the program is run under lockdep. As an aide to lockdep (as it works by intercepting the pthread functions), all the mutexes should be initialised and destroyed using pthread_mutex_init() and pthread_mutex_destroy() rather than using static initializers and no-ops. --- src/cairo-mutex-impl-private.h | 14 ++++++++++++++ src/cairo-mutex-type-private.h | 6 +++++- src/cairo-scaled-font.c | 13 +++++++++++++ 3 files changed, 32 insertions(+), 1 deletion(-) diff --git a/src/cairo-mutex-impl-private.h b/src/cairo-mutex-impl-private.h index 25fee4b63..52519076b 100644 --- a/src/cairo-mutex-impl-private.h +++ b/src/cairo-mutex-impl-private.h @@ -47,6 +47,11 @@ #include "config.h" #endif +#if HAVE_LOCKDEP +#include +#endif + +CAIRO_BEGIN_DECLS /* A fully qualified no-operation statement */ #define CAIRO_MUTEX_IMPL_NOOP do {/*no-op*/} while (0) @@ -171,10 +176,19 @@ typedef pthread_mutex_t cairo_mutex_impl_t; # define CAIRO_MUTEX_IMPL_PTHREAD 1 +#if HAVE_LOCKDEP +/* expose all mutexes to the validator */ +# define CAIRO_MUTEX_IMPL_INIT(mutex) pthread_mutex_init (&(mutex), NULL) +#endif # define CAIRO_MUTEX_IMPL_LOCK(mutex) pthread_mutex_lock (&(mutex)) # define CAIRO_MUTEX_IMPL_UNLOCK(mutex) pthread_mutex_unlock (&(mutex)) +#if HAVE_LOCKDEP +# define CAIRO_HOLDS_MUTEX(mutex) LOCKDEP_HOLDS_LOCK (&(mutex)) +#endif # define CAIRO_MUTEX_IMPL_FINI(mutex) pthread_mutex_destroy (&(mutex)) +#if ! HAVE_LOCKDEP # define CAIRO_MUTEX_IMPL_FINALIZE() CAIRO_MUTEX_IMPL_NOOP +#endif # define CAIRO_MUTEX_IMPL_NIL_INITIALIZER PTHREAD_MUTEX_INITIALIZER #elif defined(HAVE_WINDOWS_H) || defined(_MSC_VER) /*************************/ diff --git a/src/cairo-mutex-type-private.h b/src/cairo-mutex-type-private.h index 2314be1d0..776b0db28 100644 --- a/src/cairo-mutex-type-private.h +++ b/src/cairo-mutex-type-private.h @@ -44,6 +44,8 @@ #include "cairo-compiler-private.h" #include "cairo-mutex-impl-private.h" +CAIRO_BEGIN_DECLS + /* Only the following three are mandatory at this point */ #ifndef CAIRO_MUTEX_IMPL_LOCK # error "CAIRO_MUTEX_IMPL_LOCK not defined. Check cairo-mutex-impl-private.h." @@ -90,7 +92,6 @@ #endif /* CAIRO_MUTEX_IMPL_INIT */ - #ifdef CAIRO_MUTEX_IMPL_FINI /* If %CAIRO_MUTEX_IMPL_FINI is defined, we may need to finalize all @@ -169,6 +170,9 @@ typedef cairo_mutex_impl_t cairo_mutex_t; #define CAIRO_MUTEX_FINI CAIRO_MUTEX_IMPL_FINI #define CAIRO_MUTEX_NIL_INITIALIZER CAIRO_MUTEX_IMPL_NIL_INITIALIZER +#ifndef CAIRO_HOLDS_MUTEX +# define CAIRO_HOLDS_MUTEX(name) 1 +#endif /* Debugging support */ diff --git a/src/cairo-scaled-font.c b/src/cairo-scaled-font.c index bfe076a1f..fcea8aa9e 100644 --- a/src/cairo-scaled-font.c +++ b/src/cairo-scaled-font.c @@ -656,18 +656,24 @@ _cairo_scaled_font_init (cairo_scaled_font_t *scaled_font, void _cairo_scaled_font_freeze_cache (cairo_scaled_font_t *scaled_font) { + assert (CAIRO_HOLDS_MUTEX (scaled_font->mutex)); + _cairo_cache_freeze (scaled_font->glyphs); } void _cairo_scaled_font_thaw_cache (cairo_scaled_font_t *scaled_font) { + assert (CAIRO_HOLDS_MUTEX (scaled_font->mutex)); + _cairo_cache_thaw (scaled_font->glyphs); } void _cairo_scaled_font_reset_cache (cairo_scaled_font_t *scaled_font) { + assert (CAIRO_HOLDS_MUTEX (scaled_font->mutex)); + _cairo_cache_destroy (scaled_font->glyphs); scaled_font->glyphs = _cairo_cache_create (_cairo_scaled_glyph_keys_equal, _cairo_scaled_glyph_destroy, @@ -1689,6 +1695,8 @@ _cairo_scaled_font_glyph_device_extents (cairo_scaled_font_t *scaled_font, if (scaled_font->status) return scaled_font->status; + assert (CAIRO_HOLDS_MUTEX (scaled_font->mutex)); + for (i = 0; i < num_glyphs; i++) { cairo_scaled_glyph_t *scaled_glyph; int left, top; @@ -1760,6 +1768,7 @@ _cairo_scaled_font_show_glyphs (cairo_scaled_font_t *scaled_font, if (!num_glyphs) return CAIRO_STATUS_SUCCESS; + assert (CAIRO_HOLDS_MUTEX (scaled_font->mutex)); if (scaled_font->backend->show_glyphs != NULL) { int remaining_glyphs = num_glyphs; status = scaled_font->backend->show_glyphs (scaled_font, @@ -2074,6 +2083,8 @@ _cairo_scaled_font_glyph_path (cairo_scaled_font_t *scaled_font, if (status) return status; + assert (CAIRO_HOLDS_MUTEX (scaled_font->mutex)); + closure.path = path; _cairo_scaled_font_freeze_cache (scaled_font); for (i = 0; i < num_glyphs; i++) { @@ -2284,6 +2295,8 @@ _cairo_scaled_glyph_lookup (cairo_scaled_font_t *scaled_font, if (scaled_font->status) return scaled_font->status; + assert (CAIRO_HOLDS_MUTEX (scaled_font->mutex)); + key.hash = index; /* * Check cache for glyph