[cairo-commit] 4 commits - src/cairo-mutex.c src/cairo-mutex-impl-private.h src/cairo-mutex-private.h src/cairo-mutex-type-private.h src/cairo-xlib-surface.c src/Makefile.am util/backtrace-symbols.c
Behdad Esfahbod
behdad at kemper.freedesktop.org
Tue May 27 02:20:34 PDT 2008
src/Makefile.am | 1
src/cairo-mutex-impl-private.h | 226 ++++++++++++++++++++++++++++++++++
src/cairo-mutex-private.h | 129 +------------------
src/cairo-mutex-type-private.h | 269 +++++++++++++++++++----------------------
src/cairo-mutex.c | 18 +-
src/cairo-xlib-surface.c | 72 ++++++++++
util/backtrace-symbols.c | 18 ++
7 files changed, 459 insertions(+), 274 deletions(-)
New commits:
commit 626edfc333b77604b6955c12ae111d14c174034c
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Mon May 26 20:28:23 2008 -0400
[cairo-mutex] Prepare mutex infrastructure for adding mutex debugging facilities
Essentially renaming cairo-mutex-type-private.h to cairo-mutex-impl-private.h
and changing all its namespace from cairo_mutex to cairo_mutex_impl.
cairo-mutex-type-private.h then does all the sanity checks on the
implementation that used to be in cairo-mutex-private.h. Plus, defines macros
for the cairo-mutex namespace to map to the cairo-mutex-impl namespace. This
extra mapping layer allows for add debugging facilities.
diff --git a/src/Makefile.am b/src/Makefile.am
index c52a7a0..de080e7 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -36,6 +36,7 @@ cairo_base_sources = \
cairo-matrix.c \
cairo-mutex.c \
cairo-mutex-private.h \
+ cairo-mutex-impl-private.h \
cairo-mutex-type-private.h \
cairo-path.c \
cairo-path-private.h \
diff --git a/src/cairo-mutex-impl-private.h b/src/cairo-mutex-impl-private.h
new file mode 100644
index 0000000..6905566
--- /dev/null
+++ b/src/cairo-mutex-impl-private.h
@@ -0,0 +1,226 @@
+/* cairo - a vector graphics library with display and print output
+ *
+ * Copyright © 2002 University of Southern California
+ * Copyright © 2005,2007 Red Hat, Inc.
+ * Copyright © 2007 Mathias Hasselmann
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it either under the terms of the GNU Lesser General Public
+ * License version 2.1 as published by the Free Software Foundation
+ * (the "LGPL") or, at your option, under the terms of the Mozilla
+ * Public License Version 1.1 (the "MPL"). If you do not alter this
+ * notice, a recipient may use your version of this file under either
+ * the MPL or the LGPL.
+ *
+ * You should have received a copy of the LGPL along with this library
+ * in the file COPYING-LGPL-2.1; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * You should have received a copy of the MPL along with this library
+ * in the file COPYING-MPL-1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
+ * OF ANY KIND, either express or implied. See the LGPL or the MPL for
+ * the specific language governing rights and limitations.
+ *
+ * The Original Code is the cairo graphics library.
+ *
+ * The Initial Developer of the Original Code is University of Southern
+ * California.
+ *
+ * Contributor(s):
+ * Carl D. Worth <cworth at cworth.org>
+ * Mathias Hasselmann <mathias.hasselmann at gmx.de>
+ * Behdad Esfahbod <behdad at behdad.org>
+ */
+
+#ifndef CAIRO_MUTEX_IMPL_PRIVATE_H
+#define CAIRO_MUTEX_IMPL_PRIVATE_H
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <cairo-features.h>
+
+CAIRO_BEGIN_DECLS
+
+
+/* A fully qualified no-operation statement */
+#define CAIRO_MUTEX_IMPL_NOOP do {/*no-op*/} while (0)
+/* And one that evaluates it's argument once */
+#define CAIRO_MUTEX_IMPL_NOOP1(expr) do { if (expr) ; } while (0)
+
+
+/* Cairo mutex implementation:
+ *
+ * Any new mutex implementation needs to do the following:
+ *
+ * - Condition on the right header or feature. Headers are
+ * preferred as eg. you still can use win32 mutex implementation
+ * on a win32 system even if you do not compile the win32
+ * surface/backend.
+ *
+ * - typedef #cairo_mutex_impl_t to the proper mutex type on your target
+ * system. Note that you may or may not need to use a pointer,
+ * depending on what kinds of initialization your mutex
+ * implementation supports. No trailing semicolon needed.
+ * You should be able to compile the following snippet (don't try
+ * running it):
+ *
+ * <programlisting>
+ * cairo_mutex_impl_t _cairo_some_mutex;
+ * </programlisting>
+ *
+ * - #define CAIRO_MUTEX_IMPL_LOCK(mutex) and CAIRO_MUTEX_IMPL_UNLOCK(mutex) to
+ * proper statement to lock/unlock the mutex object passed in.
+ * You can (and should) assume that the mutex is already
+ * initialized, and is-not-already-locked/is-locked,
+ * respectively. Use the "do { ... } while (0)" idiom if necessary.
+ * No trailing semicolons are needed (in any macro you define here).
+ * You should be able to compile the following snippet:
+ *
+ * <programlisting>
+ * cairo_mutex_impl_t _cairo_some_mutex;
+ *
+ * if (1)
+ * CAIRO_MUTEX_IMPL_LOCK (_cairo_some_mutex);
+ * else
+ * CAIRO_MUTEX_IMPL_UNLOCK (_cairo_some_mutex);
+ * </programlisting>
+ *
+ * - #define %CAIRO_MUTEX_IMPL_NIL_INITIALIZER to something that can
+ * initialize the #cairo_mutex_impl_t type you defined. Most of the
+ * time one of 0, %NULL, or {} works. At this point
+ * you should be able to compile the following snippet:
+ *
+ * <programlisting>
+ * cairo_mutex_impl_t _cairo_some_mutex = CAIRO_MUTEX_IMPL_NIL_INITIALIZER;
+ *
+ * if (1)
+ * CAIRO_MUTEX_IMPL_LOCK (_cairo_some_mutex);
+ * else
+ * CAIRO_MUTEX_IMPL_UNLOCK (_cairo_some_mutex);
+ * </programlisting>
+ *
+ * - If the above code is not enough to initialize a mutex on
+ * your platform, #define CAIRO_MUTEX_IMPL_INIT(mutex) to statement
+ * to initialize the mutex (allocate resources, etc). Such that
+ * you should be able to compile AND RUN the following snippet:
+ *
+ * <programlisting>
+ * cairo_mutex_impl_t _cairo_some_mutex = CAIRO_MUTEX_IMPL_NIL_INITIALIZER;
+ *
+ * CAIRO_MUTEX_IMPL_INIT (_cairo_some_mutex);
+ *
+ * if (1)
+ * CAIRO_MUTEX_IMPL_LOCK (_cairo_some_mutex);
+ * else
+ * CAIRO_MUTEX_IMPL_UNLOCK (_cairo_some_mutex);
+ * </programlisting>
+ *
+ * - If you define CAIRO_MUTEX_IMPL_INIT(mutex), cairo will use it to
+ * initialize all static mutex'es. If for any reason that should
+ * not happen (eg. %CAIRO_MUTEX_IMPL_INIT is just a faster way than
+ * what cairo does using %CAIRO_MUTEX_IMPL_NIL_INITIALIZER), then
+ * <programlisting>
+ * #define CAIRO_MUTEX_IMPL_INITIALIZE() CAIRO_MUTEX_IMPL_NOOP
+ * </programlisting>
+ *
+ * - If your system supports freeing a mutex object (deallocating
+ * resources, etc), then #define CAIRO_MUTEX_IMPL_FINI(mutex) to do
+ * that.
+ *
+ * - If you define CAIRO_MUTEX_IMPL_FINI(mutex), cairo will use it to
+ * define a finalizer function to finalize all static mutex'es.
+ * However, it's up to you to call CAIRO_MUTEX_IMPL_FINALIZE() at
+ * proper places, eg. when the system is unloading the cairo library.
+ * So, if for any reason finalizing static mutex'es is not needed
+ * (eg. you never call CAIRO_MUTEX_IMPL_FINALIZE()), then
+ * <programlisting>
+ * #define CAIRO_MUTEX_IMPL_FINALIZE() CAIRO_MUTEX_IMPL_NOOP
+ * </programlisting>
+ *
+ * - That is all. If for any reason you think the above API is
+ * not enough to implement #cairo_mutex_impl_t on your system, please
+ * stop and write to the cairo mailing list about it. DO NOT
+ * poke around cairo-mutex-private.h for possible solutions.
+ */
+
+#ifndef CAIRO_MUTEX_TYPE_PRIVATE_H
+#error "Do not include cairo-mutex-impl-private.h directly. Include cairo-mutex-type-private.h instead."
+#endif
+
+#if CAIRO_NO_MUTEX
+
+/* No mutexes */
+
+ typedef int cairo_mutex_impl_t;
+
+# define CAIRO_MUTEX_IMPL_INITIALIZE() CAIRO_MUTEX_IMPL_NOOP
+# define CAIRO_MUTEX_IMPL_LOCK(mutex) CAIRO_MUTEX_IMPL_NOOP1(mutex)
+# define CAIRO_MUTEX_IMPL_UNLOCK(mutex) CAIRO_MUTEX_IMPL_NOOP1(mutex)
+# define CAIRO_MUTEX_IMPL_NIL_INITIALIZER 0
+
+#elif HAVE_PTHREAD_H /*******************************************************/
+
+# include <pthread.h>
+
+ typedef pthread_mutex_t cairo_mutex_impl_t;
+
+# define CAIRO_MUTEX_IMPL_LOCK(mutex) pthread_mutex_lock (&(mutex))
+# define CAIRO_MUTEX_IMPL_UNLOCK(mutex) pthread_mutex_unlock (&(mutex))
+# define CAIRO_MUTEX_IMPL_FINI(mutex) pthread_mutex_destroy (&(mutex))
+# define CAIRO_MUTEX_IMPL_FINALIZE() CAIRO_MUTEX_IMPL_NOOP
+# define CAIRO_MUTEX_IMPL_NIL_INITIALIZER PTHREAD_MUTEX_INITIALIZER
+
+#elif HAVE_WINDOWS_H /*******************************************************/
+
+# include <windows.h>
+
+ typedef CRITICAL_SECTION cairo_mutex_impl_t;
+
+# define CAIRO_MUTEX_IMPL_LOCK(mutex) EnterCriticalSection (&(mutex))
+# define CAIRO_MUTEX_IMPL_UNLOCK(mutex) LeaveCriticalSection (&(mutex))
+# define CAIRO_MUTEX_IMPL_INIT(mutex) InitializeCriticalSection (&(mutex))
+# define CAIRO_MUTEX_IMPL_FINI(mutex) DeleteCriticalSection (&(mutex))
+# define CAIRO_MUTEX_IMPL_NIL_INITIALIZER { NULL, 0, 0, NULL, NULL, 0 }
+
+#elif defined __OS2__ /******************************************************/
+
+# define INCL_BASE
+# define INCL_PM
+# include <os2.h>
+
+ typedef HMTX cairo_mutex_impl_t;
+
+# define CAIRO_MUTEX_IMPL_LOCK(mutex) DosRequestMutexSem(mutex, SEM_INDEFINITE_WAIT)
+# define CAIRO_MUTEX_IMPL_UNLOCK(mutex) DosReleaseMutexSem(mutex)
+# define CAIRO_MUTEX_IMPL_INIT(mutex) DosCreateMutexSem (NULL, &(mutex), 0L, FALSE)
+# define CAIRO_MUTEX_IMPL_FINI(mutex) DosCloseMutexSem (mutex)
+# define CAIRO_MUTEX_IMPL_NIL_INITIALIZER 0
+
+#elif CAIRO_HAS_BEOS_SURFACE /***********************************************/
+
+ typedef BLocker* cairo_mutex_impl_t;
+
+# define CAIRO_MUTEX_IMPL_LOCK(mutex) (mutex)->Lock()
+# define CAIRO_MUTEX_IMPL_UNLOCK(mutex) (mutex)->Unlock()
+# define CAIRO_MUTEX_IMPL_INIT(mutex) (mutex) = new BLocker()
+# define CAIRO_MUTEX_IMPL_FINI(mutex) delete (mutex)
+# define CAIRO_MUTEX_IMPL_NIL_INITIALIZER NULL
+
+#else /**********************************************************************/
+
+# error "XXX: No mutex implementation found. Cairo will not work with multiple threads. Define CAIRO_NO_MUTEX to 1 to acknowledge and accept this limitation and compile cairo without thread-safety support."
+
+
+#endif
+
+CAIRO_END_DECLS
+
+#endif
diff --git a/src/cairo-mutex-private.h b/src/cairo-mutex-private.h
index 64afd64..61b87d7 100644
--- a/src/cairo-mutex-private.h
+++ b/src/cairo-mutex-private.h
@@ -41,136 +41,27 @@
#ifndef CAIRO_MUTEX_PRIVATE_H
#define CAIRO_MUTEX_PRIVATE_H
-#if HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <cairo-features.h>
-
-#include "cairo-compiler-private.h"
#include "cairo-mutex-type-private.h"
-/* Only the following three are mandatory at this point */
-#ifndef CAIRO_MUTEX_LOCK
-# error "CAIRO_MUTEX_LOCK not defined. Check cairo-mutex-type-private.h."
-#endif
-#ifndef CAIRO_MUTEX_UNLOCK
-# error "CAIRO_MUTEX_UNLOCK not defined. Check cairo-mutex-type-private.h."
-#endif
-#ifndef CAIRO_MUTEX_NIL_INITIALIZER
-# error "CAIRO_MUTEX_NIL_INITIALIZER not defined. Check cairo-mutex-type-private.h."
-#endif
-
CAIRO_BEGIN_DECLS
-
-#define CAIRO_MUTEX_DECLARE(mutex) extern cairo_mutex_t mutex
-#include "cairo-mutex-list-private.h"
-#undef CAIRO_MUTEX_DECLARE
-
-
-/* make sure implementations don't fool us: we decide these ourself */
-#undef _CAIRO_MUTEX_USE_STATIC_INITIALIZER
-#undef _CAIRO_MUTEX_USE_STATIC_FINALIZER
-
-
-#ifdef CAIRO_MUTEX_INIT
-
-/* If %CAIRO_MUTEX_INIT is defined, we may need to initialize all
- * static mutex'es. */
-# ifndef CAIRO_MUTEX_INITIALIZE
-# define CAIRO_MUTEX_INITIALIZE() do { \
- if (!_cairo_mutex_initialized) \
- _cairo_mutex_initialize (); \
- } while(0)
-
- cairo_private void _cairo_mutex_initialize (void);
-
- /* and make sure we implement the above */
-# define _CAIRO_MUTEX_USE_STATIC_INITIALIZER 1
-# endif /* CAIRO_MUTEX_INITIALIZE */
-
-#else /* no CAIRO_MUTEX_INIT */
-
-/* Otherwise we probably don't need to initialize static mutex'es, */
-# ifndef CAIRO_MUTEX_INITIALIZE
-# define CAIRO_MUTEX_INITIALIZE() CAIRO_MUTEX_NOOP
-# endif /* CAIRO_MUTEX_INITIALIZE */
-
-/* and dynamic ones can be initialized using the static initializer. */
-# define CAIRO_MUTEX_INIT(mutex) do { \
- cairo_mutex_t _tmp_mutex = CAIRO_MUTEX_NIL_INITIALIZER; \
- memcpy (&(mutex), &_tmp_mutex, sizeof (_tmp_mutex)); \
- } while (0)
-
-#endif /* CAIRO_MUTEX_INIT */
-
-
-#ifdef CAIRO_MUTEX_FINI
-
-/* If %CAIRO_MUTEX_FINI is defined, we may need to finalize all
- * static mutex'es. */
-# ifndef CAIRO_MUTEX_FINALIZE
-# define CAIRO_MUTEX_FINALIZE() do { \
- if (_cairo_mutex_initialized) \
- _cairo_mutex_finalize (); \
- } while(0)
-
- cairo_private void _cairo_mutex_finalize (void);
-
- /* and make sure we implement the above */
-# define _CAIRO_MUTEX_USE_STATIC_FINALIZER 1
-# endif /* CAIRO_MUTEX_FINALIZE */
-
-#else /* no CAIRO_MUTEX_FINI */
-
-/* Otherwise we probably don't need to finalize static mutex'es, */
-# ifndef CAIRO_MUTEX_FINALIZE
-# define CAIRO_MUTEX_FINALIZE() CAIRO_MUTEX_NOOP
-# endif /* CAIRO_MUTEX_FINALIZE */
-
-/* neither do the dynamic ones. */
-# define CAIRO_MUTEX_FINI(mutex) CAIRO_MUTEX_NOOP1(mutex)
-
-#endif /* CAIRO_MUTEX_FINI */
-
-
-#ifndef _CAIRO_MUTEX_USE_STATIC_INITIALIZER
-#define _CAIRO_MUTEX_USE_STATIC_INITIALIZER 0
+#if _CAIRO_MUTEX_IMPL_USE_STATIC_INITIALIZER
+cairo_private void _cairo_mutex_initialize (void);
#endif
-#ifndef _CAIRO_MUTEX_USE_STATIC_FINALIZER
-#define _CAIRO_MUTEX_USE_STATIC_FINALIZER 0
+#if _CAIRO_MUTEX_IMPL_USE_STATIC_FINALIZER
+cairo_private void _cairo_mutex_finalize (void);
#endif
-
/* only if using static initializer and/or finalizer define the boolean */
-#if _CAIRO_MUTEX_USE_STATIC_INITIALIZER || _CAIRO_MUTEX_USE_STATIC_FINALIZER
+#if _CAIRO_MUTEX_IMPL_USE_STATIC_INITIALIZER || _CAIRO_MUTEX_IMPL_USE_STATIC_FINALIZER
cairo_private extern cairo_bool_t _cairo_mutex_initialized;
#endif
+/* Finally, extern the static mutexes and undef */
-CAIRO_END_DECLS
+#define CAIRO_MUTEX_DECLARE(mutex) cairo_private extern cairo_mutex_t mutex
+#include "cairo-mutex-list-private.h"
+#undef CAIRO_MUTEX_DECLARE
-/* Make sure everything we want is defined */
-#ifndef CAIRO_MUTEX_INITIALIZE
-# error "CAIRO_MUTEX_INITIALIZE not defined"
-#endif
-#ifndef CAIRO_MUTEX_FINALIZE
-# error "CAIRO_MUTEX_FINALIZE not defined"
-#endif
-#ifndef CAIRO_MUTEX_LOCK
-# error "CAIRO_MUTEX_LOCK not defined"
-#endif
-#ifndef CAIRO_MUTEX_UNLOCK
-# error "CAIRO_MUTEX_UNLOCK not defined"
-#endif
-#ifndef CAIRO_MUTEX_INIT
-# error "CAIRO_MUTEX_INIT not defined"
-#endif
-#ifndef CAIRO_MUTEX_FINI
-# error "CAIRO_MUTEX_FINI not defined"
-#endif
-#ifndef CAIRO_MUTEX_NIL_INITIALIZER
-# error "CAIRO_MUTEX_NIL_INITIALIZER not defined"
-#endif
+CAIRO_END_DECLS
#endif
diff --git a/src/cairo-mutex-type-private.h b/src/cairo-mutex-type-private.h
index f68afb7..3dc5f49 100644
--- a/src/cairo-mutex-type-private.h
+++ b/src/cairo-mutex-type-private.h
@@ -47,176 +47,161 @@
#include <cairo-features.h>
-CAIRO_BEGIN_DECLS
+#include "cairo-compiler-private.h"
+#include "cairo-mutex-impl-private.h"
+/* 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."
+#endif
+#ifndef CAIRO_MUTEX_IMPL_UNLOCK
+# error "CAIRO_MUTEX_IMPL_UNLOCK not defined. Check cairo-mutex-impl-private.h."
+#endif
+#ifndef CAIRO_MUTEX_IMPL_NIL_INITIALIZER
+# error "CAIRO_MUTEX_IMPL_NIL_INITIALIZER not defined. Check cairo-mutex-impl-private.h."
+#endif
-/* A fully qualified no-operation statement */
-#define CAIRO_MUTEX_NOOP do {/*no-op*/} while (0)
-/* And one that evaluates it's argument once */
-#define CAIRO_MUTEX_NOOP1(expr) do { if (expr) ; } while (0)
+/* make sure implementations don't fool us: we decide these ourself */
+#undef _CAIRO_MUTEX_IMPL_USE_STATIC_INITIALIZER
+#undef _CAIRO_MUTEX_IMPL_USE_STATIC_FINALIZER
-/* Cairo mutex implementation:
- *
- * Any new mutex implementation needs to do the following:
- *
- * - Condition on the right header or feature. Headers are
- * preferred as eg. you still can use win32 mutex implementation
- * on a win32 system even if you do not compile the win32
- * surface/backend.
- *
- * - typedef #cairo_mutex_t to the proper mutex type on your target
- * system. Note that you may or may not need to use a pointer,
- * depending on what kinds of initialization your mutex
- * implementation supports. No trailing semicolon needed.
- * You should be able to compile the following snippet (don't try
- * running it):
- *
- * <programlisting>
- * cairo_mutex_t _cairo_some_mutex;
- * </programlisting>
- *
- * - #define CAIRO_MUTEX_LOCK(mutex) and CAIRO_MUTEX_UNLOCK(mutex) to
- * proper statement to lock/unlock the mutex object passed in.
- * You can (and should) assume that the mutex is already
- * initialized, and is-not-already-locked/is-locked,
- * respectively. Use the "do { ... } while (0)" idiom if necessary.
- * No trailing semicolons are needed (in any macro you define here).
- * You should be able to compile the following snippet:
- *
- * <programlisting>
- * cairo_mutex_t _cairo_some_mutex;
- *
- * if (1)
- * CAIRO_MUTEX_LOCK (_cairo_some_mutex);
- * else
- * CAIRO_MUTEX_UNLOCK (_cairo_some_mutex);
- * </programlisting>
- *
- * - #define %CAIRO_MUTEX_NIL_INITIALIZER to something that can
- * initialize the #cairo_mutex_t type you defined. Most of the
- * time one of 0, %NULL, or {} works. At this point
- * you should be able to compile the following snippet:
- *
- * <programlisting>
- * cairo_mutex_t _cairo_some_mutex = CAIRO_MUTEX_NIL_INITIALIZER;
- *
- * if (1)
- * CAIRO_MUTEX_LOCK (_cairo_some_mutex);
- * else
- * CAIRO_MUTEX_UNLOCK (_cairo_some_mutex);
- * </programlisting>
- *
- * - If the above code is not enough to initialize a mutex on
- * your platform, #define CAIRO_MUTEX_INIT(mutex) to statement
- * to initialize the mutex (allocate resources, etc). Such that
- * you should be able to compile AND RUN the following snippet:
- *
- * <programlisting>
- * cairo_mutex_t _cairo_some_mutex = CAIRO_MUTEX_NIL_INITIALIZER;
- *
- * CAIRO_MUTEX_INIT (_cairo_some_mutex);
- *
- * if (1)
- * CAIRO_MUTEX_LOCK (_cairo_some_mutex);
- * else
- * CAIRO_MUTEX_UNLOCK (_cairo_some_mutex);
- * </programlisting>
- *
- * - If you define CAIRO_MUTEX_INIT(mutex), cairo will use it to
- * initialize all static mutex'es. If for any reason that should
- * not happen (eg. %CAIRO_MUTEX_INIT is just a faster way than
- * what cairo does using %CAIRO_MUTEX_NIL_INITIALIZER), then
- * <programlisting>
- * #define CAIRO_MUTEX_INITIALIZE() CAIRO_MUTEX_NOOP
- * </programlisting>
- *
- * - If your system supports freeing a mutex object (deallocating
- * resources, etc), then #define CAIRO_MUTEX_FINI(mutex) to do
- * that.
- *
- * - If you define CAIRO_MUTEX_FINI(mutex), cairo will use it to
- * define a finalizer function to finalize all static mutex'es.
- * However, it's up to you to call CAIRO_MUTEX_FINALIZE() at
- * proper places, eg. when the system is unloading the cairo library.
- * So, if for any reason finalizing static mutex'es is not needed
- * (eg. you never call CAIRO_MUTEX_FINALIZE()), then
- * <programlisting>
- * #define CAIRO_MUTEX_FINALIZE() CAIRO_MUTEX_NOOP
- * </programlisting>
- *
- * - That is all. If for any reason you think the above API is
- * not enough to implement #cairo_mutex_t on your system, please
- * stop and write to the cairo mailing list about it. DO NOT
- * poke around cairo-mutex-private.h for possible solutions.
- */
-#if CAIRO_NO_MUTEX
+#ifdef CAIRO_MUTEX_IMPL_INIT
-/* No mutexes */
+/* If %CAIRO_MUTEX_IMPL_INIT is defined, we may need to initialize all
+ * static mutex'es. */
+# ifndef CAIRO_MUTEX_IMPL_INITIALIZE
+# define CAIRO_MUTEX_IMPL_INITIALIZE() do { \
+ if (!_cairo_mutex_initialized) \
+ _cairo_mutex_initialize (); \
+ } while(0)
- typedef int cairo_mutex_t;
+ /* and make sure we implement the above */
+# define _CAIRO_MUTEX_IMPL_USE_STATIC_INITIALIZER 1
+# endif /* CAIRO_MUTEX_IMPL_INITIALIZE */
-# define CAIRO_MUTEX_INITIALIZE() CAIRO_MUTEX_NOOP
-# define CAIRO_MUTEX_LOCK(mutex) CAIRO_MUTEX_NOOP1(mutex)
-# define CAIRO_MUTEX_UNLOCK(mutex) CAIRO_MUTEX_NOOP1(mutex)
-# define CAIRO_MUTEX_NIL_INITIALIZER 0
+#else /* no CAIRO_MUTEX_IMPL_INIT */
-#elif HAVE_PTHREAD_H /*******************************************************/
+/* Otherwise we probably don't need to initialize static mutex'es, */
+# ifndef CAIRO_MUTEX_IMPL_INITIALIZE
+# define CAIRO_MUTEX_IMPL_INITIALIZE() CAIRO_MUTEX_IMPL_NOOP
+# endif /* CAIRO_MUTEX_IMPL_INITIALIZE */
-# include <pthread.h>
+/* 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; \
+ memcpy (&(mutex), &_tmp_mutex, sizeof (_tmp_mutex)); \
+ } while (0)
- typedef pthread_mutex_t cairo_mutex_t;
+#endif /* CAIRO_MUTEX_IMPL_INIT */
-# define CAIRO_MUTEX_LOCK(mutex) pthread_mutex_lock (&(mutex))
-# define CAIRO_MUTEX_UNLOCK(mutex) pthread_mutex_unlock (&(mutex))
-# define CAIRO_MUTEX_FINI(mutex) pthread_mutex_destroy (&(mutex))
-# define CAIRO_MUTEX_FINALIZE() CAIRO_MUTEX_NOOP
-# define CAIRO_MUTEX_NIL_INITIALIZER PTHREAD_MUTEX_INITIALIZER
-#elif HAVE_WINDOWS_H /*******************************************************/
+#ifdef CAIRO_MUTEX_IMPL_FINI
-# include <windows.h>
+/* If %CAIRO_MUTEX_IMPL_FINI is defined, we may need to finalize all
+ * static mutex'es. */
+# ifndef CAIRO_MUTEX_IMPL_FINALIZE
+# define CAIRO_MUTEX_IMPL_FINALIZE() do { \
+ if (_cairo_mutex_initialized) \
+ _cairo_mutex_finalize (); \
+ } while(0)
- typedef CRITICAL_SECTION cairo_mutex_t;
+ /* and make sure we implement the above */
+# define _CAIRO_MUTEX_IMPL_USE_STATIC_FINALIZER 1
+# endif /* CAIRO_MUTEX_IMPL_FINALIZE */
-# define CAIRO_MUTEX_LOCK(mutex) EnterCriticalSection (&(mutex))
-# define CAIRO_MUTEX_UNLOCK(mutex) LeaveCriticalSection (&(mutex))
-# define CAIRO_MUTEX_INIT(mutex) InitializeCriticalSection (&(mutex))
-# define CAIRO_MUTEX_FINI(mutex) DeleteCriticalSection (&(mutex))
-# define CAIRO_MUTEX_NIL_INITIALIZER { NULL, 0, 0, NULL, NULL, 0 }
+#else /* no CAIRO_MUTEX_IMPL_FINI */
-#elif defined __OS2__ /******************************************************/
+/* Otherwise we probably don't need to finalize static mutex'es, */
+# ifndef CAIRO_MUTEX_IMPL_FINALIZE
+# define CAIRO_MUTEX_IMPL_FINALIZE() CAIRO_MUTEX_IMPL_NOOP
+# endif /* CAIRO_MUTEX_IMPL_FINALIZE */
-# define INCL_BASE
-# define INCL_PM
-# include <os2.h>
+/* neither do the dynamic ones. */
+# define CAIRO_MUTEX_IMPL_FINI(mutex) CAIRO_MUTEX_IMPL_NOOP1(mutex)
- typedef HMTX cairo_mutex_t;
+#endif /* CAIRO_MUTEX_IMPL_FINI */
-# define CAIRO_MUTEX_LOCK(mutex) DosRequestMutexSem(mutex, SEM_INDEFINITE_WAIT)
-# define CAIRO_MUTEX_UNLOCK(mutex) DosReleaseMutexSem(mutex)
-# define CAIRO_MUTEX_INIT(mutex) DosCreateMutexSem (NULL, &(mutex), 0L, FALSE)
-# define CAIRO_MUTEX_FINI(mutex) DosCloseMutexSem (mutex)
-# define CAIRO_MUTEX_NIL_INITIALIZER 0
-#elif CAIRO_HAS_BEOS_SURFACE /***********************************************/
+#ifndef _CAIRO_MUTEX_IMPL_USE_STATIC_INITIALIZER
+#define _CAIRO_MUTEX_IMPL_USE_STATIC_INITIALIZER 0
+#endif
+#ifndef _CAIRO_MUTEX_IMPL_USE_STATIC_FINALIZER
+#define _CAIRO_MUTEX_IMPL_USE_STATIC_FINALIZER 0
+#endif
- typedef BLocker* cairo_mutex_t;
-# define CAIRO_MUTEX_LOCK(mutex) (mutex)->Lock()
-# define CAIRO_MUTEX_UNLOCK(mutex) (mutex)->Unlock()
-# define CAIRO_MUTEX_INIT(mutex) (mutex) = new BLocker()
-# define CAIRO_MUTEX_FINI(mutex) delete (mutex)
-# define CAIRO_MUTEX_NIL_INITIALIZER NULL
+/* Make sure everything we want is defined */
+#ifndef CAIRO_MUTEX_IMPL_INITIALIZE
+# error "CAIRO_MUTEX_IMPL_INITIALIZE not defined"
+#endif
+#ifndef CAIRO_MUTEX_IMPL_FINALIZE
+# error "CAIRO_MUTEX_IMPL_FINALIZE not defined"
+#endif
+#ifndef CAIRO_MUTEX_IMPL_LOCK
+# error "CAIRO_MUTEX_IMPL_LOCK not defined"
+#endif
+#ifndef CAIRO_MUTEX_IMPL_UNLOCK
+# error "CAIRO_MUTEX_IMPL_UNLOCK not defined"
+#endif
+#ifndef CAIRO_MUTEX_IMPL_INIT
+# error "CAIRO_MUTEX_IMPL_INIT not defined"
+#endif
+#ifndef CAIRO_MUTEX_IMPL_FINI
+# error "CAIRO_MUTEX_IMPL_FINI not defined"
+#endif
+#ifndef CAIRO_MUTEX_IMPL_NIL_INITIALIZER
+# error "CAIRO_MUTEX_IMPL_NIL_INITIALIZER not defined"
+#endif
-#else /**********************************************************************/
-# error "XXX: No mutex implementation found. Cairo will not work with multiple threads. Define CAIRO_NO_MUTEX to 1 to acknowledge and accept this limitation and compile cairo without thread-safety support."
+/* Public interface. */
+/* By default it simply uses the implementation provided.
+ * But we can provide for debugging features by overriding them */
+#ifndef CAIRO_MUTEX_DEBUG
+typedef cairo_mutex_impl_t cairo_mutex_t;
+#else
+# define cairo_mutex_t cairo_mutex_impl_t
#endif
-CAIRO_END_DECLS
+#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
+#define CAIRO_MUTEX_FINI CAIRO_MUTEX_IMPL_FINI
+#define CAIRO_MUTEX_NIL_INITIALIZER CAIRO_MUTEX_IMPL_NIL_INITIALIZER
+
+
+
+/* Debugging support */
+
+#ifdef CAIRO_MUTEX_DEBUG
+
+# undef CAIRO_MUTEX_LOCK
+# undef CAIRO_MUTEX_UNLOCK
+# define CAIRO_MUTEX_LOCK(mutex) CAIRO_MUTEX_LOG_OP(mutex, "LOCK", CAIRO_MUTEX_IMPL_LOCK)
+# define CAIRO_MUTEX_UNLOCK(mutex) CAIRO_MUTEX_LOG_OP(mutex, "UNLOCK", CAIRO_MUTEX_IMPL_UNLOCK)
+
+#define CAIRO_MUTEX_LOG_OP(mutex, msg, op) \
+ do { cairo_mutex_t *__m = &(mutex); CAIRO_MUTEX_LOG(__m, msg); op(*__m); } while (0)
+
+
+#include <execinfo.h>
+#define CAIRO_MUTEX_LOG(mutex, msg) CAIRO_MUTEX_LOG0(mutex, CAIRO_MUTEX_DEBUG, msg)
+#define CAIRO_MUTEX_LOG0(mutex, which, msg) if (mutex == &which) CAIRO_MUTEX_LOG1(mutex, which, msg)
+#define CAIRO_MUTEX_LOG1(mutex, which, msg) \
+ do { \
+ void *buffer[10]; \
+ int nptrs; \
+ fprintf (stderr, "" #which " %s\n", msg); \
+ nptrs = backtrace(buffer, ARRAY_LENGTH (buffer)); \
+ backtrace_symbols_fd (buffer, nptrs, 2); \
+ } while (0)
+
+#endif /* CAIRO_MUTEX_DEBUG */
#endif
diff --git a/src/cairo-mutex.c b/src/cairo-mutex.c
index 88aaf0d..5149ee8 100644
--- a/src/cairo-mutex.c
+++ b/src/cairo-mutex.c
@@ -33,25 +33,27 @@
#include "cairoint.h"
+#include "cairo-mutex-private.h"
+
#define CAIRO_MUTEX_DECLARE(mutex) cairo_mutex_t mutex = CAIRO_MUTEX_NIL_INITIALIZER
#include "cairo-mutex-list-private.h"
#undef CAIRO_MUTEX_DECLARE
-#if _CAIRO_MUTEX_USE_STATIC_INITIALIZER || _CAIRO_MUTEX_USE_STATIC_FINALIZER
+#if _CAIRO_MUTEX_IMPL_USE_STATIC_INITIALIZER || _CAIRO_MUTEX_IMPL_USE_STATIC_FINALIZER
-# if _CAIRO_MUTEX_USE_STATIC_INITIALIZER
-# define _CAIRO_MUTEX_INITIALIZED_DEFAULT_VALUE FALSE
+# if _CAIRO_MUTEX_IMPL_USE_STATIC_INITIALIZER
+# define _CAIRO_MUTEX_IMPL_INITIALIZED_DEFAULT_VALUE FALSE
# else
-# define _CAIRO_MUTEX_INITIALIZED_DEFAULT_VALUE TRUE
+# define _CAIRO_MUTEX_IMPL_INITIALIZED_DEFAULT_VALUE TRUE
# endif
-cairo_bool_t _cairo_mutex_initialized = _CAIRO_MUTEX_INITIALIZED_DEFAULT_VALUE;
+cairo_bool_t _cairo_mutex_initialized = _CAIRO_MUTEX_IMPL_INITIALIZED_DEFAULT_VALUE;
-# undef _CAIRO_MUTEX_INITIALIZED_DEFAULT_VALUE
+# undef _CAIRO_MUTEX_IMPL_INITIALIZED_DEFAULT_VALUE
#endif
-#if _CAIRO_MUTEX_USE_STATIC_INITIALIZER
+#if _CAIRO_MUTEX_IMPL_USE_STATIC_INITIALIZER
void _cairo_mutex_initialize (void)
{
if (_cairo_mutex_initialized)
@@ -65,7 +67,7 @@ void _cairo_mutex_initialize (void)
}
#endif
-#if _CAIRO_MUTEX_USE_STATIC_FINALIZER
+#if _CAIRO_MUTEX_IMPL_USE_STATIC_FINALIZER
void _cairo_mutex_finalize (void)
{
if (!_cairo_mutex_initialized)
commit 07fef4f4802639a2cb16284841635d1bcc9b8e8f
Author: Ginn Chen <ginn.chen at sun.com>
Date: Tue May 27 04:44:08 2008 -0400
[cairo-xlib] Implement _cairo_xlib_surface_solid_fill_rectangles() (#11529)
diff --git a/src/cairo-xlib-surface.c b/src/cairo-xlib-surface.c
index 17d511c..662f4ad 100644
--- a/src/cairo-xlib-surface.c
+++ b/src/cairo-xlib-surface.c
@@ -1615,11 +1615,66 @@ _cairo_xlib_surface_composite (cairo_operator_t op,
}
static cairo_int_status_t
+_cairo_xlib_surface_solid_fill_rectangles (cairo_xlib_surface_t *surface,
+ const cairo_color_t *color,
+ cairo_rectangle_int_t *rects,
+ int num_rects)
+{
+ XGCValues gcv;
+ int a_width=0, r_width=0, g_width=0, b_width=0;
+ int a_shift=0, r_shift=0, g_shift=0, b_shift=0;
+ int a = color->alpha_short >> 8;
+ int r = color->red_short >> 8;
+ int g = color->green_short >> 8;
+ int b = color->blue_short >> 8;
+ int i;
+
+ if (surface->visual->class == TrueColor) {
+ _characterize_field (surface->a_mask, &a_width, &a_shift);
+ _characterize_field (surface->r_mask, &r_width, &r_shift);
+ _characterize_field (surface->g_mask, &g_width, &g_shift);
+ _characterize_field (surface->b_mask, &b_width, &b_shift);
+ gcv.foreground = (_field_from_8 (a, a_width, a_shift) |
+ _field_from_8 (r, r_width, r_shift) |
+ _field_from_8 (g, g_width, g_shift) |
+ _field_from_8 (b, b_width, b_shift));
+ } else {
+ cairo_xlib_visual_info_t *visual_info;
+ cairo_int_status_t status;
+
+ status = _cairo_xlib_screen_get_visual_info (surface->screen_info,
+ surface->visual,
+ &visual_info);
+ if (status)
+ return CAIRO_INT_STATUS_UNSUPPORTED;
+
+ gcv.foreground =
+ visual_info->rgb333_to_pseudocolor[_field_from_8 (r, 3, 6) |
+ _field_from_8 (g, 3, 3) |
+ _field_from_8 (b, 3, 0)];
+ }
+
+ GC xgc = XCreateGC (surface->dpy, surface->drawable, GCForeground,
+ &gcv);
+ if (!xgc)
+ return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+
+ for (i = 0; i < num_rects; i++) {
+ XFillRectangle (surface->dpy, surface->drawable, xgc,
+ rects[i].x, rects[i].y,
+ rects[i].width, rects[i].height);
+ }
+ XFreeGC(surface->dpy, xgc);
+
+ return CAIRO_STATUS_SUCCESS;
+}
+
+static cairo_int_status_t
_cairo_xlib_surface_fill_rectangles (void *abstract_surface,
cairo_operator_t op,
const cairo_color_t *color,
cairo_rectangle_int_t *rects,
- int num_rects)
+ int num_rects)
{
cairo_xlib_surface_t *surface = abstract_surface;
XRenderColor render_color;
@@ -1629,8 +1684,15 @@ _cairo_xlib_surface_fill_rectangles (void *abstract_surface,
_cairo_xlib_display_notify (surface->screen_info->display);
- if (!CAIRO_SURFACE_RENDER_HAS_FILL_RECTANGLE (surface))
+ if (!CAIRO_SURFACE_RENDER_HAS_FILL_RECTANGLE (surface)) {
+ if (op == CAIRO_OPERATOR_CLEAR ||
+ ((op == CAIRO_OPERATOR_SOURCE || op == CAIRO_OPERATOR_OVER) &&
+ CAIRO_COLOR_IS_OPAQUE(color))) {
+ return _cairo_xlib_surface_solid_fill_rectangles(surface, color,
+ rects, num_rects);
+ }
return CAIRO_INT_STATUS_UNSUPPORTED;
+ }
render_color.red = color->red_short;
render_color.green = color->green_short;
commit f90b155b5a59211bed7502b537dbf207b3d4bf5e
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Tue May 27 04:41:03 2008 -0400
[cairo-xlib] Delay using fallback if xrender is not available
So we can use XCopyArea when Render is not available. Based on patch by
Ginn Chen.
diff --git a/src/cairo-xlib-surface.c b/src/cairo-xlib-surface.c
index ec66c4d..17d511c 100644
--- a/src/cairo-xlib-surface.c
+++ b/src/cairo-xlib-surface.c
@@ -1407,6 +1407,9 @@ _recategorize_composite_operation (cairo_xlib_surface_t *dst,
if (!CAIRO_SURFACE_RENDER_HAS_COMPOSITE (src))
return DO_UNSUPPORTED;
+ if (!CAIRO_SURFACE_RENDER_HAS_COMPOSITE (dst))
+ return DO_UNSUPPORTED;
+
return DO_RENDER;
}
@@ -1475,9 +1478,6 @@ _cairo_xlib_surface_composite (cairo_operator_t op,
_cairo_xlib_display_notify (dst->screen_info->display);
- if (!CAIRO_SURFACE_RENDER_HAS_COMPOSITE (dst))
- return CAIRO_INT_STATUS_UNSUPPORTED;
-
operation = _categorize_composite_operation (dst, op, src_pattern,
mask_pattern != NULL);
if (operation == DO_UNSUPPORTED)
commit 30a16df29ba434d298d0c8d9dbb70c1b0a398f35
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Mon May 26 19:56:09 2008 -0400
[util/backtrace-symbols] Implement backtrace_symbols_fd()
diff --git a/util/backtrace-symbols.c b/util/backtrace-symbols.c
index e6ac256..1365b83 100644
--- a/util/backtrace-symbols.c
+++ b/util/backtrace-symbols.c
@@ -359,3 +359,21 @@ char **backtrace_symbols(void *const *buffer, int size)
return final;
}
+
+void
+backtrace_symbols_fd(void *const *buffer, int size, int fd)
+{
+ int j;
+ char **strings;
+
+ strings = backtrace_symbols(buffer, size);
+ if (strings == NULL) {
+ perror("backtrace_symbols");
+ exit(EXIT_FAILURE);
+ }
+
+ for (j = 0; j < size; j++)
+ printf("%s\n", strings[j]);
+
+ free(strings);
+}
More information about the cairo-commit
mailing list