1 dnl Defines the macro CAIRO_CONFIGURE_PTHREAD to find a suitable
2 dnl pthread implementation. There are two levels of pthread conformance
3 dnl we are looking for:
5 dnl a) A minimal level denoted by -DCAIRO_HAS_PTHREAD=1: This level
6 dnl requires mutex and recursive mutexattr support. If possible we try
7 dnl to use weakly linked stubs from libc over the real pthread library.
8 dnl This level is required by the cairo library proper. If the user
9 dnl invokes configure with --enable-pthread=yes or
10 dnl --enable-pthread=always then we avoid trying to use weak stubs.
12 dnl b) A full level denoted by -DCAIRO_HAS_REAL_PTHREAD=1: This level
13 dnl requires full support from a real pthread library, including thread
14 dnl creation, joins, thread attribtues, etc. This level is required by
15 dnl multithreaded applications using cairo, such as the test suite
16 dnl binaries and cairo utilities.
19 dnl CAIRO_ENABLE(pthread, pthread, <default yes|no|auto|always>,
20 dnl [CAIRO_CONFIGURE_PTHREAD])
22 dnl This should be invoked near the end of configure.ac so that
23 dnl the pthread specific CFLAGS and LIBS end up at the front
24 dnl of CAIRO_CFLAGS and CAIRO_LIBS -- this helps ensure that we
25 dnl really do get non-weak symbols from the actual pthread library
26 dnl rather than possible stubs in other libraries.
28 dnl The user can override the choices made by
29 dnl CAIRO_CONFIGURE_PTHREAD by using --enable-pthread=yes and
30 dnl giving PTHREAD_CFLAGS and PTHREAD_LIBS to configure.
32 dnl Sets environment variables:
33 dnl use_pthread="yes" | "no (<errmsg>)"
34 dnl have_pthread="yes" | "no (<errmsg)"
35 dnl have_real_pthread="yes" | "no (<errmsg)"
36 dnl pthread_{CFLAGS,LIBS,REQUIRES}
37 dnl real_pthread_{CFLAGS,LIBS}
39 dnl Autoconfigured defines in config.h (conditional):
41 dnl CAIRO_HAS_REAL_PTHREAD
44 dnl -----------------------------------------------------------------------
45 dnl A program to test all the pthread features we need to be able to
46 dnl compile libcairo itself. We could test the features independently,
47 dnl but we need all of them anyway.
48 m4_define([libcairo_pthread_program],[dnl
50 #define _GNU_SOURCE /* for PTHREAD_MUTEX_INITIALIZER under linux */
54 pthread_mutex_t test_mutex_initializer = PTHREAD_MUTEX_INITIALIZER;
58 pthread_mutex_t mutex;
59 x |= pthread_mutex_init (&mutex, NULL);
60 x |= pthread_mutex_lock (&mutex);
61 x |= pthread_mutex_unlock (&mutex);
62 x |= pthread_mutex_destroy (&mutex);
66 int test_mutex_attr (void)
69 pthread_mutexattr_t attr;
70 pthread_mutex_t mutex;
71 x |= pthread_mutexattr_init (&attr);
72 x |= pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_RECURSIVE);
73 x |= pthread_mutex_init (&mutex, &attr);
74 x |= pthread_mutex_lock (&mutex);
75 x |= pthread_mutex_unlock (&mutex);
76 x |= pthread_mutex_destroy (&mutex);
77 x |= pthread_mutexattr_destroy (&attr);
81 dnl -----------------------------------------------------------------------
82 dnl A program to test all the features we want to be able to run the test
83 dnl suite or other thready cairo applications that want real threads.
84 m4_define([testsuite_pthread_program],[dnl
85 libcairo_pthread_program
87 pthread_once_t once_control = PTHREAD_ONCE_INIT;
88 void test_once_init (void) {}
91 return pthread_once (&once_control, test_once_init);
94 pthread_key_t test_specific_key;
95 int test_specific (void)
98 x |= pthread_key_create (&test_specific_key, NULL);
99 x |= pthread_setspecific (test_specific_key, NULL);
100 x |= pthread_getspecific (test_specific_key) != NULL;
104 void cleaner (void *arg) { (void)arg; }
107 test_thread_main (void *arg)
109 pthread_cleanup_push (cleaner, arg);
111 pthread_cleanup_pop (1);
122 x |= pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED);
123 x |= pthread_create (&thread, &attr, test_thread_main, arg);
124 x |= pthread_equal (pthread_self(), thread);
125 x |= pthread_join (thread, &arg);
126 x |= pthread_attr_destroy (&attr);
130 dnl -----------------------------------------------------------------------
132 dnl CAIRO_CHECK_PTHREAD(tag, cflags, libs, program, true-action, false-action)
133 dnl Set <tag>_{CFLAGS,LIBS} to {<cflags>,<libs>} if we can compile and link
134 dnl <program> with the given flags and libs. Execute <true-action> on
135 dnl success and <false-action> on failure.
136 AC_DEFUN([CAIRO_CHECK_PTHREAD],[dnl
137 CAIRO_CC_TRY_LINK_WITH_ENV_SILENT(
138 [CFLAGS="$CFLAGS $2";
149 dnl CAIRO_CONFIGURE_PTHREADS(): Look for pthreads.
151 dnl If the user specifies PTHREAD_CFLAGS and PTHREAD_LIBS then we use
152 dnl those. Otherwise we try CFLAGS=-D_REENTRANT and LIBS=-lpthread for
153 dnl full pthread support, and look for stubs in libc for the minimal
156 dnl CFLAGS=-D_REENTRANT LIBS=-lpthread has been tested to work on:
158 dnl Solaris 9 (5.9) Sun C 5.8 Patch 121015-04 2007/01/10
159 dnl OpenSolaris (5.11) Sun C 5.9 Patch 124868-08 2008/11/25
160 dnl OpenSolaris (5.11) clang version 1.1 (trunk 90017)
161 dnl Tru64/OSF1 V5.1 Compaq C V6.5-003
162 dnl Mac OS X 10.5.5 gcc 4.0.1 (Apple Inc. build 5465)
163 dnl Mac OS X 10.6 gcc 4.2.1 (Apple Inc. build 5659)
164 dnl FreeBSD 7.2 gcc 4.2
165 dnl OpenBSD 4.5 gcc 3.3.5 (propolice)
166 dnl Debian Linux (Etch) gcc 4.3
168 dnl Thread support is also in various libcs directly, so often using no
169 dnl flags at all works as well, but unfortunately Solaris 9 has
170 dnl practically _all_ of libpthread stubbed out in libc, so we cannot
171 dnl distinguish between a working libpthread and a stubbed out one by a
174 dnl We also explicitly do not link to pthread-stubs or whatever other
175 dnl third-party stubs library, since that forces cairo clients to be
176 dnl extra careful when giving both libcairo and libpthread on the
177 dnl command line: the user would have to use "-lpthread -lcairo" rather
178 dnl than the more common "-lcairo -lpthread" to not accidentally use
179 dnl stubs pulled in by libcairo everywhere in the application. We
180 dnl might also need to have a way to teach pkg-config about library
181 dnl ordering constraints which aren't actual dependencies, and at this
182 dnl point it just starts doing my head in.
184 dnl If your unix-like doesn't work with the secret handshake
185 dnl -D_REENTRANT -lpthread and you can actually compile the rest of
186 dnl cairo just fine otherwise, please take a moment complain loudly
187 dnl to the cairo mailing list!
189 AC_DEFUN([CAIRO_CONFIGURE_PTHREAD],[dnl
190 dnl Try to use the user's PTHREAD_LIBS/CFLAGS
191 dnl if they're available.
192 if test "x$PTHREAD_CFLAGS" = "x"; then
193 PTHREAD_CFLAGS="-D_REENTRANT"
195 if test "x$PTHREAD_LIBS" = "x"; then
196 PTHREAD_LIBS="-lpthread"
199 dnl First try to find the real pthreads.
201 [real_pthread], [$PTHREAD_CFLAGS], [$PTHREAD_LIBS],
202 [testsuite_pthread_program],
203 [have_real_pthread=yes],
204 [have_real_pthread=no])
205 if test "x$have_real_pthread" != "xyes"; then
206 dnl Give -pthread a go.
208 [real_pthread], [-pthread], [],
209 [testsuite_pthread_program],
210 [have_real_pthread=yes],
211 [have_real_pthread="no (can't link with -lpthread or -pthread)"])
216 dnl Check if we can use libc's stubs in libcairo.
217 dnl Only do this if the user hasn't explicitly enabled
218 dnl pthreads, but is relying on automatic configuration.
220 if test "x$enable_pthread" != "xyes"; then
222 [pthread], [-D_REENTRANT], [],
223 [libcairo_pthread_program],
228 dnl Default to using the real pthreads for libcairo.
229 if test "x$have_pthread" != "xyes"; then
230 have_pthread="$have_real_pthread";
231 pthread_CFLAGS="$real_pthread_CFLAGS";
232 pthread_LIBS="$real_pthread_LIBS";
235 dnl Tell autoconf about the results.
236 if test "x$have_real_pthread" = "xyes"; then
237 AC_DEFINE([CAIRO_HAS_REAL_PTHREAD], 1,
238 [Define to 1 if we have full pthread support])
240 if test "x$have_pthread" = "xyes"; then
241 AC_DEFINE([CAIRO_HAS_PTHREAD], 1,
242 [Define to 1 f we have minimal pthread support])
245 dnl Make sure we scored some pthreads.
246 if test "x$enable_pthread" = "xyes" -a "x$have_pthread" != "xyes"; then
247 AC_MSG_ERROR([pthread requested but not found])
250 dnl Set the output variables for CAIRO_ENABLE.
251 use_pthread="$have_pthread"