Implement CAIRO_MUTEX_IS_{,UN}LOCKED

Uli Schlachter <[email protected]>
Newsgroups gmane.comp.lib.cairo
Message-ID <[email protected]>
Hi,

while digging into bug #38904, I noticed that the image backend doesn't freeze
the font cache which I guess is what causes this bug.

As a first step towards a fix, I wrote the attached patch. The goal is to make
the asserts() work which are supposed to notice those unsynchronized calls. A
test suite run confirms that lots of asserts trigger.


What is missing is a way to hook this up with configure (if needed) or coming up
with another way to make this configurable.

Would anyone mind if I add a configure switch for this? Should it be enabled via
hand-editing a header and defining CAIRO_MUTEX_DEBUG (which doesn't seem to be
doing anything currently)?

Should I turn this into a proper patch which can be pushed? Anyone wants to help
fixing the failing asserts?

Cheers,
Uli

P.S.: Most of this a single bug in cairo-xcb, but still:

15 Passed, 434 Failed [430 crashed, 1 expected], 21 Skipped
-- 
- Captain, I think I should tell you I've never
  actually landed a starship before.
- That's all right, Lieutenant, neither have I.

--
cairo mailing list
[email protected]
http://lists.cairographics.org/mailman/listinfo/cairo
mutex_is_locked.patch (text/x-diff, 2.9 KB)
diff --git a/src/cairo-mutex-type-private.h b/src/cairo-mutex-type-private.h
index e8c4939..ec524d8 100644
--- a/src/cairo-mutex-type-private.h
+++ b/src/cairo-mutex-type-private.h
@@ -87,7 +87,7 @@
 
 /* and dynamic ones can be initialized using the static initializer. */
 # define CAIRO_MUTEX_IMPL_INIT(mutex) do {				\
-      cairo_mutex_t _tmp_mutex = CAIRO_MUTEX_IMPL_NIL_INITIALIZER;	\
+      cairo_mutex_t _tmp_mutex = CAIRO_MUTEX_NIL_INITIALIZER;	\
       memcpy (&(mutex), &_tmp_mutex, sizeof (_tmp_mutex));	\
   } while (0)
 
@@ -152,6 +152,9 @@
 #endif
 
 
+// FIXME: Get rid of this and add it to configure
+#define CAIRO_MUTEX_DEBUG
+
 /* Public interface. */
 
 /* By default it simply uses the implementation provided.
@@ -160,12 +163,7 @@
 #ifndef CAIRO_MUTEX_DEBUG
 typedef cairo_mutex_impl_t cairo_mutex_t;
 typedef cairo_recursive_mutex_impl_t cairo_recursive_mutex_t;
-#else
-# define cairo_mutex_t			cairo_mutex_impl_t
-#endif
 
-#define CAIRO_MUTEX_INITIALIZE		CAIRO_MUTEX_IMPL_INITIALIZE
-#define CAIRO_MUTEX_FINALIZE		CAIRO_MUTEX_IMPL_FINALIZE
 #define CAIRO_MUTEX_LOCK		CAIRO_MUTEX_IMPL_LOCK
 #define CAIRO_MUTEX_UNLOCK		CAIRO_MUTEX_IMPL_UNLOCK
 #define CAIRO_MUTEX_INIT		CAIRO_MUTEX_IMPL_INIT
@@ -181,6 +179,54 @@ typedef cairo_recursive_mutex_impl_t cairo_recursive_mutex_t;
 #ifndef CAIRO_MUTEX_IS_UNLOCKED
 # define CAIRO_MUTEX_IS_UNLOCKED(name) 1
 #endif
+#else /* CAIRO_MUTEX_DEBUG */
+typedef struct {
+    cairo_mutex_impl_t real_mutex;
+    cairo_bool_t is_locked;
+} cairo_mutex_t;
+typedef struct {
+    cairo_recursive_mutex_impl_t real_mutex;
+    cairo_bool_t is_locked;
+} cairo_recursive_mutex_t;
+
+#define CAIRO_MUTEX_LOCK(mutex) do { \
+        CAIRO_MUTEX_IMPL_LOCK((mutex).real_mutex); \
+        (mutex).is_locked = TRUE; \
+    } while (0)
+
+#define CAIRO_MUTEX_UNLOCK(mutex) do { \
+        (mutex).is_locked = FALSE; \
+        CAIRO_MUTEX_IMPL_UNLOCK((mutex).real_mutex); \
+    } while (0)
+
+#define CAIRO_MUTEX_INIT(mutex) do { \
+        CAIRO_MUTEX_IMPL_INIT((mutex).real_mutex); \
+        (mutex).is_locked = FALSE; \
+    } while (0)
+
+#define CAIRO_MUTEX_FINI(mutex) do { \
+        assert (! (mutex).is_locked); \
+        CAIRO_MUTEX_IMPL_FINI((mutex).real_mutex); \
+    } while (0)
+
+#define CAIRO_RECURSIVE_MUTEX_INIT(mutex) do { \
+        CAIRO_RECURSIVE_MUTEX_IMPL_INIT((mutex).real_mutex); \
+        (mutex).is_locked = FALSE; \
+    } while (0)
+
+#define CAIRO_RECURSIVE_MUTEX_NIL_INITIALIZER(mutex)	{ CAIRO_RECURSIVE_MUTEX_IMPL_NIL_INITIALIZER, TRUE }
+#define CAIRO_MUTEX_NIL_INITIALIZER			{ CAIRO_MUTEX_IMPL_NIL_INITIALIZER, TRUE }
+
+#ifndef CAIRO_MUTEX_IS_LOCKED
+# define CAIRO_MUTEX_IS_LOCKED(name) ((name).is_locked)
+#endif
+#ifndef CAIRO_MUTEX_IS_UNLOCKED
+# define CAIRO_MUTEX_IS_UNLOCKED(name) (! (name).is_locked)
+#endif
+#endif /* CAIRO_MUTEX_DEBUG */
+
+#define CAIRO_MUTEX_FINALIZE		CAIRO_MUTEX_IMPL_FINALIZE
+#define CAIRO_MUTEX_INITIALIZE		CAIRO_MUTEX_IMPL_INITIALIZE
 
 
 /* Debugging support */
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.