summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--config.mak.in2
-rw-r--r--configure.ac37
-rw-r--r--gs/Makefile.in2
-rw-r--r--gs/base/gp_psync.c70
-rw-r--r--gs/configure.ac37
5 files changed, 108 insertions, 40 deletions
diff --git a/config.mak.in b/config.mak.in
index ccb84aee8..d962dda20 100644
--- a/config.mak.in
+++ b/config.mak.in
@@ -17,7 +17,7 @@ CC=@CC@
17CCAUX=@CC@ 17CCAUX=@CC@
18 18
19CONFDEFS?=@HAVE_MKSTEMP@ @HAVE_SSE2@ @HAVE_BSWAP32@ @HAVE_BYTESWAP_H@ @HAVE_SYS_TIME_H@ @HAVE_FSEEKO@ @HAVE_INTTYPES@ @HAVE_MKSTEMP64@ \ 19CONFDEFS?=@HAVE_MKSTEMP@ @HAVE_SSE2@ @HAVE_BSWAP32@ @HAVE_BYTESWAP_H@ @HAVE_SYS_TIME_H@ @HAVE_FSEEKO@ @HAVE_INTTYPES@ @HAVE_MKSTEMP64@ \
20@HAVE_FILE64@ @HAVE_PREAD_PWRITE@ 20@HAVE_FILE64@ @HAVE_PREAD_PWRITE@ @RECURSIVE_MUTEXATTR@
21 21
22ACCFLAGS?=@GCFLAGS@ 22ACCFLAGS?=@GCFLAGS@
23 23
diff --git a/configure.ac b/configure.ac
index 44b725256..5da03cab1 100644
--- a/configure.ac
+++ b/configure.ac
@@ -460,25 +460,36 @@ AC_SUBST(HAVE_PREAD_PWRITE)
460SYNC="nosync" 460SYNC="nosync"
461PTHREAD_LIBS="" 461PTHREAD_LIBS=""
462 462
463# if you haven't got pread/pwrite, we can't use multithreading 463AC_ARG_ENABLE([threading], AC_HELP_STRING([--disable-threading],
464if test "x$HAVE_PREAD_PWRITE" != "x"; then 464 [disable support for multithreaded rendering]))
465 465
466 case `uname` in
467 MINGW*)
468 AC_MSG_WARN([disabling support for pthreads......])
469 ;;
470 *)
471 AC_CHECK_LIB(pthread, pthread_create, [
472 SYNC=posync;
473 PTHREAD_LIBS="-lpthread"
474 ])
475 ;;
476 esac
477 466
467# if you haven't got pread/pwrite, we can't use multithreading
468if test "x$HAVE_PREAD_PWRITE" != "x"; then
469 if test "$enable_fontconfig" != "no"; then
470 case `uname` in
471 MINGW*)
472 AC_MSG_WARN([disabling support for pthreads......])
473 ;;
474 *)
475 AC_CHECK_LIB(pthread, pthread_create, [
476 SYNC=posync;
477 PTHREAD_LIBS="-lpthread"
478 ])
479 AC_TRY_COMPILE([#include <pthread.h>],
480 [static int k = PTHREAD_MUTEX_RECURSIVE;],
481 [RECURSIVE_MUTEXATTR="-DGS_RECURSIVE_MUTEXATTR=PTHREAD_MUTEX_RECURSIVE"],
482 [AC_TRY_COMPILE([#include <pthread.h>],
483 [static int k = PTHREAD_MUTEX_RECURSIVE_NP;],
484 [RECURSIVE_MUTEXATTR="-DGS_RECURSIVE_MUTEXATTR=PTHREAD_MUTEX_RECURSIVE_NP"])])
485 ;;
486 esac
487 fi
478fi 488fi
479 489
480AC_SUBST(SYNC) 490AC_SUBST(SYNC)
481AC_SUBST(PTHREAD_LIBS) 491AC_SUBST(PTHREAD_LIBS)
492AC_SUBST(RECURSIVE_MUTEXATTR)
482 493
483AC_PATH_X 494AC_PATH_X
484 495
diff --git a/gs/Makefile.in b/gs/Makefile.in
index c13462266..68f3dc598 100644
--- a/gs/Makefile.in
+++ b/gs/Makefile.in
@@ -142,7 +142,7 @@ GENOPT=
142# -DHAVE_SSE2 142# -DHAVE_SSE2
143# use sse2 intrinsics 143# use sse2 intrinsics
144 144
145CAPOPT= @HAVE_MKSTEMP@ @HAVE_FILE64@ @HAVE_FSEEKO@ @HAVE_MKSTEMP64@ @HAVE_FONTCONFIG@ @HAVE_LIBIDN@ @HAVE_SETLOCALE@ @HAVE_SSE2@ @HAVE_DBUS@ @HAVE_BSWAP32@ @HAVE_BYTESWAP_H@ @HAVE_STRERROR@ @HAVE_PREAD_PWRITE@ 145CAPOPT= @HAVE_MKSTEMP@ @HAVE_FILE64@ @HAVE_FSEEKO@ @HAVE_MKSTEMP64@ @HAVE_FONTCONFIG@ @HAVE_LIBIDN@ @HAVE_SETLOCALE@ @HAVE_SSE2@ @HAVE_DBUS@ @HAVE_BSWAP32@ @HAVE_BYTESWAP_H@ @HAVE_STRERROR@ @HAVE_PREAD_PWRITE@ @RECURSIVE_MUTEXATTR@
146 146
147# Define the name of the executable file. 147# Define the name of the executable file.
148 148
diff --git a/gs/base/gp_psync.c b/gs/base/gp_psync.c
index 60f697763..6ddf26653 100644
--- a/gs/base/gp_psync.c
+++ b/gs/base/gp_psync.c
@@ -128,13 +128,20 @@ gp_semaphore_signal(gp_semaphore * sema)
128/* Monitor supports enter/leave semantics */ 128/* Monitor supports enter/leave semantics */
129 129
130/* 130/*
131 * We need PTHREAD_MUTEX_RECURSIVE behavior, but this isn't totally portable 131 * We need PTHREAD_MUTEX_RECURSIVE behavior, but this isn't
132 * so we implement it in a more portable fashion, keeping track of the 132 * supported on all pthread platforms, so if it's available
133 * owner thread using 'pthread_self()' 133 * we'll use it, otherwise we'll emulate it.
134 * GS_RECURSIVE_MUTEXATTR is set by the configure script
135 * on Unix-like machines to the attribute setting for
136 * PTHREAD_MUTEX_RECURSIVE - on linux this is usually
137 * PTHREAD_MUTEX_RECURSIVE_NP
134 */ 138 */
135typedef struct gp_pthread_recursive_s { 139typedef struct gp_pthread_recursive_s {
136 pthread_mutex_t mutex; /* actual mutex */ 140 pthread_mutex_t mutex; /* actual mutex */
141#ifndef GS_RECURSIVE_MUTEXATTR
137 pthread_t self_id; /* owner */ 142 pthread_t self_id; /* owner */
143 int lcount;
144#endif
138} gp_pthread_recursive_t; 145} gp_pthread_recursive_t;
139 146
140uint 147uint
@@ -148,12 +155,32 @@ gp_monitor_open(gp_monitor * mona)
148{ 155{
149 pthread_mutex_t *mon; 156 pthread_mutex_t *mon;
150 int scode; 157 int scode;
158 pthread_mutexattr_t attr;
159 pthread_mutexattr_t *attrp = NULL;
151 160
152 if (!mona) 161 if (!mona)
153 return -1; /* monitors are not movable */ 162 return -1; /* monitors are not movable */
154 mon = &((gp_pthread_recursive_t *)mona)->mutex; 163
164
165#ifdef GS_RECURSIVE_MUTEXATTR
166 attrp = &attr;
167 scode = pthread_mutexattr_init(attrp);
168 if (scode < 0) goto done;
169
170 scode = pthread_mutexattr_settype(attrp, GS_RECURSIVE_MUTEXATTR);
171 if (scode < 0) {
172 goto done;
173 }
174#else
155 ((gp_pthread_recursive_t *)mona)->self_id = 0; /* Not valid unless mutex is locked */ 175 ((gp_pthread_recursive_t *)mona)->self_id = 0; /* Not valid unless mutex is locked */
156 scode = pthread_mutex_init(mon, NULL); 176 ((gp_pthread_recursive_t *)mona)->lcount = 0;
177#endif
178
179 mon = &((gp_pthread_recursive_t *)mona)->mutex;
180 scode = pthread_mutex_init(mon, attrp);
181 if (attrp)
182 (void)pthread_mutexattr_destroy(attrp);
183done:
157 return SEM_ERROR_CODE(scode); 184 return SEM_ERROR_CODE(scode);
158} 185}
159 186
@@ -173,29 +200,48 @@ gp_monitor_enter(gp_monitor * mona)
173 pthread_mutex_t * const mon = (pthread_mutex_t *)mona; 200 pthread_mutex_t * const mon = (pthread_mutex_t *)mona;
174 int scode; 201 int scode;
175 202
203#ifdef GS_RECURSIVE_MUTEXATTR
204 scode = pthread_mutex_lock(mon);
205#else
176 if ((scode = pthread_mutex_trylock(mon)) == 0) { 206 if ((scode = pthread_mutex_trylock(mon)) == 0) {
177 ((gp_pthread_recursive_t *)mona)->self_id = pthread_self(); 207 ((gp_pthread_recursive_t *)mona)->self_id = pthread_self();
178 return SEM_ERROR_CODE(scode); 208 ((gp_pthread_recursive_t *)mona)->lcount++;
179 } else { 209 } else {
180 if (pthread_equal(pthread_self(),((gp_pthread_recursive_t *)mona)->self_id)) 210 if (pthread_equal(pthread_self(),((gp_pthread_recursive_t *)mona)->self_id)) {
181 return 0; 211 ((gp_pthread_recursive_t *)mona)->lcount++;
212 scode = 0;
213 }
182 else { 214 else {
183 /* we were not the owner, wait */ 215 /* we were not the owner, wait */
184 scode = pthread_mutex_lock(mon); 216 scode = pthread_mutex_lock(mon);
185 ((gp_pthread_recursive_t *)mona)->self_id = pthread_self(); 217 ((gp_pthread_recursive_t *)mona)->self_id = pthread_self();
186 return SEM_ERROR_CODE(scode); 218 ((gp_pthread_recursive_t *)mona)->lcount++;
187 } 219 }
188 } 220 }
221#endif
222 return SEM_ERROR_CODE(scode);
189} 223}
190 224
191int 225int
192gp_monitor_leave(gp_monitor * mona) 226gp_monitor_leave(gp_monitor * mona)
193{ 227{
194 pthread_mutex_t * const mon = (pthread_mutex_t *)mona; 228 pthread_mutex_t * const mon = (pthread_mutex_t *)mona;
195 int scode; 229 int scode = 0;
196 230
197 scode = pthread_mutex_unlock(mon); 231#ifdef GS_RECURSIVE_MUTEXATTR
198 ((gp_pthread_recursive_t *)mona)->self_id = 0; /* Not valid unless mutex is locked */ 232 scode = pthread_mutex_lock(mon);
233#else
234 if (pthread_equal(pthread_self(),((gp_pthread_recursive_t *)mona)->self_id)) {
235 if ((--((gp_pthread_recursive_t *)mona)->lcount) == 0) {
236 scode = pthread_mutex_unlock(mon);
237 ((gp_pthread_recursive_t *)mona)->self_id = 0; /* Not valid unless mutex is locked */
238
239 }
240 }
241 else {
242 scode = -1 /* should be EPERM */;
243 }
244#endif
199 return SEM_ERROR_CODE(scode); 245 return SEM_ERROR_CODE(scode);
200} 246}
201 247
diff --git a/gs/configure.ac b/gs/configure.ac
index 5f64dd221..233129a90 100644
--- a/gs/configure.ac
+++ b/gs/configure.ac
@@ -498,26 +498,37 @@ AC_SUBST(HAVE_PREAD_PWRITE)
498 498
499SYNC="nosync" 499SYNC="nosync"
500PTHREAD_LIBS="" 500PTHREAD_LIBS=""
501RECURSIVE_MUTEXATTR=""
502
503AC_ARG_ENABLE([threading], AC_HELP_STRING([--disable-threading],
504 [disable support for multithreaded rendering]))
501 505
502# if you haven't got pread/pwrite, we can't use multithreading 506# if you haven't got pread/pwrite, we can't use multithreading
503if test "x$HAVE_PREAD_PWRITE" != "x"; then 507if test "x$HAVE_PREAD_PWRITE" != "x"; then
504 508 if test "$enable_fontconfig" != "no"; then
505 case `uname` in 509 case `uname` in
506 MINGW*) 510 MINGW*)
507 AC_MSG_WARN([disabling support for pthreads......]) 511 AC_MSG_WARN([disabling support for pthreads......])
508 ;; 512 ;;
509 *) 513 *)
510 AC_CHECK_LIB(pthread, pthread_create, [ 514 AC_CHECK_LIB(pthread, pthread_create, [
511 SYNC=posync; 515 SYNC=posync;
512 PTHREAD_LIBS="-lpthread" 516 PTHREAD_LIBS="-lpthread"
513 ]) 517 ])
514 ;; 518 AC_TRY_COMPILE([#include <pthread.h>],
515 esac 519 [static int k = PTHREAD_MUTEX_RECURSIVE;],
516 520 [RECURSIVE_MUTEXATTR="-DGS_RECURSIVE_MUTEXATTR=PTHREAD_MUTEX_RECURSIVE"],
521 [AC_TRY_COMPILE([#include <pthread.h>],
522 [static int k = PTHREAD_MUTEX_RECURSIVE_NP;],
523 [RECURSIVE_MUTEXATTR="-DGS_RECURSIVE_MUTEXATTR=PTHREAD_MUTEX_RECURSIVE_NP"])])
524 ;;
525 esac
526 fi
517fi 527fi
518 528
519AC_SUBST(SYNC) 529AC_SUBST(SYNC)
520AC_SUBST(PTHREAD_LIBS) 530AC_SUBST(PTHREAD_LIBS)
531AC_SUBST(RECURSIVE_MUTEXATTR)
521 532
522AC_MSG_CHECKING([for local trio library source]) 533AC_MSG_CHECKING([for local trio library source])
523if test -f $srcdir/trio/trio.h; then 534if test -f $srcdir/trio/trio.h; then