summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLudovic Courtès <ludo@gnu.org>2014-03-12 00:02:01 +0100
committerLudovic Courtès <ludo@gnu.org>2014-03-12 00:02:01 +0100
commit8f7887d61604073528544ccb09849ca0e2f4df78 (patch)
treefc79fca216e19e0873f8a377e543719b9a7570d5
parentde7aa61ac48811610b1b99005ada2464cf1a96f1 (diff)
downloadguile-8f7887d61604073528544ccb09849ca0e2f4df78.tar.gz
Provide glthread/lock.h implementation in terms of Guile threads.
Fixes <http://bugs.gnu.org/14404>. Thanks to Paul Eggert <eggert@cs.ucla.edu> for the suggestion. * m4/gnulib-cache.m4: Avoid 'lock' module. * m4/lock.m4, m4/threadlib.m4, lib/glthread/threadlib.c, lib/glthread/lock.c: Remove. * lib/glthread/lock.h: Rewrite in terms of libguile/threads.h. * m4/gnulib-common.m4, m4/gnulib-comp.m4, lib/Makefile.am, lib/unistd.in.h, maint.mk : Update, from Gnulib v0.1-92-g546ff82. * configure.ac (GNULIB_LOCK): Define 'GNULIB_LOCK'. Define 'USE_POSIX_THREADS' when building with pthread support. * Makefile.am (noinst_HEADERS): New variable. (BUILT_SOURCES): Add libguile/scmconfig.h. (libguile/scmconfig.h): New target.
-rw-r--r--Makefile.am15
-rw-r--r--configure.ac14
-rw-r--r--lib/Makefile.am17
-rw-r--r--lib/glthread/lock.c1057
-rw-r--r--lib/glthread/lock.h955
-rw-r--r--lib/glthread/threadlib.c73
-rw-r--r--lib/unistd.in.h15
-rw-r--r--m4/gnulib-cache.m44
-rw-r--r--m4/gnulib-common.m456
-rw-r--r--m4/gnulib-comp.m412
-rw-r--r--m4/lock.m442
-rw-r--r--m4/threadlib.m4371
-rw-r--r--maint.mk35
13 files changed, 151 insertions, 2515 deletions
diff --git a/Makefile.am b/Makefile.am
index 2ed837046..8f9e014c7 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,7 +1,8 @@
## Process this file with automake to produce Makefile.in.
##
## Copyright (C) 1998, 1999, 2000, 2001, 2002, 2006, 2007,
-## 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+## 2008, 2009, 2010, 2011, 2012, 2013,
+## 2014 Free Software Foundation, Inc.
##
## This file is part of GUILE.
##
@@ -45,6 +46,16 @@ libguileinclude_HEADERS = libguile.h
schemelibdir = $(pkgdatadir)/$(GUILE_EFFECTIVE_VERSION)
schemelib_DATA = libguile/guile-procedures.txt
+# Our own implementation of Gnulib's lock interface.
+noinst_HEADERS = lib/glthread/lock.h
+
+# Our lib/glthreads/lock.h header indirectly includes
+# libguile/scmconfig.h. Make sure it is built before we recurse into
+# lib/.
+BUILT_SOURCES = libguile/scmconfig.h
+libguile/scmconfig.h:
+ $(MAKE) -C libguile scmconfig.h
+
# Build it from here so that all the modules are compiled by the time we
# build it.
libguile/guile-procedures.txt: libguile/guile-procedures.texi
@@ -94,7 +105,7 @@ gen-ChangeLog:
mv $(distdir)/cl-t $(distdir)/ChangeLog; \
fi
-BUILT_SOURCES = $(top_srcdir)/.version
+BUILT_SOURCES += $(top_srcdir)/.version
$(top_srcdir)/.version:
echo $(VERSION) > $@-t && mv $@-t $@
gen-tarball-version:
diff --git a/configure.ac b/configure.ac
index a5cb4b867..947296ba7 100644
--- a/configure.ac
+++ b/configure.ac
@@ -76,6 +76,13 @@ AM_PROG_AR
dnl Gnulib.
gl_INIT
+dnl We provide our own lib/glthread/lock.h, so let other Gnulib modules
+dnl know that we have it. This allows them to be compiled with adequate
+dnl locking support. See <http://bugs.gnu.org/14404>.
+AC_DEFINE([GNULIB_LOCK], [1],
+ [Define to allow Gnulib modules to use Guile's locks.])
+
+
AC_PROG_CC_C89
# for per-target cflags in the libguile subdir
@@ -1437,10 +1444,13 @@ AM_CONDITIONAL([BUILD_PTHREAD_SUPPORT],
[test "x$build_pthread_support" = "xyes"])
-## Check whether pthread_attr_getstack works for the main thread
-
if test "$with_threads" = pthreads; then
+dnl Normally Gnulib's 'threadlib' module would define this macro, but
+dnl since we don't use it, define it by ourselves.
+AC_DEFINE([USE_POSIX_THREADS], [1],
+ [Define to let Gnulib modules know that we use POSIX threads.])
+
AC_MSG_CHECKING([whether pthread_attr_getstack works for the main thread])
old_CFLAGS="$CFLAGS"
CFLAGS="$PTHREAD_CFLAGS $CFLAGS"
diff --git a/lib/Makefile.am b/lib/Makefile.am
index 8b643c72b..5d9c902fc 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -21,7 +21,7 @@
# the same distribution terms as the rest of that program.
#
# Generated by gnulib-tool.
-# Reproduce by: gnulib-tool --import --dir=. --local-dir=gnulib-local --lib=libgnu --source-base=lib --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=build-aux --lgpl=3 --no-conditional-dependencies --libtool --macro-prefix=gl --no-vc-files accept alignof alloca-opt announce-gen autobuild bind byteswap c-strcase canonicalize-lgpl ceil clock-time close connect copysign dirfd duplocale environ extensions flock floor fpieee frexp fstat fsync full-read full-write func gendocs getaddrinfo getlogin getpeername getsockname getsockopt git-version-gen gitlog-to-changelog gnu-web-doc-update gnupload havelib iconv_open-utf inet_ntop inet_pton isfinite isinf isnan ldexp lib-symbol-versions lib-symbol-visibility libunistring link listen localcharset locale log1p lstat maintainer-makefile malloc-gnu malloca mkdir mkstemp nl_langinfo nproc open pipe-posix pipe2 poll putenv readlink recv recvfrom regex rename rmdir select send sendto setenv setsockopt shutdown socket stat-time stdlib strftime striconveh string sys_stat time times trunc unistd verify vsnprintf warnings wchar
+# Reproduce by: gnulib-tool --import --dir=. --local-dir=gnulib-local --lib=libgnu --source-base=lib --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=build-aux --avoid=lock --lgpl=3 --no-conditional-dependencies --libtool --macro-prefix=gl --no-vc-files accept alignof alloca-opt announce-gen autobuild bind byteswap c-strcase canonicalize-lgpl ceil clock-time close connect copysign dirfd duplocale environ extensions flock floor fpieee frexp fstat fsync full-read full-write func gendocs getaddrinfo getlogin getpeername getsockname getsockopt git-version-gen gitlog-to-changelog gnu-web-doc-update gnupload havelib iconv_open-utf inet_ntop inet_pton isfinite isinf isnan ldexp lib-symbol-versions lib-symbol-visibility libunistring link listen localcharset locale log1p lstat maintainer-makefile malloc-gnu malloca mkdir mkstemp nl_langinfo nproc open pipe-posix pipe2 poll putenv readlink recv recvfrom regex rename rmdir select send sendto setenv setsockopt shutdown socket stat-time stdlib strftime striconveh string sys_stat time times trunc unistd verify vsnprintf warnings wchar
AUTOMAKE_OPTIONS = 1.9.6 gnits subdir-objects
@@ -69,7 +69,6 @@ libgnu_la_LDFLAGS += $(LOG1P_LIBM)
libgnu_la_LDFLAGS += $(LOG_LIBM)
libgnu_la_LDFLAGS += $(LTLIBICONV)
libgnu_la_LDFLAGS += $(LTLIBINTL)
-libgnu_la_LDFLAGS += $(LTLIBTHREAD)
libgnu_la_LDFLAGS += $(LTLIBUNISTRING)
libgnu_la_LDFLAGS += $(ROUND_LIBM)
libgnu_la_LDFLAGS += $(SERVENT_LIB)
@@ -1050,12 +1049,6 @@ EXTRA_libgnu_la_SOURCES += localeconv.c
## end gnulib module localeconv
-## begin gnulib module lock
-
-libgnu_la_SOURCES += glthread/lock.h glthread/lock.c
-
-## end gnulib module lock
-
## begin gnulib module log
@@ -2799,14 +2792,6 @@ EXTRA_DIST += tempname.h
## end gnulib module tempname
-## begin gnulib module threadlib
-
-libgnu_la_SOURCES += glthread/threadlib.c
-
-EXTRA_DIST += $(top_srcdir)/build-aux/config.rpath
-
-## end gnulib module threadlib
-
## begin gnulib module time
BUILT_SOURCES += time.h
diff --git a/lib/glthread/lock.c b/lib/glthread/lock.c
deleted file mode 100644
index 0454cc251..000000000
--- a/lib/glthread/lock.c
+++ /dev/null
@@ -1,1057 +0,0 @@
-/* Locking in multithreaded situations.
- Copyright (C) 2005-2014 Free Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with this program; if not, see <http://www.gnu.org/licenses/>. */
-
-/* Written by Bruno Haible <bruno@clisp.org>, 2005.
- Based on GCC's gthr-posix.h, gthr-posix95.h, gthr-solaris.h,
- gthr-win32.h. */
-
-#include <config.h>
-
-#include "glthread/lock.h"
-
-/* ========================================================================= */
-
-#if USE_POSIX_THREADS
-
-/* -------------------------- gl_lock_t datatype -------------------------- */
-
-/* ------------------------- gl_rwlock_t datatype ------------------------- */
-
-# if HAVE_PTHREAD_RWLOCK
-
-# if !defined PTHREAD_RWLOCK_INITIALIZER
-
-int
-glthread_rwlock_init_multithreaded (gl_rwlock_t *lock)
-{
- int err;
-
- err = pthread_rwlock_init (&lock->rwlock, NULL);
- if (err != 0)
- return err;
- lock->initialized = 1;
- return 0;
-}
-
-int
-glthread_rwlock_rdlock_multithreaded (gl_rwlock_t *lock)
-{
- if (!lock->initialized)
- {
- int err;
-
- err = pthread_mutex_lock (&lock->guard);
- if (err != 0)
- return err;
- if (!lock->initialized)
- {
- err = glthread_rwlock_init_multithreaded (lock);
- if (err != 0)
- {
- pthread_mutex_unlock (&lock->guard);
- return err;
- }
- }
- err = pthread_mutex_unlock (&lock->guard);
- if (err != 0)
- return err;
- }
- return pthread_rwlock_rdlock (&lock->rwlock);
-}
-
-int
-glthread_rwlock_wrlock_multithreaded (gl_rwlock_t *lock)
-{
- if (!lock->initialized)
- {
- int err;
-
- err = pthread_mutex_lock (&lock->guard);
- if (err != 0)
- return err;
- if (!lock->initialized)
- {
- err = glthread_rwlock_init_multithreaded (lock);
- if (err != 0)
- {
- pthread_mutex_unlock (&lock->guard);
- return err;
- }
- }
- err = pthread_mutex_unlock (&lock->guard);
- if (err != 0)
- return err;
- }
- return pthread_rwlock_wrlock (&lock->rwlock);
-}
-
-int
-glthread_rwlock_unlock_multithreaded (gl_rwlock_t *lock)
-{
- if (!lock->initialized)
- return EINVAL;
- return pthread_rwlock_unlock (&lock->rwlock);
-}
-
-int
-glthread_rwlock_destroy_multithreaded (gl_rwlock_t *lock)
-{
- int err;
-
- if (!lock->initialized)
- return EINVAL;
- err = pthread_rwlock_destroy (&lock->rwlock);
- if (err != 0)
- return err;
- lock->initialized = 0;
- return 0;
-}
-
-# endif
-
-# else
-
-int
-glthread_rwlock_init_multithreaded (gl_rwlock_t *lock)
-{
- int err;
-
- err = pthread_mutex_init (&lock->lock, NULL);
- if (err != 0)
- return err;
- err = pthread_cond_init (&lock->waiting_readers, NULL);
- if (err != 0)
- return err;
- err = pthread_cond_init (&lock->waiting_writers, NULL);
- if (err != 0)
- return err;
- lock->waiting_writers_count = 0;
- lock->runcount = 0;
- return 0;
-}
-
-int
-glthread_rwlock_rdlock_multithreaded (gl_rwlock_t *lock)
-{
- int err;
-
- err = pthread_mutex_lock (&lock->lock);
- if (err != 0)
- return err;
- /* Test whether only readers are currently running, and whether the runcount
- field will not overflow. */
- /* POSIX says: "It is implementation-defined whether the calling thread
- acquires the lock when a writer does not hold the lock and there are
- writers blocked on the lock." Let's say, no: give the writers a higher
- priority. */
- while (!(lock->runcount + 1 > 0 && lock->waiting_writers_count == 0))
- {
- /* This thread has to wait for a while. Enqueue it among the
- waiting_readers. */
- err = pthread_cond_wait (&lock->waiting_readers, &lock->lock);
- if (err != 0)
- {
- pthread_mutex_unlock (&lock->lock);
- return err;
- }
- }
- lock->runcount++;
- return pthread_mutex_unlock (&lock->lock);
-}
-
-int
-glthread_rwlock_wrlock_multithreaded (gl_rwlock_t *lock)
-{
- int err;
-
- err = pthread_mutex_lock (&lock->lock);
- if (err != 0)
- return err;
- /* Test whether no readers or writers are currently running. */
- while (!(lock->runcount == 0))
- {
- /* This thread has to wait for a while. Enqueue it among the
- waiting_writers. */
- lock->waiting_writers_count++;
- err = pthread_cond_wait (&lock->waiting_writers, &lock->lock);
- if (err != 0)
- {
- lock->waiting_writers_count--;
- pthread_mutex_unlock (&lock->lock);
- return err;
- }
- lock->waiting_writers_count--;
- }
- lock->runcount--; /* runcount becomes -1 */
- return pthread_mutex_unlock (&lock->lock);
-}
-
-int
-glthread_rwlock_unlock_multithreaded (gl_rwlock_t *lock)
-{
- int err;
-
- err = pthread_mutex_lock (&lock->lock);
- if (err != 0)
- return err;
- if (lock->runcount < 0)
- {
- /* Drop a writer lock. */
- if (!(lock->runcount == -1))
- {
- pthread_mutex_unlock (&lock->lock);
- return EINVAL;
- }
- lock->runcount = 0;
- }
- else
- {
- /* Drop a reader lock. */
- if (!(lock->runcount > 0))
- {
- pthread_mutex_unlock (&lock->lock);
- return EINVAL;
- }
- lock->runcount--;
- }
- if (lock->runcount == 0)
- {
- /* POSIX recommends that "write locks shall take precedence over read
- locks", to avoid "writer starvation". */
- if (lock->waiting_writers_count > 0)
- {
- /* Wake up one of the waiting writers. */
- err = pthread_cond_signal (&lock->waiting_writers);
- if (err != 0)
- {
- pthread_mutex_unlock (&lock->lock);
- return err;
- }
- }
- else
- {
- /* Wake up all waiting readers. */
- err = pthread_cond_broadcast (&lock->waiting_readers);
- if (err != 0)
- {
- pthread_mutex_unlock (&lock->lock);
- return err;
- }
- }
- }
- return pthread_mutex_unlock (&lock->lock);
-}
-
-int
-glthread_rwlock_destroy_multithreaded (gl_rwlock_t *lock)
-{
- int err;
-
- err = pthread_mutex_destroy (&lock->lock);
- if (err != 0)
- return err;
- err = pthread_cond_destroy (&lock->waiting_readers);
- if (err != 0)
- return err;
- err = pthread_cond_destroy (&lock->waiting_writers);
- if (err != 0)
- return err;
- return 0;
-}
-
-# endif
-
-/* --------------------- gl_recursive_lock_t datatype --------------------- */
-
-# if HAVE_PTHREAD_MUTEX_RECURSIVE
-
-# if defined PTHREAD_RECURSIVE_MUTEX_INITIALIZER || defined PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
-
-int
-glthread_recursive_lock_init_multithreaded (gl_recursive_lock_t *lock)
-{
- pthread_mutexattr_t attributes;
- int err;
-
- err = pthread_mutexattr_init (&attributes);
- if (err != 0)
- return err;
- err = pthread_mutexattr_settype (&attributes, PTHREAD_MUTEX_RECURSIVE);
- if (err != 0)
- {
- pthread_mutexattr_destroy (&attributes);
- return err;
- }
- err = pthread_mutex_init (lock, &attributes);
- if (err != 0)
- {
- pthread_mutexattr_destroy (&attributes);
- return err;
- }
- err = pthread_mutexattr_destroy (&attributes);
- if (err != 0)
- return err;
- return 0;
-}
-
-# else
-
-int
-glthread_recursive_lock_init_multithreaded (gl_recursive_lock_t *lock)
-{
- pthread_mutexattr_t attributes;
- int err;
-
- err = pthread_mutexattr_init (&attributes);
- if (err != 0)
- return err;
- err = pthread_mutexattr_settype (&attributes, PTHREAD_MUTEX_RECURSIVE);
- if (err != 0)
- {
- pthread_mutexattr_destroy (&attributes);
- return err;
- }
- err = pthread_mutex_init (&lock->recmutex, &attributes);
- if (err != 0)
- {
- pthread_mutexattr_destroy (&attributes);
- return err;
- }
- err = pthread_mutexattr_destroy (&attributes);
- if (err != 0)
- return err;
- lock->initialized = 1;
- return 0;
-}
-
-int
-glthread_recursive_lock_lock_multithreaded (gl_recursive_lock_t *lock)
-{
- if (!lock->initialized)
- {
- int err;
-
- err = pthread_mutex_lock (&lock->guard);
- if (err != 0)
- return err;
- if (!lock->initialized)
- {
- err = glthread_recursive_lock_init_multithreaded (lock);
- if (err != 0)
- {
- pthread_mutex_unlock (&lock->guard);
- return err;
- }
- }
- err = pthread_mutex_unlock (&lock->guard);
- if (err != 0)
- return err;
- }
- return pthread_mutex_lock (&lock->recmutex);
-}
-
-int
-glthread_recursive_lock_unlock_multithreaded (gl_recursive_lock_t *lock)
-{
- if (!lock->initialized)
- return EINVAL;
- return pthread_mutex_unlock (&lock->recmutex);
-}
-
-int
-glthread_recursive_lock_destroy_multithreaded (gl_recursive_lock_t *lock)
-{
- int err;
-
- if (!lock->initialized)
- return EINVAL;
- err = pthread_mutex_destroy (&lock->recmutex);
- if (err != 0)
- return err;
- lock->initialized = 0;
- return 0;
-}
-
-# endif
-
-# else
-
-int
-glthread_recursive_lock_init_multithreaded (gl_recursive_lock_t *lock)
-{
- int err;
-
- err = pthread_mutex_init (&lock->mutex, NULL);
- if (err != 0)
- return err;
- lock->owner = (pthread_t) 0;
- lock->depth = 0;
- return 0;
-}
-
-int
-glthread_recursive_lock_lock_multithreaded (gl_recursive_lock_t *lock)
-{
- pthread_t self = pthread_self ();
- if (lock->owner != self)
- {
- int err;
-
- err = pthread_mutex_lock (&lock->mutex);
- if (err != 0)
- return err;
- lock->owner = self;
- }
- if (++(lock->depth) == 0) /* wraparound? */
- {
- lock->depth--;
- return EAGAIN;
- }
- return 0;
-}
-
-int
-glthread_recursive_lock_unlock_multithreaded (gl_recursive_lock_t *lock)
-{
- if (lock->owner != pthread_self ())
- return EPERM;
- if (lock->depth == 0)
- return EINVAL;
- if (--(lock->depth) == 0)
- {
- lock->owner = (pthread_t) 0;
- return pthread_mutex_unlock (&lock->mutex);
- }
- else
- return 0;
-}
-
-int
-glthread_recursive_lock_destroy_multithreaded (gl_recursive_lock_t *lock)
-{
- if (lock->owner != (pthread_t) 0)
- return EBUSY;
- return pthread_mutex_destroy (&lock->mutex);
-}
-
-# endif
-
-/* -------------------------- gl_once_t datatype -------------------------- */
-
-static const pthread_once_t fresh_once = PTHREAD_ONCE_INIT;
-
-int
-glthread_once_singlethreaded (pthread_once_t *once_control)
-{
- /* We don't know whether pthread_once_t is an integer type, a floating-point
- type, a pointer type, or a structure type. */
- char *firstbyte = (char *)once_control;
- if (*firstbyte == *(const char *)&fresh_once)
- {
- /* First time use of once_control. Invert the first byte. */
- *firstbyte = ~ *(const char *)&fresh_once;
- return 1;
- }
- else
- return 0;
-}
-
-#endif
-
-/* ========================================================================= */
-
-#if USE_PTH_THREADS
-
-/* Use the GNU Pth threads library. */
-
-/* -------------------------- gl_lock_t datatype -------------------------- */
-
-/* ------------------------- gl_rwlock_t datatype ------------------------- */
-
-/* --------------------- gl_recursive_lock_t datatype --------------------- */
-
-/* -------------------------- gl_once_t datatype -------------------------- */
-
-static void
-glthread_once_call (void *arg)
-{
- void (**gl_once_temp_addr) (void) = (void (**) (void)) arg;
- void (*initfunction) (void) = *gl_once_temp_addr;
- initfunction ();
-}
-
-int
-glthread_once_multithreaded (pth_once_t *once_control, void (*initfunction) (void))
-{
- void (*temp) (void) = initfunction;
- return (!pth_once (once_control, glthread_once_call, &temp) ? errno : 0);
-}
-
-int
-glthread_once_singlethreaded (pth_once_t *once_control)
-{
- /* We know that pth_once_t is an integer type. */
- if (*once_control == PTH_ONCE_INIT)
- {
- /* First time use of once_control. Invert the marker. */
- *once_control = ~ PTH_ONCE_INIT;
- return 1;
- }
- else
- return 0;
-}
-
-#endif
-
-/* ========================================================================= */
-
-#if USE_SOLARIS_THREADS
-
-/* Use the old Solaris threads library. */
-
-/* -------------------------- gl_lock_t datatype -------------------------- */
-
-/* ------------------------- gl_rwlock_t datatype ------------------------- */
-
-/* --------------------- gl_recursive_lock_t datatype --------------------- */
-
-int
-glthread_recursive_lock_init_multithreaded (gl_recursive_lock_t *lock)
-{
- int err;
-
- err = mutex_init (&lock->mutex, USYNC_THREAD, NULL);
- if (err != 0)
- return err;
- lock->owner = (thread_t) 0;
- lock->depth = 0;
- return 0;
-}
-
-int
-glthread_recursive_lock_lock_multithreaded (gl_recursive_lock_t *lock)
-{
- thread_t self = thr_self ();
- if (lock->owner != self)
- {
- int err;
-
- err = mutex_lock (&lock->mutex);
- if (err != 0)
- return err;
- lock->owner = self;
- }
- if (++(lock->depth) == 0) /* wraparound? */
- {
- lock->depth--;
- return EAGAIN;
- }
- return 0;
-}
-
-int
-glthread_recursive_lock_unlock_multithreaded (gl_recursive_lock_t *lock)
-{
- if (lock->owner != thr_self ())
- return EPERM;
- if (lock->depth == 0)
- return EINVAL;
- if (--(lock->depth) == 0)
- {
- lock->owner = (thread_t) 0;
- return mutex_unlock (&lock->mutex);
- }
- else
- return 0;
-}
-
-int
-glthread_recursive_lock_destroy_multithreaded (gl_recursive_lock_t *lock)
-{
- if (lock->owner != (thread_t) 0)
- return EBUSY;
- return mutex_destroy (&lock->mutex);
-}
-
-/* -------------------------- gl_once_t datatype -------------------------- */
-
-int
-glthread_once_multithreaded (gl_once_t *once_control, void (*initfunction) (void))
-{
- if (!once_control->inited)
- {
- int err;
-
- /* Use the mutex to guarantee that if another thread is already calling
- the initfunction, this thread waits until it's finished. */
- err = mutex_lock (&once_control->mutex);
- if (err != 0)
- return err;
- if (!once_control->inited)
- {
- once_control->inited = 1;
- initfunction ();
- }
- return mutex_unlock (&once_control->mutex);
- }
- else
- return 0;
-}
-
-int
-glthread_once_singlethreaded (gl_once_t *once_control)
-{
- /* We know that gl_once_t contains an integer type. */
- if (!once_control->inited)
- {
- /* First time use of once_control. Invert the marker. */
- once_control->inited = ~ 0;
- return 1;
- }
- else
- return 0;
-}
-
-#endif
-
-/* ========================================================================= */
-
-#if USE_WINDOWS_THREADS
-
-/* -------------------------- gl_lock_t datatype -------------------------- */
-
-void
-glthread_lock_init_func (gl_lock_t *lock)
-{
- InitializeCriticalSection (&lock->lock);
- lock->guard.done = 1;
-}
-
-int
-glthread_lock_lock_func (gl_lock_t *lock)
-{
- if (!lock->guard.done)
- {
- if (InterlockedIncrement (&lock->guard.started) == 0)
- /* This thread is the first one to need this lock. Initialize it. */
- glthread_lock_init (lock);
- else
- /* Yield the CPU while waiting for another thread to finish
- initializing this lock. */
- while (!lock->guard.done)
- Sleep (0);
- }
- EnterCriticalSection (&lock->lock);
- return 0;
-}
-
-int
-glthread_lock_unlock_func (gl_lock_t *lock)
-{
- if (!lock->guard.done)
- return EINVAL;
- LeaveCriticalSection (&lock->lock);
- return 0;
-}
-
-int
-glthread_lock_destroy_func (gl_lock_t *lock)
-{
- if (!lock->guard.done)
- return EINVAL;
- DeleteCriticalSection (&lock->lock);
- lock->guard.done = 0;
- return 0;
-}
-
-/* ------------------------- gl_rwlock_t datatype ------------------------- */
-
-/* In this file, the waitqueues are implemented as circular arrays. */
-#define gl_waitqueue_t gl_carray_waitqueue_t
-
-static void
-gl_waitqueue_init (gl_waitqueue_t *wq)
-{
- wq->array = NULL;
- wq->count = 0;
- wq->alloc = 0;
- wq->offset = 0;
-}
-
-/* Enqueues the current thread, represented by an event, in a wait queue.
- Returns INVALID_HANDLE_VALUE if an allocation failure occurs. */
-static HANDLE
-gl_waitqueue_add (gl_waitqueue_t *wq)
-{
- HANDLE event;
- unsigned int index;
-
- if (wq->count == wq->alloc)
- {
- unsigned int new_alloc = 2 * wq->alloc + 1;
- HANDLE *new_array =
- (HANDLE *) realloc (wq->array, new_alloc * sizeof (HANDLE));
- if (new_array == NULL)
- /* No more memory. */
- return INVALID_HANDLE_VALUE;
- /* Now is a good opportunity to rotate the array so that its contents
- starts at offset 0. */
- if (wq->offset > 0)
- {
- unsigned int old_count = wq->count;
- unsigned int old_alloc = wq->alloc;
- unsigned int old_offset = wq->offset;
- unsigned int i;
- if (old_offset + old_count > old_alloc)
- {
- unsigned int limit = old_offset + old_count - old_alloc;
- for (i = 0; i < limit; i++)
- new_array[old_alloc + i] = new_array[i];
- }
- for (i = 0; i < old_count; i++)
- new_array[i] = new_array[old_offset + i];
- wq->offset = 0;
- }
- wq->array = new_array;
- wq->alloc = new_alloc;
- }
- /* Whether the created event is a manual-reset one or an auto-reset one,
- does not matter, since we will wait on it only once. */
- event = CreateEvent (NULL, TRUE, FALSE, NULL);
- if (event == INVALID_HANDLE_VALUE)
- /* No way to allocate an event. */
- return INVALID_HANDLE_VALUE;
- index = wq->offset + wq->count;
- if (index >= wq->alloc)
- index -= wq->alloc;
- wq->array[index] = event;
- wq->count++;
- return event;
-}
-
-/* Notifies the first thread from a wait queue and dequeues it. */
-static void
-gl_waitqueue_notify_first (gl_waitqueue_t *wq)
-{
- SetEvent (wq->array[wq->offset + 0]);
- wq->offset++;
- wq->count--;
- if (wq->count == 0 || wq->offset == wq->alloc)
- wq->offset = 0;
-}
-
-/* Notifies all threads from a wait queue and dequeues them all. */
-static void
-gl_waitqueue_notify_all (gl_waitqueue_t *wq)
-{
- unsigned int i;
-
- for (i = 0; i < wq->count; i++)
- {
- unsigned int index = wq->offset + i;
- if (index >= wq->alloc)
- index -= wq->alloc;
- SetEvent (wq->array[index]);
- }
- wq->count = 0;
- wq->offset = 0;
-}
-
-void
-glthread_rwlock_init_func (gl_rwlock_t *lock)
-{
- InitializeCriticalSection (&lock->lock);
- gl_waitqueue_init (&lock->waiting_readers);
- gl_waitqueue_init (&lock->waiting_writers);
- lock->runcount = 0;
- lock->guard.done = 1;
-}
-
-int
-glthread_rwlock_rdlock_func (gl_rwlock_t *lock)
-{
- if (!lock->guard.done)
- {
- if (InterlockedIncrement (&lock->guard.started) == 0)
- /* This thread is the first one to need this lock. Initialize it. */
- glthread_rwlock_init (lock);
- else
- /* Yield the CPU while waiting for another thread to finish
- initializing this lock. */
- while (!lock->guard.done)
- Sleep (0);
- }
- EnterCriticalSection (&lock->lock);
- /* Test whether only readers are currently running, and whether the runcount
- field will not overflow. */
- if (!(lock->runcount + 1 > 0))
- {
- /* This thread has to wait for a while. Enqueue it among the
- waiting_readers. */
- HANDLE event = gl_waitqueue_add (&lock->waiting_readers);
- if (event != INVALID_HANDLE_VALUE)
- {
- DWORD result;
- LeaveCriticalSection (&lock->lock);
- /* Wait until another thread signals this event. */
- result = WaitForSingleObject (event, INFINITE);
- if (result == WAIT_FAILED || result == WAIT_TIMEOUT)
- abort ();
- CloseHandle (event);
- /* The thread which signalled the event already did the bookkeeping:
- removed us from the waiting_readers, incremented lock->runcount. */
- if (!(lock->runcount > 0))
- abort ();
- return 0;
- }
- else
- {
- /* Allocation failure. Weird. */
- do
- {
- LeaveCriticalSection (&lock->lock);
- Sleep (1);
- EnterCriticalSection (&lock->lock);
- }
- while (!(lock->runcount + 1 > 0));
- }
- }
- lock->runcount++;
- LeaveCriticalSection (&lock->lock);
- return 0;
-}
-
-int
-glthread_rwlock_wrlock_func (gl_rwlock_t *lock)
-{
- if (!lock->guard.done)
- {
- if (InterlockedIncrement (&lock->guard.started) == 0)
- /* This thread is the first one to need this lock. Initialize it. */
- glthread_rwlock_init (lock);
- else
- /* Yield the CPU while waiting for another thread to finish
- initializing this lock. */
- while (!lock->guard.done)
- Sleep (0);
- }
- EnterCriticalSection (&lock->lock);
- /* Test whether no readers or writers are currently running. */
- if (!(lock->runcount == 0))
- {
- /* This thread has to wait for a while. Enqueue it among the
- waiting_writers. */
- HANDLE event = gl_waitqueue_add (&lock->waiting_writers);
- if (event != INVALID_HANDLE_VALUE)
- {
- DWORD result;
- LeaveCriticalSection (&lock->lock);
- /* Wait until another thread signals this event. */
- result = WaitForSingleObject (event, INFINITE);
- if (result == WAIT_FAILED || result == WAIT_TIMEOUT)
- abort ();
- CloseHandle (event);
- /* The thread which signalled the event already did the bookkeeping:
- removed us from the waiting_writers, set lock->runcount = -1. */
- if (!(lock->runcount == -1))
- abort ();
- return 0;
- }
- else
- {
- /* Allocation failure. Weird. */
- do
- {
- LeaveCriticalSection (&lock->lock);
- Sleep (1);
- EnterCriticalSection (&lock->lock);
- }
- while (!(lock->runcount == 0));
- }
- }
- lock->runcount--; /* runcount becomes -1 */
- LeaveCriticalSection (&lock->lock);
- return 0;
-}
-
-int
-glthread_rwlock_unlock_func (gl_rwlock_t *lock)
-{
- if (!lock->guard.done)
- return EINVAL;
- EnterCriticalSection (&lock->lock);
- if (lock->runcount < 0)
- {
- /* Drop a writer lock. */
- if (!(lock->runcount == -1))
- abort ();
- lock->runcount = 0;
- }
- else
- {
- /* Drop a reader lock. */
- if (!(lock->runcount > 0))
- {
- LeaveCriticalSection (&lock->lock);
- return EPERM;
- }
- lock->runcount--;
- }
- if (lock->runcount == 0)
- {
- /* POSIX recommends that "write locks shall take precedence over read
- locks", to avoid "writer starvation". */
- if (lock->waiting_writers.count > 0)
- {
- /* Wake up one of the waiting writers. */
- lock->runcount--;
- gl_waitqueue_notify_first (&lock->waiting_writers);
- }
- else
- {
- /* Wake up all waiting readers. */
- lock->runcount += lock->waiting_readers.count;
- gl_waitqueue_notify_all (&lock->waiting_readers);
- }
- }
- LeaveCriticalSection (&lock->lock);
- return 0;
-}
-
-int
-glthread_rwlock_destroy_func (gl_rwlock_t *lock)
-{
- if (!lock->guard.done)
- return EINVAL;
- if (lock->runcount != 0)
- return EBUSY;
- DeleteCriticalSection (&lock->lock);
- if (lock->waiting_readers.array != NULL)
- free (lock->waiting_readers.array);
- if (lock->waiting_writers.array != NULL)
- free (lock->waiting_writers.array);
- lock->guard.done = 0;
- return 0;
-}
-
-/* --------------------- gl_recursive_lock_t datatype --------------------- */
-
-void
-glthread_recursive_lock_init_func (gl_recursive_lock_t *lock)
-{
- lock->owner = 0;
- lock->depth = 0;
- InitializeCriticalSection (&lock->lock);
- lock->guard.done = 1;
-}
-
-int
-glthread_recursive_lock_lock_func (gl_recursive_lock_t *lock)
-{
- if (!lock->guard.done)
- {
- if (InterlockedIncrement (&lock->guard.started) == 0)
- /* This thread is the first one to need this lock. Initialize it. */
- glthread_recursive_lock_init (lock);
- else
- /* Yield the CPU while waiting for another thread to finish
- initializing this lock. */
- while (!lock->guard.done)
- Sleep (0);
- }
- {
- DWORD self = GetCurrentThreadId ();
- if (lock->owner != self)
- {
- EnterCriticalSection (&lock->lock);
- lock->owner = self;
- }
- if (++(lock->depth) == 0) /* wraparound? */
- {
- lock->depth--;
- return EAGAIN;
- }
- }
- return 0;
-}
-
-int
-glthread_recursive_lock_unlock_func (gl_recursive_lock_t *lock)
-{
- if (lock->owner != GetCurrentThreadId ())
- return EPERM;
- if (lock->depth == 0)
- return EINVAL;
- if (--(lock->depth) == 0)
- {
- lock->owner = 0;
- LeaveCriticalSection (&lock->lock);
- }
- return 0;
-}
-
-int
-glthread_recursive_lock_destroy_func (gl_recursive_lock_t *lock)
-{
- if (lock->owner != 0)
- return EBUSY;
- DeleteCriticalSection (&lock->lock);
- lock->guard.done = 0;
- return 0;
-}
-
-/* -------------------------- gl_once_t datatype -------------------------- */
-
-void
-glthread_once_func (gl_once_t *once_control, void (*initfunction) (void))
-{
- if (once_control->inited <= 0)
- {
- if (InterlockedIncrement (&once_control->started) == 0)
- {
- /* This thread is the first one to come to this once_control. */
- InitializeCriticalSection (&once_control->lock);
- EnterCriticalSection (&once_control->lock);
- once_control->inited = 0;
- initfunction ();
- once_control->inited = 1;
- LeaveCriticalSection (&once_control->lock);
- }
- else
- {
- /* Undo last operation. */
- InterlockedDecrement (&once_control->started);
- /* Some other thread has already started the initialization.
- Yield the CPU while waiting for the other thread to finish
- initializing and taking the lock. */
- while (once_control->inited < 0)
- Sleep (0);
- if (once_control->inited <= 0)
- {
- /* Take the lock. This blocks until the other thread has
- finished calling the initfunction. */
- EnterCriticalSection (&once_control->lock);
- LeaveCriticalSection (&once_control->lock);
- if (!(once_control->inited > 0))
- abort ();
- }
- }
- }
-}
-
-#endif
-
-/* ========================================================================= */
diff --git a/lib/glthread/lock.h b/lib/glthread/lock.h
index 894b1fbaa..66c78a6cd 100644
--- a/lib/glthread/lock.h
+++ b/lib/glthread/lock.h
@@ -1,927 +1,38 @@
-/* Locking in multithreaded situations.
- Copyright (C) 2005-2014 Free Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with this program; if not, see <http://www.gnu.org/licenses/>. */
-
-/* Written by Bruno Haible <bruno@clisp.org>, 2005.
- Based on GCC's gthr-posix.h, gthr-posix95.h, gthr-solaris.h,
- gthr-win32.h. */
-
-/* This file contains locking primitives for use with a given thread library.
- It does not contain primitives for creating threads or for other
- synchronization primitives.
-
- Normal (non-recursive) locks:
- Type: gl_lock_t
- Declaration: gl_lock_define(extern, name)
- Initializer: gl_lock_define_initialized(, name)
- Initialization: gl_lock_init (name);
- Taking the lock: gl_lock_lock (name);
- Releasing the lock: gl_lock_unlock (name);
- De-initialization: gl_lock_destroy (name);
- Equivalent functions with control of error handling:
- Initialization: err = glthread_lock_init (&name);
- Taking the lock: err = glthread_lock_lock (&name);
- Releasing the lock: err = glthread_lock_unlock (&name);
- De-initialization: err = glthread_lock_destroy (&name);
-
- Read-Write (non-recursive) locks:
- Type: gl_rwlock_t
- Declaration: gl_rwlock_define(extern, name)
- Initializer: gl_rwlock_define_initialized(, name)
- Initialization: gl_rwlock_init (name);
- Taking the lock: gl_rwlock_rdlock (name);
- gl_rwlock_wrlock (name);
- Releasing the lock: gl_rwlock_unlock (name);
- De-initialization: gl_rwlock_destroy (name);
- Equivalent functions with control of error handling:
- Initialization: err = glthread_rwlock_init (&name);
- Taking the lock: err = glthread_rwlock_rdlock (&name);
- err = glthread_rwlock_wrlock (&name);
- Releasing the lock: err = glthread_rwlock_unlock (&name);
- De-initialization: err = glthread_rwlock_destroy (&name);
-
- Recursive locks:
- Type: gl_recursive_lock_t
- Declaration: gl_recursive_lock_define(extern, name)
- Initializer: gl_recursive_lock_define_initialized(, name)
- Initialization: gl_recursive_lock_init (name);
- Taking the lock: gl_recursive_lock_lock (name);
- Releasing the lock: gl_recursive_lock_unlock (name);
- De-initialization: gl_recursive_lock_destroy (name);
- Equivalent functions with control of error handling:
- Initialization: err = glthread_recursive_lock_init (&name);
- Taking the lock: err = glthread_recursive_lock_lock (&name);
- Releasing the lock: err = glthread_recursive_lock_unlock (&name);
- De-initialization: err = glthread_recursive_lock_destroy (&name);
-
- Once-only execution:
- Type: gl_once_t
- Initializer: gl_once_define(extern, name)
- Execution: gl_once (name, initfunction);
- Equivalent functions with control of error handling:
- Execution: err = glthread_once (&name, initfunction);
-*/
-
-
-#ifndef _LOCK_H
-#define _LOCK_H
-
-#include <errno.h>
+#ifndef SCM_GLTHREADS_H
+#define SCM_GLTHREADS_H
+
+/* Copyright (C) 2014 Free Software Foundation, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 3 of
+ * the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+
+/* This file implements Gnulib's glthreads/lock.h interface in terms of
+ Guile's locking API. This allows Gnulib modules such as 'regex' to
+ be built with thread-safety support via Guile's locks (see
+ <http://bugs.gnu.org/14404>.) */
+
+#include <libguile/threads.h>
#include <stdlib.h>
-/* ========================================================================= */
-
-#if USE_POSIX_THREADS
-
-/* Use the POSIX threads library. */
-
-# include <pthread.h>
-
-# ifdef __cplusplus
-extern "C" {
-# endif
-
-# if PTHREAD_IN_USE_DETECTION_HARD
-
-/* The pthread_in_use() detection needs to be done at runtime. */
-# define pthread_in_use() \
- glthread_in_use ()
-extern int glthread_in_use (void);
-
-# endif
-
-# if USE_POSIX_THREADS_WEAK
-
-/* Use weak references to the POSIX threads library. */
-
-/* Weak references avoid dragging in external libraries if the other parts
- of the program don't use them. Here we use them, because we don't want
- every program that uses libintl to depend on libpthread. This assumes
- that libpthread would not be loaded after libintl; i.e. if libintl is
- loaded first, by an executable that does not depend on libpthread, and
- then a module is dynamically loaded that depends on libpthread, libintl
- will not be multithread-safe. */
-
-/* The way to test at runtime whether libpthread is present is to test
- whether a function pointer's value, such as &pthread_mutex_init, is
- non-NULL. However, some versions of GCC have a bug through which, in
- PIC mode, &foo != NULL always evaluates to true if there is a direct
- call to foo(...) in the same function. To avoid this, we test the
- address of a function in libpthread that we don't use. */
-
-# pragma weak pthread_mutex_init
-# pragma weak pthread_mutex_lock
-# pragma weak pthread_mutex_unlock
-# pragma weak pthread_mutex_destroy
-# pragma weak pthread_rwlock_init
-# pragma weak pthread_rwlock_rdlock
-# pragma weak pthread_rwlock_wrlock
-# pragma weak pthread_rwlock_unlock
-# pragma weak pthread_rwlock_destroy
-# pragma weak pthread_once
-# pragma weak pthread_cond_init
-# pragma weak pthread_cond_wait
-# pragma weak pthread_cond_signal
-# pragma weak pthread_cond_broadcast
-# pragma weak pthread_cond_destroy
-# pragma weak pthread_mutexattr_init
-# pragma weak pthread_mutexattr_settype
-# pragma weak pthread_mutexattr_destroy
-# ifndef pthread_self
-# pragma weak pthread_self
-# endif
-
-# if !PTHREAD_IN_USE_DETECTION_HARD
-# pragma weak pthread_cancel
-# define pthread_in_use() (pthread_cancel != NULL)
-# endif
-
-# else
-
-# if !PTHREAD_IN_USE_DETECTION_HARD
-# define pthread_in_use() 1
-# endif
-
-# endif
-
-/* -------------------------- gl_lock_t datatype -------------------------- */
-
-typedef pthread_mutex_t gl_lock_t;
-# define gl_lock_define(STORAGECLASS, NAME) \
- STORAGECLASS pthread_mutex_t NAME;
-# define gl_lock_define_initialized(STORAGECLASS, NAME) \
- STORAGECLASS pthread_mutex_t NAME = gl_lock_initializer;
-# define gl_lock_initializer \
- PTHREAD_MUTEX_INITIALIZER
-# define glthread_lock_init(LOCK) \
- (pthread_in_use () ? pthread_mutex_init (LOCK, NULL) : 0)
-# define glthread_lock_lock(LOCK) \
- (pthread_in_use () ? pthread_mutex_lock (LOCK) : 0)
-# define glthread_lock_unlock(LOCK) \
- (pthread_in_use () ? pthread_mutex_unlock (LOCK) : 0)
-# define glthread_lock_destroy(LOCK) \
- (pthread_in_use () ? pthread_mutex_destroy (LOCK) : 0)
-
-/* ------------------------- gl_rwlock_t datatype ------------------------- */
-
-# if HAVE_PTHREAD_RWLOCK
-
-# ifdef PTHREAD_RWLOCK_INITIALIZER
-
-typedef pthread_rwlock_t gl_rwlock_t;
-# define gl_rwlock_define(STORAGECLASS, NAME) \
- STORAGECLASS pthread_rwlock_t NAME;
-# define gl_rwlock_define_initialized(STORAGECLASS, NAME) \
- STORAGECLASS pthread_rwlock_t NAME = gl_rwlock_initializer;
-# define gl_rwlock_initializer \
- PTHREAD_RWLOCK_INITIALIZER
-# define glthread_rwlock_init(LOCK) \
- (pthread_in_use () ? pthread_rwlock_init (LOCK, NULL) : 0)
-# define glthread_rwlock_rdlock(LOCK) \
- (pthread_in_use () ? pthread_rwlock_rdlock (LOCK) : 0)
-# define glthread_rwlock_wrlock(LOCK) \
- (pthread_in_use () ? pthread_rwlock_wrlock (LOCK) : 0)
-# define glthread_rwlock_unlock(LOCK) \
- (pthread_in_use () ? pthread_rwlock_unlock (LOCK) : 0)
-# define glthread_rwlock_destroy(LOCK) \
- (pthread_in_use () ? pthread_rwlock_destroy (LOCK) : 0)
-
-# else
-
-typedef struct
- {
- int initialized;
- pthread_mutex_t guard; /* protects the initialization */
- pthread_rwlock_t rwlock; /* read-write lock */
- }
- gl_rwlock_t;
-# define gl_rwlock_define(STORAGECLASS, NAME) \
- STORAGECLASS gl_rwlock_t NAME;
-# define gl_rwlock_define_initialized(STORAGECLASS, NAME) \
- STORAGECLASS gl_rwlock_t NAME = gl_rwlock_initializer;
-# define gl_rwlock_initializer \
- { 0, PTHREAD_MUTEX_INITIALIZER }
-# define glthread_rwlock_init(LOCK) \
- (pthread_in_use () ? glthread_rwlock_init_multithreaded (LOCK) : 0)
-# define glthread_rwlock_rdlock(LOCK) \
- (pthread_in_use () ? glthread_rwlock_rdlock_multithreaded (LOCK) : 0)
-# define glthread_rwlock_wrlock(LOCK) \
- (pthread_in_use () ? glthread_rwlock_wrlock_multithreaded (LOCK) : 0)
-# define glthread_rwlock_unlock(LOCK) \
- (pthread_in_use () ? glthread_rwlock_unlock_multithreaded (LOCK) : 0)
-# define glthread_rwlock_destroy(LOCK) \
- (pthread_in_use () ? glthread_rwlock_destroy_multithreaded (LOCK) : 0)
-extern int glthread_rwlock_init_multithreaded (gl_rwlock_t *lock);
-extern int glthread_rwlock_rdlock_multithreaded (gl_rwlock_t *lock);
-extern int glthread_rwlock_wrlock_multithreaded (gl_rwlock_t *lock);
-extern int glthread_rwlock_unlock_multithreaded (gl_rwlock_t *lock);
-extern int glthread_rwlock_destroy_multithreaded (gl_rwlock_t *lock);
-
-# endif
+#define gl_lock_define(klass, name) \
+ klass scm_i_pthread_mutex_t name;
-# else
-
-typedef struct
- {
- pthread_mutex_t lock; /* protects the remaining fields */
- pthread_cond_t waiting_readers; /* waiting readers */
- pthread_cond_t waiting_writers; /* waiting writers */
- unsigned int waiting_writers_count; /* number of waiting writers */
- int runcount; /* number of readers running, or -1 when a writer runs */
- }
- gl_rwlock_t;
-# define gl_rwlock_define(STORAGECLASS, NAME) \
- STORAGECLASS gl_rwlock_t NAME;
-# define gl_rwlock_define_initialized(STORAGECLASS, NAME) \
- STORAGECLASS gl_rwlock_t NAME = gl_rwlock_initializer;
-# define gl_rwlock_initializer \
- { PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER, PTHREAD_COND_INITIALIZER, 0, 0 }
-# define glthread_rwlock_init(LOCK) \
- (pthread_in_use () ? glthread_rwlock_init_multithreaded (LOCK) : 0)
-# define glthread_rwlock_rdlock(LOCK) \
- (pthread_in_use () ? glthread_rwlock_rdlock_multithreaded (LOCK) : 0)
-# define glthread_rwlock_wrlock(LOCK) \
- (pthread_in_use () ? glthread_rwlock_wrlock_multithreaded (LOCK) : 0)
-# define glthread_rwlock_unlock(LOCK) \
- (pthread_in_use () ? glthread_rwlock_unlock_multithreaded (LOCK) : 0)
-# define glthread_rwlock_destroy(LOCK) \
- (pthread_in_use () ? glthread_rwlock_destroy_multithreaded (LOCK) : 0)
-extern int glthread_rwlock_init_multithreaded (gl_rwlock_t *lock);
-extern int glthread_rwlock_rdlock_multithreaded (gl_rwlock_t *lock);
-extern int glthread_rwlock_wrlock_multithreaded (gl_rwlock_t *lock);
-extern int glthread_rwlock_unlock_multithreaded (gl_rwlock_t *lock);
-extern int glthread_rwlock_destroy_multithreaded (gl_rwlock_t *lock);
-
-# endif
-
-/* --------------------- gl_recursive_lock_t datatype --------------------- */
-
-# if HAVE_PTHREAD_MUTEX_RECURSIVE
-
-# if defined PTHREAD_RECURSIVE_MUTEX_INITIALIZER || defined PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
-
-typedef pthread_mutex_t gl_recursive_lock_t;
-# define gl_recursive_lock_define(STORAGECLASS, NAME) \
- STORAGECLASS pthread_mutex_t NAME;
-# define gl_recursive_lock_define_initialized(STORAGECLASS, NAME) \
- STORAGECLASS pthread_mutex_t NAME = gl_recursive_lock_initializer;
-# ifdef PTHREAD_RECURSIVE_MUTEX_INITIALIZER
-# define gl_recursive_lock_initializer \
- PTHREAD_RECURSIVE_MUTEX_INITIALIZER
-# else
-# define gl_recursive_lock_initializer \
- PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
-# endif
-# define glthread_recursive_lock_init(LOCK) \
- (pthread_in_use () ? glthread_recursive_lock_init_multithreaded (LOCK) : 0)
-# define glthread_recursive_lock_lock(LOCK) \
- (pthread_in_use () ? pthread_mutex_lock (LOCK) : 0)
-# define glthread_recursive_lock_unlock(LOCK) \
- (pthread_in_use () ? pthread_mutex_unlock (LOCK) : 0)
-# define glthread_recursive_lock_destroy(LOCK) \
- (pthread_in_use () ? pthread_mutex_destroy (LOCK) : 0)
-extern int glthread_recursive_lock_init_multithreaded (gl_recursive_lock_t *lock);
-
-# else
-
-typedef struct
- {
- pthread_mutex_t recmutex; /* recursive mutex */
- pthread_mutex_t guard; /* protects the initialization */
- int initialized;
- }
- gl_recursive_lock_t;
-# define gl_recursive_lock_define(STORAGECLASS, NAME) \
- STORAGECLASS gl_recursive_lock_t NAME;
-# define gl_recursive_lock_define_initialized(STORAGECLASS, NAME) \
- STORAGECLASS gl_recursive_lock_t NAME = gl_recursive_lock_initializer;
-# define gl_recursive_lock_initializer \
- { PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, 0 }
-# define glthread_recursive_lock_init(LOCK) \
- (pthread_in_use () ? glthread_recursive_lock_init_multithreaded (LOCK) : 0)
-# define glthread_recursive_lock_lock(LOCK) \
- (pthread_in_use () ? glthread_recursive_lock_lock_multithreaded (LOCK) : 0)
-# define glthread_recursive_lock_unlock(LOCK) \
- (pthread_in_use () ? glthread_recursive_lock_unlock_multithreaded (LOCK) : 0)
-# define glthread_recursive_lock_destroy(LOCK) \
- (pthread_in_use () ? glthread_recursive_lock_destroy_multithreaded (LOCK) : 0)
-extern int glthread_recursive_lock_init_multithreaded (gl_recursive_lock_t *lock);
-extern int glthread_recursive_lock_lock_multithreaded (gl_recursive_lock_t *lock);
-extern int glthread_recursive_lock_unlock_multithreaded (gl_recursive_lock_t *lock);
-extern int glthread_recursive_lock_destroy_multithreaded (gl_recursive_lock_t *lock);
-
-# endif
-
-# else
-
-/* Old versions of POSIX threads on Solaris did not have recursive locks.
- We have to implement them ourselves. */
-
-typedef struct
- {
- pthread_mutex_t mutex;
- pthread_t owner;
- unsigned long depth;
- }
- gl_recursive_lock_t;
-# define gl_recursive_lock_define(STORAGECLASS, NAME) \
- STORAGECLASS gl_recursive_lock_t NAME;
-# define gl_recursive_lock_define_initialized(STORAGECLASS, NAME) \
- STORAGECLASS gl_recursive_lock_t NAME = gl_recursive_lock_initializer;
-# define gl_recursive_lock_initializer \
- { PTHREAD_MUTEX_INITIALIZER, (pthread_t) 0, 0 }
-# define glthread_recursive_lock_init(LOCK) \
- (pthread_in_use () ? glthread_recursive_lock_init_multithreaded (LOCK) : 0)
-# define glthread_recursive_lock_lock(LOCK) \
- (pthread_in_use () ? glthread_recursive_lock_lock_multithreaded (LOCK) : 0)
-# define glthread_recursive_lock_unlock(LOCK) \
- (pthread_in_use () ? glthread_recursive_lock_unlock_multithreaded (LOCK) : 0)
-# define glthread_recursive_lock_destroy(LOCK) \
- (pthread_in_use () ? glthread_recursive_lock_destroy_multithreaded (LOCK) : 0)
-extern int glthread_recursive_lock_init_multithreaded (gl_recursive_lock_t *lock);
-extern int glthread_recursive_lock_lock_multithreaded (gl_recursive_lock_t *lock);
-extern int glthread_recursive_lock_unlock_multithreaded (gl_recursive_lock_t *lock);
-extern int glthread_recursive_lock_destroy_multithreaded (gl_recursive_lock_t *lock);
-
-# endif
-
-/* -------------------------- gl_once_t datatype -------------------------- */
-
-typedef pthread_once_t gl_once_t;
-# define gl_once_define(STORAGECLASS, NAME) \
- STORAGECLASS pthread_once_t NAME = PTHREAD_ONCE_INIT;
-# define glthread_once(ONCE_CONTROL, INITFUNCTION) \
- (pthread_in_use () \
- ? pthread_once (ONCE_CONTROL, INITFUNCTION) \
- : (glthread_once_singlethreaded (ONCE_CONTROL) ? (INITFUNCTION (), 0) : 0))
-extern int glthread_once_singlethreaded (pthread_once_t *once_control);
-
-# ifdef __cplusplus
-}
-# endif
+#define glthread_lock_init(lock) scm_i_pthread_mutex_init ((lock), NULL)
+#define glthread_lock_destroy scm_i_pthread_mutex_destroy
+#define glthread_lock_lock scm_i_pthread_mutex_lock
+#define glthread_lock_unlock scm_i_pthread_mutex_unlock
#endif
-
-/* ========================================================================= */
-
-#if USE_PTH_THREADS
-
-/* Use the GNU Pth threads library. */
-
-# include <pth.h>
-
-# ifdef __cplusplus
-extern "C" {
-# endif
-
-# if USE_PTH_THREADS_WEAK
-
-/* Use weak references to the GNU Pth threads library. */
-
-# pragma weak pth_mutex_init
-# pragma weak pth_mutex_acquire
-# pragma weak pth_mutex_release
-# pragma weak pth_rwlock_init
-# pragma weak pth_rwlock_acquire
-# pragma weak pth_rwlock_release
-# pragma weak pth_once
-
-# pragma weak pth_cancel
-# define pth_in_use() (pth_cancel != NULL)
-
-# else
-
-# define pth_in_use() 1
-
-# endif
-
-/* -------------------------- gl_lock_t datatype -------------------------- */
-
-typedef pth_mutex_t gl_lock_t;
-# define gl_lock_define(STORAGECLASS, NAME) \
- STORAGECLASS pth_mutex_t NAME;
-# define gl_lock_define_initialized(STORAGECLASS, NAME) \
- STORAGECLASS pth_mutex_t NAME = gl_lock_initializer;
-# define gl_lock_initializer \
- PTH_MUTEX_INIT
-# define glthread_lock_init(LOCK) \
- (pth_in_use () && !pth_mutex_init (LOCK) ? errno : 0)
-# define glthread_lock_lock(LOCK) \
- (pth_in_use () && !pth_mutex_acquire (LOCK, 0, NULL) ? errno : 0)
-# define glthread_lock_unlock(LOCK) \
- (pth_in_use () && !pth_mutex_release (LOCK) ? errno : 0)
-# define glthread_lock_destroy(LOCK) \
- ((void)(LOCK), 0)
-
-/* ------------------------- gl_rwlock_t datatype ------------------------- */
-
-typedef pth_rwlock_t gl_rwlock_t;
-# define gl_rwlock_define(STORAGECLASS, NAME) \
- STORAGECLASS pth_rwlock_t NAME;
-# define gl_rwlock_define_initialized(STORAGECLASS, NAME) \
- STORAGECLASS pth_rwlock_t NAME = gl_rwlock_initializer;
-# define gl_rwlock_initializer \
- PTH_RWLOCK_INIT
-# define glthread_rwlock_init(LOCK) \
- (pth_in_use () && !pth_rwlock_init (LOCK) ? errno : 0)
-# define glthread_rwlock_rdlock(LOCK) \
- (pth_in_use () && !pth_rwlock_acquire (LOCK, PTH_RWLOCK_RD, 0, NULL) ? errno : 0)
-# define glthread_rwlock_wrlock(LOCK) \
- (pth_in_use () && !pth_rwlock_acquire (LOCK, PTH_RWLOCK_RW, 0, NULL) ? errno : 0)
-# define glthread_rwlock_unlock(LOCK) \
- (pth_in_use () && !pth_rwlock_release (LOCK) ? errno : 0)
-# define glthread_rwlock_destroy(LOCK) \
- ((void)(LOCK), 0)
-
-/* --------------------- gl_recursive_lock_t datatype --------------------- */
-
-/* In Pth, mutexes are recursive by default. */
-typedef pth_mutex_t gl_recursive_lock_t;
-# define gl_recursive_lock_define(STORAGECLASS, NAME) \
- STORAGECLASS pth_mutex_t NAME;
-# define gl_recursive_lock_define_initialized(STORAGECLASS, NAME) \
- STORAGECLASS pth_mutex_t NAME = gl_recursive_lock_initializer;
-# define gl_recursive_lock_initializer \
- PTH_MUTEX_INIT
-# define glthread_recursive_lock_init(LOCK) \
- (pth_in_use () && !pth_mutex_init (LOCK) ? errno : 0)
-# define glthread_recursive_lock_lock(LOCK) \
- (pth_in_use () && !pth_mutex_acquire (LOCK, 0, NULL) ? errno : 0)
-# define glthread_recursive_lock_unlock(LOCK) \
- (pth_in_use () && !pth_mutex_release (LOCK) ? errno : 0)
-# define glthread_recursive_lock_destroy(LOCK) \
- ((void)(LOCK), 0)
-
-/* -------------------------- gl_once_t datatype -------------------------- */
-
-typedef pth_once_t gl_once_t;
-# define gl_once_define(STORAGECLASS, NAME) \
- STORAGECLASS pth_once_t NAME = PTH_ONCE_INIT;
-# define glthread_once(ONCE_CONTROL, INITFUNCTION) \
- (pth_in_use () \
- ? glthread_once_multithreaded (ONCE_CONTROL, INITFUNCTION) \
- : (glthread_once_singlethreaded (ONCE_CONTROL) ? (INITFUNCTION (), 0) : 0))
-extern int glthread_once_multithreaded (pth_once_t *once_control, void (*initfunction) (void));
-extern int glthread_once_singlethreaded (pth_once_t *once_control);
-
-# ifdef __cplusplus
-}
-# endif
-
-#endif
-
-/* ========================================================================= */
-
-#if USE_SOLARIS_THREADS
-
-/* Use the old Solaris threads library. */
-
-# include <thread.h>
-# include <synch.h>
-
-# ifdef __cplusplus
-extern "C" {
-# endif
-
-# if USE_SOLARIS_THREADS_WEAK
-
-/* Use weak references to the old Solaris threads library. */
-
-# pragma weak mutex_init
-# pragma weak mutex_lock
-# pragma weak mutex_unlock
-# pragma weak mutex_destroy
-# pragma weak rwlock_init
-# pragma weak rw_rdlock
-# pragma weak rw_wrlock
-# pragma weak rw_unlock
-# pragma weak rwlock_destroy
-# pragma weak thr_self
-
-# pragma weak thr_suspend
-# define thread_in_use() (thr_suspend != NULL)
-
-# else
-
-# define thread_in_use() 1
-
-# endif
-
-/* -------------------------- gl_lock_t datatype -------------------------- */
-
-typedef mutex_t gl_lock_t;
-# define gl_lock_define(STORAGECLASS, NAME) \
- STORAGECLASS mutex_t NAME;
-# define gl_lock_define_initialized(STORAGECLASS, NAME) \
- STORAGECLASS mutex_t NAME = gl_lock_initializer;
-# define gl_lock_initializer \
- DEFAULTMUTEX
-# define glthread_lock_init(LOCK) \
- (thread_in_use () ? mutex_init (LOCK, USYNC_THREAD, NULL) : 0)
-# define glthread_lock_lock(LOCK) \
- (thread_in_use () ? mutex_lock (LOCK) : 0)
-# define glthread_lock_unlock(LOCK) \
- (thread_in_use () ? mutex_unlock (LOCK) : 0)
-# define glthread_lock_destroy(LOCK) \
- (thread_in_use () ? mutex_destroy (LOCK) : 0)
-
-/* ------------------------- gl_rwlock_t datatype ------------------------- */
-
-typedef rwlock_t gl_rwlock_t;
-# define gl_rwlock_define(STORAGECLASS, NAME) \
- STORAGECLASS rwlock_t NAME;
-# define gl_rwlock_define_initialized(STORAGECLASS, NAME) \
- STORAGECLASS rwlock_t NAME = gl_rwlock_initializer;
-# define gl_rwlock_initializer \
- DEFAULTRWLOCK
-# define glthread_rwlock_init(LOCK) \
- (thread_in_use () ? rwlock_init (LOCK, USYNC_THREAD, NULL) : 0)
-# define glthread_rwlock_rdlock(LOCK) \
- (thread_in_use () ? rw_rdlock (LOCK) : 0)
-# define glthread_rwlock_wrlock(LOCK) \
- (thread_in_use () ? rw_wrlock (LOCK) : 0)
-# define glthread_rwlock_unlock(LOCK) \
- (thread_in_use () ? rw_unlock (LOCK) : 0)
-# define glthread_rwlock_destroy(LOCK) \
- (thread_in_use () ? rwlock_destroy (LOCK) : 0)
-
-/* --------------------- gl_recursive_lock_t datatype --------------------- */
-
-/* Old Solaris threads did not have recursive locks.
- We have to implement them ourselves. */
-
-typedef struct
- {
- mutex_t mutex;
- thread_t owner;
- unsigned long depth;
- }
- gl_recursive_lock_t;
-# define gl_recursive_lock_define(STORAGECLASS, NAME) \
- STORAGECLASS gl_recursive_lock_t NAME;
-# define gl_recursive_lock_define_initialized(STORAGECLASS, NAME) \
- STORAGECLASS gl_recursive_lock_t NAME = gl_recursive_lock_initializer;
-# define gl_recursive_lock_initializer \
- { DEFAULTMUTEX, (thread_t) 0, 0 }
-# define glthread_recursive_lock_init(LOCK) \
- (thread_in_use () ? glthread_recursive_lock_init_multithreaded (LOCK) : 0)
-# define glthread_recursive_lock_lock(LOCK) \
- (thread_in_use () ? glthread_recursive_lock_lock_multithreaded (LOCK) : 0)
-# define glthread_recursive_lock_unlock(LOCK) \
- (thread_in_use () ? glthread_recursive_lock_unlock_multithreaded (LOCK) : 0)
-# define glthread_recursive_lock_destroy(LOCK) \
- (thread_in_use () ? glthread_recursive_lock_destroy_multithreaded (LOCK) : 0)
-extern int glthread_recursive_lock_init_multithreaded (gl_recursive_lock_t *lock);
-extern int glthread_recursive_lock_lock_multithreaded (gl_recursive_lock_t *lock);
-extern int glthread_recursive_lock_unlock_multithreaded (gl_recursive_lock_t *lock);
-extern int glthread_recursive_lock_destroy_multithreaded (gl_recursive_lock_t *lock);
-
-/* -------------------------- gl_once_t datatype -------------------------- */
-
-typedef struct
- {
- volatile int inited;
- mutex_t mutex;
- }
- gl_once_t;
-# define gl_once_define(STORAGECLASS, NAME) \
- STORAGECLASS gl_once_t NAME = { 0, DEFAULTMUTEX };
-# define glthread_once(ONCE_CONTROL, INITFUNCTION) \
- (thread_in_use () \
- ? glthread_once_multithreaded (ONCE_CONTROL, INITFUNCTION) \
- : (glthread_once_singlethreaded (ONCE_CONTROL) ? (INITFUNCTION (), 0) : 0))
-extern int glthread_once_multithreaded (gl_once_t *once_control, void (*initfunction) (void));
-extern int glthread_once_singlethreaded (gl_once_t *once_control);
-
-# ifdef __cplusplus
-}
-# endif
-
-#endif
-
-/* ========================================================================= */
-
-#if USE_WINDOWS_THREADS
-
-# define WIN32_LEAN_AND_MEAN /* avoid including junk */
-# include <windows.h>
-
-# ifdef __cplusplus
-extern "C" {
-# endif
-
-/* We can use CRITICAL_SECTION directly, rather than the native Windows Event,
- Mutex, Semaphore types, because
- - we need only to synchronize inside a single process (address space),
- not inter-process locking,
- - we don't need to support trylock operations. (TryEnterCriticalSection
- does not work on Windows 95/98/ME. Packages that need trylock usually
- define their own mutex type.) */
-
-/* There is no way to statically initialize a CRITICAL_SECTION. It needs
- to be done lazily, once only. For this we need spinlocks. */
-
-typedef struct { volatile int done; volatile long started; } gl_spinlock_t;
-
-/* -------------------------- gl_lock_t datatype -------------------------- */
-
-typedef struct
- {
- gl_spinlock_t guard; /* protects the initialization */
- CRITICAL_SECTION lock;
- }
- gl_lock_t;
-# define gl_lock_define(STORAGECLASS, NAME) \
- STORAGECLASS gl_lock_t NAME;
-# define gl_lock_define_initialized(STORAGECLASS, NAME) \
- STORAGECLASS gl_lock_t NAME = gl_lock_initializer;
-# define gl_lock_initializer \
- { { 0, -1 } }
-# define glthread_lock_init(LOCK) \
- (glthread_lock_init_func (LOCK), 0)
-# define glthread_lock_lock(LOCK) \
- glthread_lock_lock_func (LOCK)
-# define glthread_lock_unlock(LOCK) \
- glthread_lock_unlock_func (LOCK)
-# define glthread_lock_destroy(LOCK) \
- glthread_lock_destroy_func (LOCK)
-extern void glthread_lock_init_func (gl_lock_t *lock);
-extern int glthread_lock_lock_func (gl_lock_t *lock);
-extern int glthread_lock_unlock_func (gl_lock_t *lock);
-extern int glthread_lock_destroy_func (gl_lock_t *lock);
-
-/* ------------------------- gl_rwlock_t datatype ------------------------- */
-
-/* It is impossible to implement read-write locks using plain locks, without
- introducing an extra thread dedicated to managing read-write locks.
- Therefore here we need to use the low-level Event type. */
-
-typedef struct
- {
- HANDLE *array; /* array of waiting threads, each represented by an event */
- unsigned int count; /* number of waiting threads */
- unsigned int alloc; /* length of allocated array */
- unsigned int offset; /* index of first waiting thread in array */
- }
- gl_carray_waitqueue_t;
-typedef struct
- {
- gl_spinlock_t guard; /* protects the initialization */
- CRITICAL_SECTION lock; /* protects the remaining fields */
- gl_carray_waitqueue_t waiting_readers; /* waiting readers */
- gl_carray_waitqueue_t waiting_writers; /* waiting writers */
- int runcount; /* number of readers running, or -1 when a writer runs */
- }
- gl_rwlock_t;
-# define gl_rwlock_define(STORAGECLASS, NAME) \
- STORAGECLASS gl_rwlock_t NAME;
-# define gl_rwlock_define_initialized(STORAGECLASS, NAME) \
- STORAGECLASS gl_rwlock_t NAME = gl_rwlock_initializer;
-# define gl_rwlock_initializer \
- { { 0, -1 } }
-# define glthread_rwlock_init(LOCK) \
- (glthread_rwlock_init_func (LOCK), 0)
-# define glthread_rwlock_rdlock(LOCK) \
- glthread_rwlock_rdlock_func (LOCK)
-# define glthread_rwlock_wrlock(LOCK) \
- glthread_rwlock_wrlock_func (LOCK)
-# define glthread_rwlock_unlock(LOCK) \
- glthread_rwlock_unlock_func (LOCK)
-# define glthread_rwlock_destroy(LOCK) \
- glthread_rwlock_destroy_func (LOCK)
-extern void glthread_rwlock_init_func (gl_rwlock_t *lock);
-extern int glthread_rwlock_rdlock_func (gl_rwlock_t *lock);
-extern int glthread_rwlock_wrlock_func (gl_rwlock_t *lock);
-extern int glthread_rwlock_unlock_func (gl_rwlock_t *lock);
-extern int glthread_rwlock_destroy_func (gl_rwlock_t *lock);
-
-/* --------------------- gl_recursive_lock_t datatype --------------------- */
-
-/* The native Windows documentation says that CRITICAL_SECTION already
- implements a recursive lock. But we need not rely on it: It's easy to
- implement a recursive lock without this assumption. */
-
-typedef struct
- {
- gl_spinlock_t guard; /* protects the initialization */
- DWORD owner;
- unsigned long depth;
- CRITICAL_SECTION lock;
- }
- gl_recursive_lock_t;
-# define gl_recursive_lock_define(STORAGECLASS, NAME) \
- STORAGECLASS gl_recursive_lock_t NAME;
-# define gl_recursive_lock_define_initialized(STORAGECLASS, NAME) \
- STORAGECLASS gl_recursive_lock_t NAME = gl_recursive_lock_initializer;
-# define gl_recursive_lock_initializer \
- { { 0, -1 }, 0, 0 }
-# define glthread_recursive_lock_init(LOCK) \
- (glthread_recursive_lock_init_func (LOCK), 0)
-# define glthread_recursive_lock_lock(LOCK) \
- glthread_recursive_lock_lock_func (LOCK)
-# define glthread_recursive_lock_unlock(LOCK) \
- glthread_recursive_lock_unlock_func (LOCK)
-# define glthread_recursive_lock_destroy(LOCK) \
- glthread_recursive_lock_destroy_func (LOCK)
-extern void glthread_recursive_lock_init_func (gl_recursive_lock_t *lock);
-extern int glthread_recursive_lock_lock_func (gl_recursive_lock_t *lock);
-extern int glthread_recursive_lock_unlock_func (gl_recursive_lock_t *lock);
-extern int glthread_recursive_lock_destroy_func (gl_recursive_lock_t *lock);
-
-/* -------------------------- gl_once_t datatype -------------------------- */
-
-typedef struct
- {
- volatile int inited;
- volatile long started;
- CRITICAL_SECTION lock;
- }
- gl_once_t;
-# define gl_once_define(STORAGECLASS, NAME) \
- STORAGECLASS gl_once_t NAME = { -1, -1 };
-# define glthread_once(ONCE_CONTROL, INITFUNCTION) \
- (glthread_once_func (ONCE_CONTROL, INITFUNCTION), 0)
-extern void glthread_once_func (gl_once_t *once_control, void (*initfunction) (void));
-
-# ifdef __cplusplus
-}
-# endif
-
-#endif
-
-/* ========================================================================= */
-
-#if !(USE_POSIX_THREADS || USE_PTH_THREADS || USE_SOLARIS_THREADS || USE_WINDOWS_THREADS)
-
-/* Provide dummy implementation if threads are not supported. */
-
-/* -------------------------- gl_lock_t datatype -------------------------- */
-
-typedef int gl_lock_t;
-# define gl_lock_define(STORAGECLASS, NAME)
-# define gl_lock_define_initialized(STORAGECLASS, NAME)
-# define glthread_lock_init(NAME) 0
-# define glthread_lock_lock(NAME) 0
-# define glthread_lock_unlock(NAME) 0
-# define glthread_lock_destroy(NAME) 0
-
-/* ------------------------- gl_rwlock_t datatype ------------------------- */
-
-typedef int gl_rwlock_t;
-# define gl_rwlock_define(STORAGECLASS, NAME)
-# define gl_rwlock_define_initialized(STORAGECLASS, NAME)
-# define glthread_rwlock_init(NAME) 0
-# define glthread_rwlock_rdlock(NAME) 0
-# define glthread_rwlock_wrlock(NAME) 0
-# define glthread_rwlock_unlock(NAME) 0
-# define glthread_rwlock_destroy(NAME) 0
-
-/* --------------------- gl_recursive_lock_t datatype --------------------- */
-
-typedef int gl_recursive_lock_t;
-# define gl_recursive_lock_define(STORAGECLASS, NAME)
-# define gl_recursive_lock_define_initialized(STORAGECLASS, NAME)
-# define glthread_recursive_lock_init(NAME) 0
-# define glthread_recursive_lock_lock(NAME) 0
-# define glthread_recursive_lock_unlock(NAME) 0
-# define glthread_recursive_lock_destroy(NAME) 0
-
-/* -------------------------- gl_once_t datatype -------------------------- */
-
-typedef int gl_once_t;
-# define gl_once_define(STORAGECLASS, NAME) \
- STORAGECLASS gl_once_t NAME = 0;
-# define glthread_once(ONCE_CONTROL, INITFUNCTION) \
- (*(ONCE_CONTROL) == 0 ? (*(ONCE_CONTROL) = ~ 0, INITFUNCTION (), 0) : 0)
-
-#endif
-
-/* ========================================================================= */
-
-/* Macros with built-in error handling. */
-
-/* -------------------------- gl_lock_t datatype -------------------------- */
-
-#define gl_lock_init(NAME) \
- do \
- { \
- if (glthread_lock_init (&NAME)) \
- abort (); \
- } \
- while (0)
-#define gl_lock_lock(NAME) \
- do \
- { \
- if (glthread_lock_lock (&NAME)) \
- abort (); \
- } \
- while (0)
-#define gl_lock_unlock(NAME) \
- do \
- { \
- if (glthread_lock_unlock (&NAME)) \
- abort (); \
- } \
- while (0)
-#define gl_lock_destroy(NAME) \
- do \
- { \
- if (glthread_lock_destroy (&NAME)) \
- abort (); \
- } \
- while (0)
-
-/* ------------------------- gl_rwlock_t datatype ------------------------- */
-
-#define gl_rwlock_init(NAME) \
- do \
- { \
- if (glthread_rwlock_init (&NAME)) \
- abort (); \
- } \
- while (0)
-#define gl_rwlock_rdlock(NAME) \
- do \
- { \
- if (glthread_rwlock_rdlock (&NAME)) \
- abort (); \
- } \
- while (0)
-#define gl_rwlock_wrlock(NAME) \
- do \
- { \
- if (glthread_rwlock_wrlock (&NAME)) \
- abort (); \
- } \
- while (0)
-#define gl_rwlock_unlock(NAME) \
- do \
- { \
- if (glthread_rwlock_unlock (&NAME)) \
- abort (); \
- } \
- while (0)
-#define gl_rwlock_destroy(NAME) \
- do \
- { \
- if (glthread_rwlock_destroy (&NAME)) \
- abort (); \
- } \
- while (0)
-
-/* --------------------- gl_recursive_lock_t datatype --------------------- */
-
-#define gl_recursive_lock_init(NAME) \
- do \
- { \
- if (glthread_recursive_lock_init (&NAME)) \
- abort (); \
- } \
- while (0)
-#define gl_recursive_lock_lock(NAME) \
- do \
- { \
- if (glthread_recursive_lock_lock (&NAME)) \
- abort (); \
- } \
- while (0)
-#define gl_recursive_lock_unlock(NAME) \
- do \
- { \
- if (glthread_recursive_lock_unlock (&NAME)) \
- abort (); \
- } \
- while (0)
-#define gl_recursive_lock_destroy(NAME) \
- do \
- { \
- if (glthread_recursive_lock_destroy (&NAME)) \
- abort (); \
- } \
- while (0)
-
-/* -------------------------- gl_once_t datatype -------------------------- */
-
-#define gl_once(NAME, INITFUNCTION) \
- do \
- { \
- if (glthread_once (&NAME, INITFUNCTION)) \
- abort (); \
- } \
- while (0)
-
-/* ========================================================================= */
-
-#endif /* _LOCK_H */
diff --git a/lib/glthread/threadlib.c b/lib/glthread/threadlib.c
deleted file mode 100644
index 37a5762d8..000000000
--- a/lib/glthread/threadlib.c
+++ /dev/null
@@ -1,73 +0,0 @@
-/* Multithreading primitives.
- Copyright (C) 2005-2014 Free Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with this program; if not, see <http://www.gnu.org/licenses/>. */
-
-/* Written by Bruno Haible <bruno@clisp.org>, 2005. */
-
-#include <config.h>
-
-/* ========================================================================= */
-
-#if USE_POSIX_THREADS
-
-/* Use the POSIX threads library. */
-
-# include <pthread.h>
-# include <stdlib.h>
-
-# if PTHREAD_IN_USE_DETECTION_HARD
-
-/* The function to be executed by a dummy thread. */
-static void *
-dummy_thread_func (void *arg)
-{
- return arg;
-}
-
-int
-glthread_in_use (void)
-{
- static int tested;
- static int result; /* 1: linked with -lpthread, 0: only with libc */
-
- if (!tested)
- {
- pthread_t thread;
-
- if (pthread_create (&thread, NULL, dummy_thread_func, NULL) != 0)
- /* Thread creation failed. */
- result = 0;
- else
- {
- /* Thread creation works. */
- void *retval;
- if (pthread_join (thread, &retval) != 0)
- abort ();
- result = 1;
- }
- tested = 1;
- }
- return result;
-}
-
-# endif
-
-#endif
-
-/* ========================================================================= */
-
-/* This declaration is solely to ensure that after preprocessing
- this file is never empty. */
-typedef int dummy;
diff --git a/lib/unistd.in.h b/lib/unistd.in.h
index 988090814..842025024 100644
--- a/lib/unistd.in.h
+++ b/lib/unistd.in.h
@@ -21,9 +21,23 @@
#endif
@PRAGMA_COLUMNS@
+#ifdef _GL_INCLUDING_UNISTD_H
+/* Special invocation convention:
+ - On Mac OS X 10.3.9 we have a sequence of nested includes
+ <unistd.h> -> <signal.h> -> <pthread.h> -> <unistd.h>
+ In this situation, the functions are not yet declared, therefore we cannot
+ provide the C++ aliases. */
+
+#@INCLUDE_NEXT@ @NEXT_UNISTD_H@
+
+#else
+/* Normal invocation convention. */
+
/* The include_next requires a split double-inclusion guard. */
#if @HAVE_UNISTD_H@
+# define _GL_INCLUDING_UNISTD_H
# @INCLUDE_NEXT@ @NEXT_UNISTD_H@
+# undef _GL_INCLUDING_UNISTD_H
#endif
/* Get all possible declarations of gethostname(). */
@@ -1539,4 +1553,5 @@ _GL_CXXALIASWARN (write);
_GL_INLINE_HEADER_END
#endif /* _@GUARD_PREFIX@_UNISTD_H */
+#endif /* _GL_INCLUDING_UNISTD_H */
#endif /* _@GUARD_PREFIX@_UNISTD_H */
diff --git a/m4/gnulib-cache.m4 b/m4/gnulib-cache.m4
index fc7391cda..9e095da7c 100644
--- a/m4/gnulib-cache.m4
+++ b/m4/gnulib-cache.m4
@@ -27,7 +27,7 @@
# Specification in the form of a command-line invocation:
-# gnulib-tool --import --dir=. --local-dir=gnulib-local --lib=libgnu --source-base=lib --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=build-aux --lgpl=3 --no-conditional-dependencies --libtool --macro-prefix=gl --no-vc-files accept alignof alloca-opt announce-gen autobuild bind byteswap c-strcase canonicalize-lgpl ceil clock-time close connect copysign dirfd duplocale environ extensions flock floor fpieee frexp fstat fsync full-read full-write func gendocs getaddrinfo getlogin getpeername getsockname getsockopt git-version-gen gitlog-to-changelog gnu-web-doc-update gnupload havelib iconv_open-utf inet_ntop inet_pton isfinite isinf isnan ldexp lib-symbol-versions lib-symbol-visibility libunistring link listen localcharset locale log1p lstat maintainer-makefile malloc-gnu malloca mkdir mkstemp nl_langinfo nproc open pipe-posix pipe2 poll putenv readlink recv recvfrom regex rename rmdir select send sendto setenv setsockopt shutdown socket stat-time stdlib strftime striconveh string sys_stat time times trunc unistd verify vsnprintf warnings wchar
+# gnulib-tool --import --dir=. --local-dir=gnulib-local --lib=libgnu --source-base=lib --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=build-aux --avoid=lock --lgpl=3 --no-conditional-dependencies --libtool --macro-prefix=gl --no-vc-files accept alignof alloca-opt announce-gen autobuild bind byteswap c-strcase canonicalize-lgpl ceil clock-time close connect copysign dirfd duplocale environ extensions flock floor fpieee frexp fstat fsync full-read full-write func gendocs getaddrinfo getlogin getpeername getsockname getsockopt git-version-gen gitlog-to-changelog gnu-web-doc-update gnupload havelib iconv_open-utf inet_ntop inet_pton isfinite isinf isnan ldexp lib-symbol-versions lib-symbol-visibility libunistring link listen localcharset locale log1p lstat maintainer-makefile malloc-gnu malloca mkdir mkstemp nl_langinfo nproc open pipe-posix pipe2 poll putenv readlink recv recvfrom regex rename rmdir select send sendto setenv setsockopt shutdown socket stat-time stdlib strftime striconveh string sys_stat time times trunc unistd verify vsnprintf warnings wchar
# Specification in the form of a few gnulib-tool.m4 macro invocations:
gl_LOCAL_DIR([gnulib-local])
@@ -126,7 +126,7 @@ gl_MODULES([
warnings
wchar
])
-gl_AVOID([])
+gl_AVOID([lock])
gl_SOURCE_BASE([lib])
gl_M4_BASE([m4])
gl_PO_BASE([])
diff --git a/m4/gnulib-common.m4 b/m4/gnulib-common.m4
index 3b61b239b..20ce40e74 100644
--- a/m4/gnulib-common.m4
+++ b/m4/gnulib-common.m4
@@ -379,3 +379,59 @@ AC_DEFUN([gl_CACHE_VAL_SILENT],
# AS_VAR_COPY was added in autoconf 2.63b
m4_define_default([AS_VAR_COPY],
[AS_LITERAL_IF([$1[]$2], [$1=$$2], [eval $1=\$$2])])
+
+# AC_PROG_SED was added in autoconf 2.59b
+m4_ifndef([AC_PROG_SED],
+[AC_DEFUN([AC_PROG_SED],
+[AC_CACHE_CHECK([for a sed that does not truncate output], ac_cv_path_SED,
+ [dnl ac_script should not contain more than 99 commands (for HP-UX sed),
+ dnl but more than about 7000 bytes, to catch a limit in Solaris 8 /usr/ucb/sed.
+ ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/
+ for ac_i in 1 2 3 4 5 6 7; do
+ ac_script="$ac_script$as_nl$ac_script"
+ done
+ echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed
+ AS_UNSET([ac_script])
+ if test -z "$SED"; then
+ ac_path_SED_found=false
+ _AS_PATH_WALK([], [
+ for ac_prog in sed gsed; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ ac_path_SED="$as_dir/$ac_prog$ac_exec_ext"
+ AS_EXECUTABLE_P(["$ac_path_SED"]) || continue
+ case `"$ac_path_SED" --version 2>&1` in
+ *GNU*) ac_cv_path_SED=$ac_path_SED ac_path_SED_found=:;;
+ *)
+ ac_count=0
+ _AS_ECHO_N([0123456789]) >conftest.in
+ while :
+ do
+ cat conftest.in conftest.in >conftest.tmp
+ mv conftest.tmp conftest.in
+ cp conftest.in conftest.nl
+ echo >> conftest.nl
+ "$ac_path_SED" -f conftest.sed <conftest.nl >conftest.out 2>/dev/null || break
+ diff conftest.out conftest.nl >/dev/null 2>&1 || break
+ ac_count=`expr $ac_count + 1`
+ if test $ac_count -gt ${ac_path_SED_max-0}; then
+ # Best so far, but keep looking for better
+ ac_cv_path_SED=$ac_path_SED
+ ac_path_SED_max=$ac_count
+ fi
+ test $ac_count -gt 10 && break
+ done
+ rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+ esac
+ $ac_path_SED_found && break 3
+ done
+ done])
+ if test -z "$ac_cv_path_SED"; then
+ AC_ERROR([no acceptable sed could be found in \$PATH])
+ fi
+ else
+ ac_cv_path_SED=$SED
+ fi
+ SED="$ac_cv_path_SED"
+ AC_SUBST([SED])dnl
+ rm -f conftest.sed
+])])])
diff --git a/m4/gnulib-comp.m4 b/m4/gnulib-comp.m4
index b333d6aed..429fee422 100644
--- a/m4/gnulib-comp.m4
+++ b/m4/gnulib-comp.m4
@@ -133,7 +133,6 @@ AC_DEFUN([gl_EARLY],
# Code from module localcharset:
# Code from module locale:
# Code from module localeconv:
- # Code from module lock:
# Code from module log:
# Code from module log1p:
# Code from module lstat:
@@ -219,8 +218,6 @@ AC_DEFUN([gl_EARLY],
# Code from module sys_types:
# Code from module sys_uio:
# Code from module tempname:
- # Code from module threadlib:
- gl_THREADLIB_EARLY
# Code from module time:
# Code from module time_r:
# Code from module times:
@@ -529,8 +526,6 @@ AC_SUBST([LTALLOCA])
gl_PREREQ_LOCALECONV
fi
gl_LOCALE_MODULE_INDICATOR([localeconv])
- gl_LOCK
- gl_MODULE_INDICATOR([lock])
AC_REQUIRE([gl_FUNC_LOG])
if test $REPLACE_LOG = 1; then
AC_LIBOBJ([log])
@@ -549,6 +544,7 @@ AC_SUBST([LTALLOCA])
gl_SYS_STAT_MODULE_INDICATOR([lstat])
AC_CONFIG_COMMANDS_PRE([m4_ifdef([AH_HEADER],
[AC_SUBST([CONFIG_INCLUDE], m4_defn([AH_HEADER]))])])
+ AC_REQUIRE([AC_PROG_SED])
gl_FUNC_MALLOC_GNU
if test $REPLACE_MALLOC = 1; then
AC_LIBOBJ([malloc])
@@ -800,7 +796,6 @@ AC_SUBST([LTALLOCA])
gl_HEADER_SYS_UIO
AC_PROG_MKDIR_P
gl_FUNC_GEN_TEMPNAME
- gl_THREADLIB
gl_HEADER_TIME_H
gl_TIME_R
if test $HAVE_LOCALTIME_R = 0 || test $REPLACE_LOCALTIME_R = 1; then
@@ -1054,9 +1049,6 @@ AC_DEFUN([gl_FILE_LIST], [
lib/getsockopt.c
lib/gettext.h
lib/gettimeofday.c
- lib/glthread/lock.c
- lib/glthread/lock.h
- lib/glthread/threadlib.c
lib/iconv.c
lib/iconv.in.h
lib/iconv_close.c
@@ -1294,7 +1286,6 @@ AC_DEFUN([gl_FILE_LIST], [
m4/locale-zh.m4
m4/locale_h.m4
m4/localeconv.m4
- m4/lock.m4
m4/log.m4
m4/log1p.m4
m4/longlong.m4
@@ -1372,7 +1363,6 @@ AC_DEFUN([gl_FILE_LIST], [
m4/sys_types_h.m4
m4/sys_uio_h.m4
m4/tempname.m4
- m4/threadlib.m4
m4/time_h.m4
m4/time_r.m4
m4/times.m4
diff --git a/m4/lock.m4 b/m4/lock.m4
deleted file mode 100644
index 73a3c54ce..000000000
--- a/m4/lock.m4
+++ /dev/null
@@ -1,42 +0,0 @@
-# lock.m4 serial 13 (gettext-0.18.2)
-dnl Copyright (C) 2005-2014 Free Software Foundation, Inc.
-dnl This file is free software; the Free Software Foundation
-dnl gives unlimited permission to copy and/or distribute it,
-dnl with or without modifications, as long as this notice is preserved.
-
-dnl From Bruno Haible.
-
-AC_DEFUN([gl_LOCK],
-[
- AC_REQUIRE([gl_THREADLIB])
- if test "$gl_threads_api" = posix; then
- # OSF/1 4.0 and Mac OS X 10.1 lack the pthread_rwlock_t type and the
- # pthread_rwlock_* functions.
- AC_CHECK_TYPE([pthread_rwlock_t],
- [AC_DEFINE([HAVE_PTHREAD_RWLOCK], [1],
- [Define if the POSIX multithreading library has read/write locks.])],
- [],
- [#include <pthread.h>])
- # glibc defines PTHREAD_MUTEX_RECURSIVE as enum, not as a macro.
- AC_COMPILE_IFELSE([
- AC_LANG_PROGRAM(
- [[#include <pthread.h>]],
- [[
-#if __FreeBSD__ == 4
-error "No, in FreeBSD 4.0 recursive mutexes actually don't work."
-#elif (defined __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ \
- && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 1070)
-error "No, in Mac OS X < 10.7 recursive mutexes actually don't work."
-#else
-int x = (int)PTHREAD_MUTEX_RECURSIVE;
-return !x;
-#endif
- ]])],
- [AC_DEFINE([HAVE_PTHREAD_MUTEX_RECURSIVE], [1],
- [Define if the <pthread.h> defines PTHREAD_MUTEX_RECURSIVE.])])
- fi
- gl_PREREQ_LOCK
-])
-
-# Prerequisites of lib/glthread/lock.c.
-AC_DEFUN([gl_PREREQ_LOCK], [:])
diff --git a/m4/threadlib.m4 b/m4/threadlib.m4
deleted file mode 100644
index a88170261..000000000
--- a/m4/threadlib.m4
+++ /dev/null
@@ -1,371 +0,0 @@
-# threadlib.m4 serial 10 (gettext-0.18.2)
-dnl Copyright (C) 2005-2014 Free Software Foundation, Inc.
-dnl This file is free software; the Free Software Foundation
-dnl gives unlimited permission to copy and/or distribute it,
-dnl with or without modifications, as long as this notice is preserved.
-
-dnl From Bruno Haible.
-
-dnl gl_THREADLIB
-dnl ------------
-dnl Tests for a multithreading library to be used.
-dnl If the configure.ac contains a definition of the gl_THREADLIB_DEFAULT_NO
-dnl (it must be placed before the invocation of gl_THREADLIB_EARLY!), then the
-dnl default is 'no', otherwise it is system dependent. In both cases, the user
-dnl can change the choice through the options --enable-threads=choice or
-dnl --disable-threads.
-dnl Defines at most one of the macros USE_POSIX_THREADS, USE_SOLARIS_THREADS,
-dnl USE_PTH_THREADS, USE_WINDOWS_THREADS
-dnl Sets the variables LIBTHREAD and LTLIBTHREAD to the linker options for use
-dnl in a Makefile (LIBTHREAD for use without libtool, LTLIBTHREAD for use with
-dnl libtool).
-dnl Sets the variables LIBMULTITHREAD and LTLIBMULTITHREAD similarly, for
-dnl programs that really need multithread functionality. The difference
-dnl between LIBTHREAD and LIBMULTITHREAD is that on platforms supporting weak
-dnl symbols, typically LIBTHREAD="" whereas LIBMULTITHREAD="-lpthread".
-dnl Adds to CPPFLAGS the flag -D_REENTRANT or -D_THREAD_SAFE if needed for
-dnl multithread-safe programs.
-
-AC_DEFUN([gl_THREADLIB_EARLY],
-[
- AC_REQUIRE([gl_THREADLIB_EARLY_BODY])
-])
-
-dnl The guts of gl_THREADLIB_EARLY. Needs to be expanded only once.
-
-AC_DEFUN([gl_THREADLIB_EARLY_BODY],
-[
- dnl Ordering constraints: This macro modifies CPPFLAGS in a way that
- dnl influences the result of the autoconf tests that test for *_unlocked
- dnl declarations, on AIX 5 at least. Therefore it must come early.
- AC_BEFORE([$0], [gl_FUNC_GLIBC_UNLOCKED_IO])dnl
- AC_BEFORE([$0], [gl_ARGP])dnl
-
- AC_REQUIRE([AC_CANONICAL_HOST])
- dnl _GNU_SOURCE is needed for pthread_rwlock_t on glibc systems.
- dnl AC_USE_SYSTEM_EXTENSIONS was introduced in autoconf 2.60 and obsoletes
- dnl AC_GNU_SOURCE.
- m4_ifdef([AC_USE_SYSTEM_EXTENSIONS],
- [AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS])],
- [AC_REQUIRE([AC_GNU_SOURCE])])
- dnl Check for multithreading.
- m4_ifdef([gl_THREADLIB_DEFAULT_NO],
- [m4_divert_text([DEFAULTS], [gl_use_threads_default=no])],
- [m4_divert_text([DEFAULTS], [gl_use_threads_default=])])
- AC_ARG_ENABLE([threads],
-AC_HELP_STRING([--enable-threads={posix|solaris|pth|windows}], [specify multithreading API])m4_ifdef([gl_THREADLIB_DEFAULT_NO], [], [
-AC_HELP_STRING([--disable-threads], [build without multithread safety])]),
- [gl_use_threads=$enableval],
- [if test -n "$gl_use_threads_default"; then
- gl_use_threads="$gl_use_threads_default"
- else
-changequote(,)dnl
- case "$host_os" in
- dnl Disable multithreading by default on OSF/1, because it interferes
- dnl with fork()/exec(): When msgexec is linked with -lpthread, its
- dnl child process gets an endless segmentation fault inside execvp().
- dnl Disable multithreading by default on Cygwin 1.5.x, because it has
- dnl bugs that lead to endless loops or crashes. See
- dnl <http://cygwin.com/ml/cygwin/2009-08/msg00283.html>.
- osf*) gl_use_threads=no ;;
- cygwin*)
- case `uname -r` in
- 1.[0-5].*) gl_use_threads=no ;;
- *) gl_use_threads=yes ;;
- esac
- ;;
- *) gl_use_threads=yes ;;
- esac
-changequote([,])dnl
- fi
- ])
- if test "$gl_use_threads" = yes || test "$gl_use_threads" = posix; then
- # For using <pthread.h>:
- case "$host_os" in
- osf*)
- # On OSF/1, the compiler needs the flag -D_REENTRANT so that it
- # groks <pthread.h>. cc also understands the flag -pthread, but
- # we don't use it because 1. gcc-2.95 doesn't understand -pthread,
- # 2. putting a flag into CPPFLAGS that has an effect on the linker
- # causes the AC_LINK_IFELSE test below to succeed unexpectedly,
- # leading to wrong values of LIBTHREAD and LTLIBTHREAD.
- CPPFLAGS="$CPPFLAGS -D_REENTRANT"
- ;;
- esac
- # Some systems optimize for single-threaded programs by default, and
- # need special flags to disable these optimizations. For example, the
- # definition of 'errno' in <errno.h>.
- case "$host_os" in
- aix* | freebsd*) CPPFLAGS="$CPPFLAGS -D_THREAD_SAFE" ;;
- solaris*) CPPFLAGS="$CPPFLAGS -D_REENTRANT" ;;
- esac
- fi
-])
-
-dnl The guts of gl_THREADLIB. Needs to be expanded only once.
-
-AC_DEFUN([gl_THREADLIB_BODY],
-[
- AC_REQUIRE([gl_THREADLIB_EARLY_BODY])
- gl_threads_api=none
- LIBTHREAD=
- LTLIBTHREAD=
- LIBMULTITHREAD=
- LTLIBMULTITHREAD=
- if test "$gl_use_threads" != no; then
- dnl Check whether the compiler and linker support weak declarations.
- AC_CACHE_CHECK([whether imported symbols can be declared weak],
- [gl_cv_have_weak],
- [gl_cv_have_weak=no
- dnl First, test whether the compiler accepts it syntactically.
- AC_LINK_IFELSE(
- [AC_LANG_PROGRAM(
- [[extern void xyzzy ();
-#pragma weak xyzzy]],
- [[xyzzy();]])],
- [gl_cv_have_weak=maybe])
- if test $gl_cv_have_weak = maybe; then
- dnl Second, test whether it actually works. On Cygwin 1.7.2, with
- dnl gcc 4.3, symbols declared weak always evaluate to the address 0.
- AC_RUN_IFELSE(
- [AC_LANG_SOURCE([[
-#include <stdio.h>
-#pragma weak fputs
-int main ()
-{
- return (fputs == NULL);
-}]])],
- [gl_cv_have_weak=yes],
- [gl_cv_have_weak=no],
- [dnl When cross-compiling, assume that only ELF platforms support
- dnl weak symbols.
- AC_EGREP_CPP([Extensible Linking Format],
- [#ifdef __ELF__
- Extensible Linking Format
- #endif
- ],
- [gl_cv_have_weak="guessing yes"],
- [gl_cv_have_weak="guessing no"])
- ])
- fi
- ])
- if test "$gl_use_threads" = yes || test "$gl_use_threads" = posix; then
- # On OSF/1, the compiler needs the flag -pthread or -D_REENTRANT so that
- # it groks <pthread.h>. It's added above, in gl_THREADLIB_EARLY_BODY.
- AC_CHECK_HEADER([pthread.h],
- [gl_have_pthread_h=yes], [gl_have_pthread_h=no])
- if test "$gl_have_pthread_h" = yes; then
- # Other possible tests:
- # -lpthreads (FSU threads, PCthreads)
- # -lgthreads
- gl_have_pthread=
- # Test whether both pthread_mutex_lock and pthread_mutexattr_init exist
- # in libc. IRIX 6.5 has the first one in both libc and libpthread, but
- # the second one only in libpthread, and lock.c needs it.
- AC_LINK_IFELSE(
- [AC_LANG_PROGRAM(
- [[#include <pthread.h>]],
- [[pthread_mutex_lock((pthread_mutex_t*)0);
- pthread_mutexattr_init((pthread_mutexattr_t*)0);]])],
- [gl_have_pthread=yes])
- # Test for libpthread by looking for pthread_kill. (Not pthread_self,
- # since it is defined as a macro on OSF/1.)
- if test -n "$gl_have_pthread"; then
- # The program links fine without libpthread. But it may actually
- # need to link with libpthread in order to create multiple threads.
- AC_CHECK_LIB([pthread], [pthread_kill],
- [LIBMULTITHREAD=-lpthread LTLIBMULTITHREAD=-lpthread
- # On Solaris and HP-UX, most pthread functions exist also in libc.
- # Therefore pthread_in_use() needs to actually try to create a
- # thread: pthread_create from libc will fail, whereas
- # pthread_create will actually create a thread.
- case "$host_os" in
- solaris* | hpux*)
- AC_DEFINE([PTHREAD_IN_USE_DETECTION_HARD], [1],
- [Define if the pthread_in_use() detection is hard.])
- esac
- ])
- else
- # Some library is needed. Try libpthread and libc_r.
- AC_CHECK_LIB([pthread], [pthread_kill],
- [gl_have_pthread=yes
- LIBTHREAD=-lpthread LTLIBTHREAD=-lpthread
- LIBMULTITHREAD=-lpthread LTLIBMULTITHREAD=-lpthread])
- if test -z "$gl_have_pthread"; then
- # For FreeBSD 4.
- AC_CHECK_LIB([c_r], [pthread_kill],
- [gl_have_pthread=yes
- LIBTHREAD=-lc_r LTLIBTHREAD=-lc_r
- LIBMULTITHREAD=-lc_r LTLIBMULTITHREAD=-lc_r])
- fi
- fi
- if test -n "$gl_have_pthread"; then
- gl_threads_api=posix
- AC_DEFINE([USE_POSIX_THREADS], [1],
- [Define if the POSIX multithreading library can be used.])
- if test -n "$LIBMULTITHREAD" || test -n "$LTLIBMULTITHREAD"; then
- if case "$gl_cv_have_weak" in *yes) true;; *) false;; esac; then
- AC_DEFINE([USE_POSIX_THREADS_WEAK], [1],
- [Define if references to the POSIX multithreading library should be made weak.])
- LIBTHREAD=
- LTLIBTHREAD=
- fi
- fi
- fi
- fi
- fi
- if test -z "$gl_have_pthread"; then
- if test "$gl_use_threads" = yes || test "$gl_use_threads" = solaris; then
- gl_have_solaristhread=
- gl_save_LIBS="$LIBS"
- LIBS="$LIBS -lthread"
- AC_LINK_IFELSE(
- [AC_LANG_PROGRAM(
- [[
-#include <thread.h>
-#include <synch.h>
- ]],
- [[thr_self();]])],
- [gl_have_solaristhread=yes])
- LIBS="$gl_save_LIBS"
- if test -n "$gl_have_solaristhread"; then
- gl_threads_api=solaris
- LIBTHREAD=-lthread
- LTLIBTHREAD=-lthread
- LIBMULTITHREAD="$LIBTHREAD"
- LTLIBMULTITHREAD="$LTLIBTHREAD"
- AC_DEFINE([USE_SOLARIS_THREADS], [1],
- [Define if the old Solaris multithreading library can be used.])
- if case "$gl_cv_have_weak" in *yes) true;; *) false;; esac; then
- AC_DEFINE([USE_SOLARIS_THREADS_WEAK], [1],
- [Define if references to the old Solaris multithreading library should be made weak.])
- LIBTHREAD=
- LTLIBTHREAD=
- fi
- fi
- fi
- fi
- if test "$gl_use_threads" = pth; then
- gl_save_CPPFLAGS="$CPPFLAGS"
- AC_LIB_LINKFLAGS([pth])
- gl_have_pth=
- gl_save_LIBS="$LIBS"
- LIBS="$LIBS $LIBPTH"
- AC_LINK_IFELSE(
- [AC_LANG_PROGRAM([[#include <pth.h>]], [[pth_self();]])],
- [gl_have_pth=yes])
- LIBS="$gl_save_LIBS"
- if test -n "$gl_have_pth"; then
- gl_threads_api=pth
- LIBTHREAD="$LIBPTH"
- LTLIBTHREAD="$LTLIBPTH"
- LIBMULTITHREAD="$LIBTHREAD"
- LTLIBMULTITHREAD="$LTLIBTHREAD"
- AC_DEFINE([USE_PTH_THREADS], [1],
- [Define if the GNU Pth multithreading library can be used.])
- if test -n "$LIBMULTITHREAD" || test -n "$LTLIBMULTITHREAD"; then
- if case "$gl_cv_have_weak" in *yes) true;; *) false;; esac; then
- AC_DEFINE([USE_PTH_THREADS_WEAK], [1],
- [Define if references to the GNU Pth multithreading library should be made weak.])
- LIBTHREAD=
- LTLIBTHREAD=
- fi
- fi
- else
- CPPFLAGS="$gl_save_CPPFLAGS"
- fi
- fi
- if test -z "$gl_have_pthread"; then
- case "$gl_use_threads" in
- yes | windows | win32) # The 'win32' is for backward compatibility.
- if { case "$host_os" in
- mingw*) true;;
- *) false;;
- esac
- }; then
- gl_threads_api=windows
- AC_DEFINE([USE_WINDOWS_THREADS], [1],
- [Define if the native Windows multithreading API can be used.])
- fi
- ;;
- esac
- fi
- fi
- AC_MSG_CHECKING([for multithread API to use])
- AC_MSG_RESULT([$gl_threads_api])
- AC_SUBST([LIBTHREAD])
- AC_SUBST([LTLIBTHREAD])
- AC_SUBST([LIBMULTITHREAD])
- AC_SUBST([LTLIBMULTITHREAD])
-])
-
-AC_DEFUN([gl_THREADLIB],
-[
- AC_REQUIRE([gl_THREADLIB_EARLY])
- AC_REQUIRE([gl_THREADLIB_BODY])
-])
-
-
-dnl gl_DISABLE_THREADS
-dnl ------------------
-dnl Sets the gl_THREADLIB default so that threads are not used by default.
-dnl The user can still override it at installation time, by using the
-dnl configure option '--enable-threads'.
-
-AC_DEFUN([gl_DISABLE_THREADS], [
- m4_divert_text([INIT_PREPARE], [gl_use_threads_default=no])
-])
-
-
-dnl Survey of platforms:
-dnl
-dnl Platform Available Compiler Supports test-lock
-dnl flavours option weak result
-dnl --------------- --------- --------- -------- ---------
-dnl Linux 2.4/glibc posix -lpthread Y OK
-dnl
-dnl GNU Hurd/glibc posix
-dnl
-dnl FreeBSD 5.3 posix -lc_r Y
-dnl posix -lkse ? Y
-dnl posix -lpthread ? Y
-dnl posix -lthr Y
-dnl
-dnl FreeBSD 5.2 posix -lc_r Y
-dnl posix -lkse Y
-dnl posix -lthr Y
-dnl
-dnl FreeBSD 4.0,4.10 posix -lc_r Y OK
-dnl
-dnl NetBSD 1.6 --
-dnl
-dnl OpenBSD 3.4 posix -lpthread Y OK
-dnl
-dnl Mac OS X 10.[123] posix -lpthread Y OK
-dnl
-dnl Solaris 7,8,9 posix -lpthread Y Sol 7,8: 0.0; Sol 9: OK
-dnl solaris -lthread Y Sol 7,8: 0.0; Sol 9: OK
-dnl
-dnl HP-UX 11 posix -lpthread N (cc) OK
-dnl Y (gcc)
-dnl
-dnl IRIX 6.5 posix -lpthread Y 0.5
-dnl
-dnl AIX 4.3,5.1 posix -lpthread N AIX 4: 0.5; AIX 5: OK
-dnl
-dnl OSF/1 4.0,5.1 posix -pthread (cc) N OK
-dnl -lpthread (gcc) Y
-dnl
-dnl Cygwin posix -lpthread Y OK
-dnl
-dnl Any of the above pth -lpth 0.0
-dnl
-dnl Mingw windows N OK
-dnl
-dnl BeOS 5 --
-dnl
-dnl The test-lock result shows what happens if in test-lock.c EXPLICIT_YIELD is
-dnl turned off:
-dnl OK if all three tests terminate OK,
-dnl 0.5 if the first test terminates OK but the second one loops endlessly,
-dnl 0.0 if the first test already loops endlessly.
diff --git a/maint.mk b/maint.mk
index d5bb427a2..30f2e8e69 100644
--- a/maint.mk
+++ b/maint.mk
@@ -76,7 +76,7 @@ _dot_escaped_srcdir = $(subst .,\.,$(srcdir))
ifeq ($(srcdir),.)
_prepend_srcdir_prefix =
else
- _prepend_srcdir_prefix = | sed 's|^|$(srcdir)/|'
+ _prepend_srcdir_prefix = | $(SED) 's|^|$(srcdir)/|'
endif
# In order to be able to consistently filter "."-relative names,
@@ -85,7 +85,7 @@ endif
_sc_excl = \
$(or $(exclude_file_name_regexp--$@),^$$)
VC_LIST_EXCEPT = \
- $(VC_LIST) | sed 's|^$(_dot_escaped_srcdir)/||' \
+ $(VC_LIST) | $(SED) 's|^$(_dot_escaped_srcdir)/||' \
| if test -f $(srcdir)/.x-$@; then grep -vEf $(srcdir)/.x-$@; \
else grep -Ev -e "$${VC_LIST_EXCEPT_DEFAULT-ChangeLog}"; fi \
| grep -Ev -e '($(VC_LIST_ALWAYS_EXCLUDE_REGEX)|$(_sc_excl))' \
@@ -158,8 +158,8 @@ export LC_ALL = C
_cfg_mk := $(wildcard $(srcdir)/cfg.mk)
# Collect the names of rules starting with 'sc_'.
-syntax-check-rules := $(sort $(shell sed -n 's/^\(sc_[a-zA-Z0-9_-]*\):.*/\1/p' \
- $(srcdir)/$(ME) $(_cfg_mk)))
+syntax-check-rules := $(sort $(shell $(SED) -n \
+ 's/^\(sc_[a-zA-Z0-9_-]*\):.*/\1/p' $(srcdir)/$(ME) $(_cfg_mk)))
.PHONY: $(syntax-check-rules)
ifeq ($(shell $(VC_LIST) >/dev/null 2>&1; echo $$?),0)
@@ -448,7 +448,7 @@ sc_require_config_h_first:
@if $(VC_LIST_EXCEPT) | grep -l '\.c$$' > /dev/null; then \
fail=0; \
for i in $$($(VC_LIST_EXCEPT) | grep '\.c$$'); do \
- grep '^# *include\>' $$i | sed 1q \
+ grep '^# *include\>' $$i | $(SED) 1q \
| grep -E '^# *include $(config_h_header)' > /dev/null \
|| { echo $$i; fail=1; }; \
done; \
@@ -468,7 +468,7 @@ sc_prohibit_HAVE_MBRTOWC:
# re: a regular expression that matches IFF something provided by $h is used.
define _sc_header_without_use
dummy=; : so we do not need a semicolon before each use; \
- h_esc=`echo '[<"]'"$$h"'[">]'|sed 's/\./\\\\./g'`; \
+ h_esc=`echo '[<"]'"$$h"'[">]'|$(SED) 's/\./\\\\./g'`; \
if $(VC_LIST_EXCEPT) | grep -l '\.c$$' > /dev/null; then \
files=$$(grep -l '^# *include '"$$h_esc" \
$$($(VC_LIST_EXCEPT) | grep '\.c$$')) && \
@@ -789,7 +789,7 @@ sc_useless_cpp_parens:
# #if HAVE_HEADER_H that you remove, be sure that your project explicitly
# requires the gnulib module that guarantees the usability of that header.
gl_assured_headers_ = \
- cd $(gnulib_dir)/lib && echo *.in.h|sed 's/\.in\.h//g'
+ cd $(gnulib_dir)/lib && echo *.in.h|$(SED) 's/\.in\.h//g'
# Convert the list of names to upper case, and replace each space with "|".
az_ = abcdefghijklmnopqrstuvwxyz
@@ -840,7 +840,7 @@ define def_sym_regex
&& perl -lne '$(gl_extract_significant_defines_)' $$f; \
done; \
) | sort -u \
- | sed 's/^/^ *# *(define|undef) */;s/$$/\\>/'
+ | $(SED) 's/^/^ *# *(define|undef) */;s/$$/\\>/'
endef
# Don't define macros that we already get from gnulib header files.
@@ -1054,12 +1054,12 @@ sc_const_long_option:
$(_sc_search_regexp)
NEWS_hash = \
- $$(sed -n '/^\*.* $(PREV_VERSION_REGEXP) ([0-9-]*)/,$$p' \
+ $$($(SED) -n '/^\*.* $(PREV_VERSION_REGEXP) ([0-9-]*)/,$$p' \
$(srcdir)/NEWS \
| perl -0777 -pe \
's/^Copyright.+?Free\sSoftware\sFoundation,\sInc\.\n//ms' \
| md5sum - \
- | sed 's/ .*//')
+ | $(SED) 's/ .*//')
# Ensure that we don't accidentally insert an entry into an old NEWS block.
sc_immutable_NEWS:
@@ -1097,7 +1097,7 @@ sc_makefile_at_at_check:
&& { echo '$(ME): use $$(...), not @...@' 1>&2; exit 1; } || :
news-check: NEWS
- $(AM_V_GEN)if sed -n $(news-check-lines-spec)p $< \
+ $(AM_V_GEN)if $(SED) -n $(news-check-lines-spec)p $< \
| grep -E $(news-check-regexp) >/dev/null; then \
:; \
else \
@@ -1146,7 +1146,7 @@ sc_po_check:
files="$$files $$file"; \
done; \
grep -E -l '$(_gl_translatable_string_re)' $$files \
- | sed 's|^$(_dot_escaped_srcdir)/||' | sort -u > $@-2; \
+ | $(SED) 's|^$(_dot_escaped_srcdir)/||' | sort -u > $@-2; \
diff -u -L $(po_file) -L $(po_file) $@-1 $@-2 \
|| { printf '$(ME): '$(fix_po_file_diag) 1>&2; exit 1; }; \
rm -f $@-1 $@-2; \
@@ -1511,7 +1511,7 @@ refresh-gnulib-patches:
test -n "$$t" && gl=$$t; \
fi; \
for diff in $$(cd $$gl; git ls-files | grep '\.diff$$'); do \
- b=$$(printf %s "$$diff"|sed 's/\.diff$$//'); \
+ b=$$(printf %s "$$diff"|$(SED) 's/\.diff$$//'); \
VERSION_CONTROL=none \
patch "$(gnulib_dir)/$$b" "$$gl/$$diff" || exit 1; \
( cd $(gnulib_dir) || exit 1; \
@@ -1530,7 +1530,8 @@ refresh-po:
wget --no-verbose --directory-prefix $(PODIR) --no-directories --recursive --level 1 --accept .po --accept .po.1 $(POURL) && \
echo 'en@boldquot' > $(PODIR)/LINGUAS && \
echo 'en@quot' >> $(PODIR)/LINGUAS && \
- ls $(PODIR)/*.po | sed 's/\.po//;s,$(PODIR)/,,' | sort >> $(PODIR)/LINGUAS
+ ls $(PODIR)/*.po | $(SED) 's/\.po//;s,$(PODIR)/,,' | \
+ sort >> $(PODIR)/LINGUAS
# Running indent once is not idempotent, but running it twice is.
INDENT_SOURCES ?= $(C_SOURCES)
@@ -1640,18 +1641,18 @@ _gl_tight_scope: $(bin_PROGRAMS)
test -f $$f && d= || d=$(srcdir)/; echo $$d$$f; done`; \
( printf '^%s$$\n' '__.*' $(_gl_TS_unmarked_extern_functions); \
grep -h -A1 '^extern .*[^;]$$' $$src \
- | grep -vE '^(extern |--)' | sed 's/ .*//'; \
+ | grep -vE '^(extern |--)' | $(SED) 's/ .*//'; \
perl -lne \
'$(_gl_TS_function_match) and print "^$$1\$$"' $$hdr; \
) | sort -u > $$t; \
- nm -e $(_gl_TS_obj_files) | sed -n 's/.* T //p'|grep -Ev -f $$t \
+ nm -e $(_gl_TS_obj_files)|$(SED) -n 's/.* T //p'|grep -Ev -f $$t \
&& { echo the above functions should have static scope >&2; \
exit 1; } || : ; \
( printf '^%s$$\n' '__.*' $(_gl_TS_unmarked_extern_vars); \
perl -lne '$(_gl_TS_var_match) and print "^$$1\$$"' \
$$hdr $(_gl_TS_other_headers) \
) | sort -u > $$t; \
- nm -e $(_gl_TS_obj_files) | sed -n 's/.* [BCDGRS] //p' \
+ nm -e $(_gl_TS_obj_files) | $(SED) -n 's/.* [BCDGRS] //p' \
| sort -u | grep -Ev -f $$t \
&& { echo the above variables should have static scope >&2; \
exit 1; } || :