From: Bruno Haible Date: Sat, 20 Jul 2019 12:25:21 +0000 (+0200) Subject: Update after gnulib changed. X-Git-Tag: v0.20.2~87 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5c61c0000e0fbb48aef6af02c86f33745a9a0c25;p=thirdparty%2Fgettext.git Update after gnulib changed. * autogen.sh (GNULIB_MODULES_TOOLS_FOR_SRC_COMMON_DEPENDENCIES): Add windows-rwlock. * gettext-runtime/intl/windows-rwlock.h: New file, from gnulib. * gettext-runtime/intl/windows-rwlock.c: New file, from gnulib. * gettext-runtime/intl/windows-initguard.h: New file, from gnulib. * gettext-runtime/intl/windows-spinlock.h: Remove file. * gettext-runtime/intl/lock.h: Update from gnulib. * gettext-runtime/intl/lock.c: Likewise. * gettext-runtime/intl/verify.h: Likewise. * gettext-runtime/intl/windows-mutex.h: Likewise. * gettext-runtime/intl/windows-recmutex.h: Likewise. * gettext-runtime/intl/Makefile.am (EXTRA_DIST): Add windows-rwlock.h, windows-initguard.h. Remove windows-spinlock.h. (LIBINTLSOURCES): Conditionally add windows-rwlock.c. (windows-rwlock.lo): New rule. (*.lo): Update dependencies. * Makefile.am (distcheck-hook): Check that gettext-runtime/intl/windows-*.[hc] are up-to-date. * gnulib-local/lib/libxml/threads.c: Test HAVE_PTHREAD_H, HAVE_WIN32_THREADS, HAVE_BEOS_THREADS only if LIBXML_THREAD_ENABLED is defined; otherwise use a fallback suitable for single-threaded applications. --- diff --git a/.gitignore b/.gitignore index db259acf1..81a02146b 100644 --- a/.gitignore +++ b/.gitignore @@ -239,13 +239,15 @@ /gettext-tools/libgettextpo/wctype-h.c /gettext-tools/libgettextpo/wctype.in.h /gettext-tools/libgettextpo/wcwidth.c +/gettext-tools/libgettextpo/windows-initguard.h /gettext-tools/libgettextpo/windows-mutex.c /gettext-tools/libgettextpo/windows-mutex.h /gettext-tools/libgettextpo/windows-once.c /gettext-tools/libgettextpo/windows-once.h /gettext-tools/libgettextpo/windows-recmutex.c /gettext-tools/libgettextpo/windows-recmutex.h -/gettext-tools/libgettextpo/windows-spinlock.h +/gettext-tools/libgettextpo/windows-rwlock.c +/gettext-tools/libgettextpo/windows-rwlock.h /gettext-tools/libgettextpo/windows-tls.c /gettext-tools/libgettextpo/windows-tls.h /gettext-tools/libgettextpo/xalloc-oversized.h diff --git a/Makefile.am b/Makefile.am index 5aeb7adf3..c2f634e59 100644 --- a/Makefile.am +++ b/Makefile.am @@ -95,13 +95,15 @@ distcheck-hook: test "`sed 1,15d $(srcdir)/gettext-runtime/intl/lock.c | md5sum`" = "`sed -e 1,15d -e 's,glthread/,,g' $(srcdir)/gettext-tools/gnulib-lib/glthread/lock.c | md5sum`" test "`sed 1,15d $(srcdir)/gettext-runtime/intl/threadlib.c | md5sum`" = "`sed -e 1,15d $(srcdir)/gettext-tools/gnulib-lib/glthread/threadlib.c | md5sum`" test "`sed 1,16d $(srcdir)/gettext-runtime/intl/verify.h | md5sum`" = "`sed 1,16d $(srcdir)/gettext-tools/gnulib-lib/verify.h | md5sum`" + test "`sed 1,15d $(srcdir)/gettext-runtime/intl/windows-initguard.h | md5sum`" = "`sed 1,15d $(srcdir)/gettext-tools/gnulib-lib/windows-initguard.h | md5sum`" test "`sed 1,15d $(srcdir)/gettext-runtime/intl/windows-mutex.h | md5sum`" = "`sed 1,15d $(srcdir)/gettext-tools/gnulib-lib/windows-mutex.h | md5sum`" test "`sed 1,15d $(srcdir)/gettext-runtime/intl/windows-mutex.c | md5sum`" = "`sed 1,15d $(srcdir)/gettext-tools/gnulib-lib/windows-mutex.c | md5sum`" test "`sed 1,15d $(srcdir)/gettext-runtime/intl/windows-once.h | md5sum`" = "`sed 1,15d $(srcdir)/gettext-tools/gnulib-lib/windows-once.h | md5sum`" test "`sed 1,15d $(srcdir)/gettext-runtime/intl/windows-once.c | md5sum`" = "`sed 1,15d $(srcdir)/gettext-tools/gnulib-lib/windows-once.c | md5sum`" test "`sed 1,15d $(srcdir)/gettext-runtime/intl/windows-recmutex.h | md5sum`" = "`sed 1,15d $(srcdir)/gettext-tools/gnulib-lib/windows-recmutex.h | md5sum`" test "`sed 1,15d $(srcdir)/gettext-runtime/intl/windows-recmutex.c | md5sum`" = "`sed 1,15d $(srcdir)/gettext-tools/gnulib-lib/windows-recmutex.c | md5sum`" - test "`sed 1,15d $(srcdir)/gettext-runtime/intl/windows-spinlock.h | md5sum`" = "`sed 1,15d $(srcdir)/gettext-tools/gnulib-lib/windows-spinlock.h | md5sum`" + test "`sed 1,15d $(srcdir)/gettext-runtime/intl/windows-rwlock.h | md5sum`" = "`sed 1,15d $(srcdir)/gettext-tools/gnulib-lib/windows-rwlock.h | md5sum`" + test "`sed 1,15d $(srcdir)/gettext-runtime/intl/windows-rwlock.c | md5sum`" = "`sed 1,15d $(srcdir)/gettext-tools/gnulib-lib/windows-rwlock.c | md5sum`" cmp -s $(srcdir)/gettext-runtime/intl/printf-args.h $(srcdir)/gettext-runtime/libasprintf/printf-args.h cmp -s $(srcdir)/gettext-runtime/intl/printf-args.c $(srcdir)/gettext-runtime/libasprintf/printf-args.c cmp -s $(srcdir)/gettext-runtime/intl/printf-parse.h $(srcdir)/gettext-runtime/libasprintf/printf-parse.h diff --git a/autogen.sh b/autogen.sh index c0ce815ba..c566d7130 100755 --- a/autogen.sh +++ b/autogen.sh @@ -250,6 +250,7 @@ if ! $skip_gnulib; then windows-mutex windows-once windows-recmutex + windows-rwlock ' GNULIB_MODULES_TOOLS_OTHER=' gettext-tools-misc diff --git a/gettext-runtime/intl/Makefile.am b/gettext-runtime/intl/Makefile.am index 9cb70a1f5..6063a9206 100644 --- a/gettext-runtime/intl/Makefile.am +++ b/gettext-runtime/intl/Makefile.am @@ -81,7 +81,7 @@ EXTRA_DIST += \ plural-exp.h \ eval-plural.h \ localcharset.h \ - lock.h windows-spinlock.h windows-mutex.h windows-recmutex.h windows-once.h \ + lock.h windows-mutex.h windows-rwlock.h windows-recmutex.h windows-once.h windows-initguard.h \ relocatable.h \ flexmember.h \ localename-table.in.h \ @@ -129,6 +129,7 @@ LIBINTLSOURCES = \ if WINDOWS_NATIVE LIBINTLSOURCES += \ windows-mutex.c \ + windows-rwlock.c \ windows-recmutex.c \ windows-once.c endif @@ -281,6 +282,8 @@ intl-compat.lo: $(srcdir)/intl-compat.c $(AM_V_CC)$(LTCOMPILE) -c -o $@ $(srcdir)/intl-compat.c windows-mutex.lo: $(srcdir)/windows-mutex.c $(AM_V_CC)$(LTCOMPILE) -c -o $@ $(srcdir)/windows-mutex.c +windows-rwlock.lo: $(srcdir)/windows-rwlock.c + $(AM_V_CC)$(LTCOMPILE) -c -o $@ $(srcdir)/windows-rwlock.c windows-recmutex.lo: $(srcdir)/windows-recmutex.c $(AM_V_CC)$(LTCOMPILE) -c -o $@ $(srcdir)/windows-recmutex.c windows-once.lo: $(srcdir)/windows-once.c @@ -294,39 +297,40 @@ if USE_INCLUDED_LIBINTL PLURAL_DEPS += libintl.h endif -bindtextdom.lo: ../config.h $(srcdir)/gettextP.h libgnuintl.h $(srcdir)/gmo.h $(srcdir)/loadinfo.h $(srcdir)/lock.h $(srcdir)/windows-spinlock.h $(srcdir)/windows-mutex.h $(srcdir)/windows-recmutex.h $(srcdir)/windows-once.h -dcgettext.lo: ../config.h $(srcdir)/gettextP.h libgnuintl.h $(srcdir)/gmo.h $(srcdir)/loadinfo.h $(srcdir)/lock.h $(srcdir)/windows-spinlock.h $(srcdir)/windows-mutex.h $(srcdir)/windows-recmutex.h $(srcdir)/windows-once.h -dgettext.lo: ../config.h $(srcdir)/gettextP.h libgnuintl.h $(srcdir)/gmo.h $(srcdir)/loadinfo.h $(srcdir)/lock.h $(srcdir)/windows-spinlock.h $(srcdir)/windows-mutex.h $(srcdir)/windows-recmutex.h $(srcdir)/windows-once.h -gettext.lo: ../config.h $(srcdir)/gettextP.h libgnuintl.h $(srcdir)/gmo.h $(srcdir)/loadinfo.h $(srcdir)/lock.h $(srcdir)/windows-spinlock.h $(srcdir)/windows-mutex.h $(srcdir)/windows-recmutex.h $(srcdir)/windows-once.h -finddomain.lo: ../config.h $(srcdir)/gettextP.h libgnuintl.h $(srcdir)/gmo.h $(srcdir)/loadinfo.h $(srcdir)/lock.h $(srcdir)/windows-spinlock.h $(srcdir)/windows-mutex.h $(srcdir)/windows-recmutex.h $(srcdir)/windows-once.h +bindtextdom.lo: ../config.h $(srcdir)/gettextP.h libgnuintl.h $(srcdir)/gmo.h $(srcdir)/loadinfo.h $(srcdir)/lock.h $(srcdir)/windows-mutex.h $(srcdir)/windows-rwlock.h $(srcdir)/windows-recmutex.h $(srcdir)/windows-once.h $(srcdir)/windows-initguard.h +dcgettext.lo: ../config.h $(srcdir)/gettextP.h libgnuintl.h $(srcdir)/gmo.h $(srcdir)/loadinfo.h $(srcdir)/lock.h $(srcdir)/windows-mutex.h $(srcdir)/windows-rwlock.h $(srcdir)/windows-recmutex.h $(srcdir)/windows-once.h $(srcdir)/windows-initguard.h +dgettext.lo: ../config.h $(srcdir)/gettextP.h libgnuintl.h $(srcdir)/gmo.h $(srcdir)/loadinfo.h $(srcdir)/lock.h $(srcdir)/windows-mutex.h $(srcdir)/windows-rwlock.h $(srcdir)/windows-recmutex.h $(srcdir)/windows-once.h $(srcdir)/windows-initguard.h +gettext.lo: ../config.h $(srcdir)/gettextP.h libgnuintl.h $(srcdir)/gmo.h $(srcdir)/loadinfo.h $(srcdir)/lock.h $(srcdir)/windows-mutex.h $(srcdir)/windows-rwlock.h $(srcdir)/windows-recmutex.h $(srcdir)/windows-once.h $(srcdir)/windows-initguard.h +finddomain.lo: ../config.h $(srcdir)/gettextP.h libgnuintl.h $(srcdir)/gmo.h $(srcdir)/loadinfo.h $(srcdir)/lock.h $(srcdir)/windows-mutex.h $(srcdir)/windows-rwlock.h $(srcdir)/windows-recmutex.h $(srcdir)/windows-once.h $(srcdir)/windows-initguard.h hash-string.lo: ../config.h $(srcdir)/hash-string.h -loadmsgcat.lo: ../config.h $(srcdir)/gettextP.h libgnuintl.h $(srcdir)/gmo.h $(srcdir)/loadinfo.h $(srcdir)/lock.h $(srcdir)/windows-spinlock.h $(srcdir)/windows-mutex.h $(srcdir)/windows-recmutex.h $(srcdir)/windows-once.h $(srcdir)/hash-string.h $(srcdir)/plural-exp.h -localealias.lo: ../config.h $(srcdir)/gettextP.h libgnuintl.h $(srcdir)/gmo.h $(srcdir)/loadinfo.h $(srcdir)/lock.h $(srcdir)/windows-spinlock.h $(srcdir)/windows-mutex.h $(srcdir)/windows-recmutex.h $(srcdir)/windows-once.h $(srcdir)/relocatable.h -textdomain.lo: ../config.h $(srcdir)/gettextP.h libgnuintl.h $(srcdir)/gmo.h $(srcdir)/loadinfo.h $(srcdir)/lock.h $(srcdir)/windows-spinlock.h $(srcdir)/windows-mutex.h $(srcdir)/windows-recmutex.h $(srcdir)/windows-once.h +loadmsgcat.lo: ../config.h $(srcdir)/gettextP.h libgnuintl.h $(srcdir)/gmo.h $(srcdir)/loadinfo.h $(srcdir)/lock.h $(srcdir)/windows-mutex.h $(srcdir)/windows-rwlock.h $(srcdir)/windows-recmutex.h $(srcdir)/windows-once.h $(srcdir)/windows-initguard.h $(srcdir)/hash-string.h $(srcdir)/plural-exp.h +localealias.lo: ../config.h $(srcdir)/gettextP.h libgnuintl.h $(srcdir)/gmo.h $(srcdir)/loadinfo.h $(srcdir)/lock.h $(srcdir)/windows-mutex.h $(srcdir)/windows-rwlock.h $(srcdir)/windows-recmutex.h $(srcdir)/windows-once.h $(srcdir)/windows-initguard.h $(srcdir)/relocatable.h +textdomain.lo: ../config.h $(srcdir)/gettextP.h libgnuintl.h $(srcdir)/gmo.h $(srcdir)/loadinfo.h $(srcdir)/lock.h $(srcdir)/windows-mutex.h $(srcdir)/windows-rwlock.h $(srcdir)/windows-recmutex.h $(srcdir)/windows-once.h $(srcdir)/windows-initguard.h l10nflist.lo: ../config.h $(srcdir)/loadinfo.h explodename.lo: ../config.h $(srcdir)/loadinfo.h -dcigettext.lo: ../config.h $(srcdir)/gettextP.h libgnuintl.h $(srcdir)/gmo.h $(srcdir)/loadinfo.h $(srcdir)/lock.h $(srcdir)/windows-spinlock.h $(srcdir)/windows-mutex.h $(srcdir)/windows-recmutex.h $(srcdir)/windows-once.h $(srcdir)/localcharset.h $(srcdir)/plural-exp.h $(srcdir)/hash-string.h $(srcdir)/tsearch.h $(srcdir)/tsearch.c $(srcdir)/eval-plural.h -dcngettext.lo: ../config.h $(srcdir)/gettextP.h libgnuintl.h $(srcdir)/gmo.h $(srcdir)/loadinfo.h $(srcdir)/lock.h $(srcdir)/windows-spinlock.h $(srcdir)/windows-mutex.h $(srcdir)/windows-recmutex.h $(srcdir)/windows-once.h -dngettext.lo: ../config.h $(srcdir)/gettextP.h libgnuintl.h $(srcdir)/gmo.h $(srcdir)/loadinfo.h $(srcdir)/lock.h $(srcdir)/windows-spinlock.h $(srcdir)/windows-mutex.h $(srcdir)/windows-recmutex.h $(srcdir)/windows-once.h -ngettext.lo: ../config.h $(srcdir)/gettextP.h libgnuintl.h $(srcdir)/gmo.h $(srcdir)/loadinfo.h $(srcdir)/lock.h $(srcdir)/windows-spinlock.h $(srcdir)/windows-mutex.h $(srcdir)/windows-recmutex.h $(srcdir)/windows-once.h +dcigettext.lo: ../config.h $(srcdir)/gettextP.h libgnuintl.h $(srcdir)/gmo.h $(srcdir)/loadinfo.h $(srcdir)/lock.h $(srcdir)/windows-mutex.h $(srcdir)/windows-rwlock.h $(srcdir)/windows-recmutex.h $(srcdir)/windows-once.h $(srcdir)/windows-initguard.h $(srcdir)/localcharset.h $(srcdir)/plural-exp.h $(srcdir)/hash-string.h $(srcdir)/tsearch.h $(srcdir)/tsearch.c $(srcdir)/eval-plural.h +dcngettext.lo: ../config.h $(srcdir)/gettextP.h libgnuintl.h $(srcdir)/gmo.h $(srcdir)/loadinfo.h $(srcdir)/lock.h $(srcdir)/windows-mutex.h $(srcdir)/windows-rwlock.h $(srcdir)/windows-recmutex.h $(srcdir)/windows-once.h $(srcdir)/windows-initguard.h +dngettext.lo: ../config.h $(srcdir)/gettextP.h libgnuintl.h $(srcdir)/gmo.h $(srcdir)/loadinfo.h $(srcdir)/lock.h $(srcdir)/windows-mutex.h $(srcdir)/windows-rwlock.h $(srcdir)/windows-recmutex.h $(srcdir)/windows-once.h $(srcdir)/windows-initguard.h +ngettext.lo: ../config.h $(srcdir)/gettextP.h libgnuintl.h $(srcdir)/gmo.h $(srcdir)/loadinfo.h $(srcdir)/lock.h $(srcdir)/windows-mutex.h $(srcdir)/windows-rwlock.h $(srcdir)/windows-recmutex.h $(srcdir)/windows-once.h $(srcdir)/windows-initguard.h plural.lo: ../config.h $(srcdir)/plural-exp.h $(PLURAL_DEPS) plural-exp.lo: ../config.h $(srcdir)/plural-exp.h localcharset.lo: ../config.h $(srcdir)/localcharset.h threadlib.lo: ../config.h -lock.lo: ../config.h $(srcdir)/lock.h $(srcdir)/windows-spinlock.h $(srcdir)/windows-mutex.h $(srcdir)/windows-recmutex.h $(srcdir)/windows-once.h +lock.lo: ../config.h $(srcdir)/lock.h $(srcdir)/windows-mutex.h $(srcdir)/windows-rwlock.h $(srcdir)/windows-recmutex.h $(srcdir)/windows-once.h $(srcdir)/windows-initguard.h relocatable.lo: ../config.h $(srcdir)/relocatable.h langprefs.lo: ../config.h -localename.lo: ../config.h $(srcdir)/gettextP.h libgnuintl.h $(srcdir)/gmo.h $(srcdir)/loadinfo.h $(srcdir)/lock.h $(srcdir)/windows-spinlock.h $(srcdir)/windows-mutex.h $(srcdir)/windows-recmutex.h $(srcdir)/windows-once.h $(srcdir)/flexmember.h localename-table.h -localename-table.lo: ../config.h localename-table.h $(srcdir)/lock.h $(srcdir)/windows-spinlock.h $(srcdir)/windows-mutex.h $(srcdir)/windows-recmutex.h $(srcdir)/windows-once.h -log.lo: ../config.h $(srcdir)/lock.h $(srcdir)/windows-spinlock.h $(srcdir)/windows-mutex.h $(srcdir)/windows-recmutex.h $(srcdir)/windows-once.h +localename.lo: ../config.h $(srcdir)/gettextP.h libgnuintl.h $(srcdir)/gmo.h $(srcdir)/loadinfo.h $(srcdir)/lock.h $(srcdir)/windows-mutex.h $(srcdir)/windows-rwlock.h $(srcdir)/windows-recmutex.h $(srcdir)/windows-once.h $(srcdir)/windows-initguard.h $(srcdir)/flexmember.h localename-table.h +localename-table.lo: ../config.h localename-table.h $(srcdir)/lock.h $(srcdir)/windows-mutex.h $(srcdir)/windows-rwlock.h $(srcdir)/windows-recmutex.h $(srcdir)/windows-once.h $(srcdir)/windows-initguard.h +log.lo: ../config.h $(srcdir)/lock.h $(srcdir)/windows-mutex.h $(srcdir)/windows-rwlock.h $(srcdir)/windows-recmutex.h $(srcdir)/windows-once.h $(srcdir)/windows-initguard.h printf.lo: ../config.h $(srcdir)/printf-args.c $(srcdir)/printf-args.h $(srcdir)/printf-parse.c $(srcdir)/printf-parse.h $(srcdir)/wprintf-parse.h $(srcdir)/xsize.h $(srcdir)/vasnprintf.c $(srcdir)/vasnprintf.h $(srcdir)/vasnwprintf.h $(srcdir)/verify.h -setlocale.lo: ../config.h $(srcdir)/gettextP.h libgnuintl.h $(srcdir)/gmo.h $(srcdir)/loadinfo.h $(srcdir)/lock.h $(srcdir)/windows-spinlock.h $(srcdir)/windows-mutex.h $(srcdir)/windows-recmutex.h $(srcdir)/windows-once.h +setlocale.lo: ../config.h $(srcdir)/gettextP.h libgnuintl.h $(srcdir)/gmo.h $(srcdir)/loadinfo.h $(srcdir)/lock.h $(srcdir)/windows-mutex.h $(srcdir)/windows-rwlock.h $(srcdir)/windows-recmutex.h $(srcdir)/windows-once.h $(srcdir)/windows-initguard.h version.lo: ../config.h libgnuintl.h xsize.lo: ../config.h $(srcdir)/xsize.h osdep.lo: ../config.h $(srcdir)/intl-exports.c $(srcdir)/os2compat.c -intl-compat.lo: ../config.h $(srcdir)/gettextP.h libgnuintl.h $(srcdir)/gmo.h $(srcdir)/loadinfo.h $(srcdir)/lock.h $(srcdir)/windows-spinlock.h $(srcdir)/windows-mutex.h $(srcdir)/windows-recmutex.h $(srcdir)/windows-once.h -windows-mutex.lo: ../config.h $(srcdir)/windows-mutex.h $(srcdir)/windows-spinlock.h -windows-recmutex.lo: ../config.h $(srcdir)/windows-recmutex.h $(srcdir)/windows-spinlock.h +intl-compat.lo: ../config.h $(srcdir)/gettextP.h libgnuintl.h $(srcdir)/gmo.h $(srcdir)/loadinfo.h $(srcdir)/lock.h $(srcdir)/windows-mutex.h $(srcdir)/windows-rwlock.h $(srcdir)/windows-recmutex.h $(srcdir)/windows-once.h $(srcdir)/windows-initguard.h +windows-mutex.lo: ../config.h $(srcdir)/windows-mutex.h $(srcdir)/windows-initguard.h +windows-rwlock.lo: ../config.h $(srcdir)/windows-rwlock.h $(srcdir)/windows-initguard.h +windows-recmutex.lo: ../config.h $(srcdir)/windows-recmutex.h $(srcdir)/windows-initguard.h windows-once.lo: ../config.h $(srcdir)/windows-once.h # Version information according to Woe32 conventions. diff --git a/gettext-runtime/intl/lock.c b/gettext-runtime/intl/lock.c index ad2794baa..564011178 100644 --- a/gettext-runtime/intl/lock.c +++ b/gettext-runtime/intl/lock.c @@ -15,8 +15,7 @@ along with this program. If not, see . */ /* Written by Bruno Haible , 2005. - Based on GCC's gthr-posix.h, gthr-posix95.h, gthr-solaris.h, - gthr-win32.h. */ + Based on GCC's gthr-posix.h, gthr-posix95.h. */ #include @@ -500,579 +499,8 @@ glthread_once_singlethreaded (pthread_once_t *once_control) /* ========================================================================= */ -#if USE_PTH_THREADS - -/* Use the GNU Pth threads library. */ - -/* -------------------------- gl_lock_t datatype -------------------------- */ - -/* ------------------------- gl_rwlock_t datatype ------------------------- */ - -# if !HAVE_PTH_RWLOCK_ACQUIRE_PREFER_WRITER - -int -glthread_rwlock_init_multithreaded (gl_rwlock_t *lock) -{ - if (!pth_mutex_init (&lock->lock)) - return errno; - if (!pth_cond_init (&lock->waiting_readers)) - return errno; - if (!pth_cond_init (&lock->waiting_writers)) - return errno; - lock->waiting_writers_count = 0; - lock->runcount = 0; - lock->initialized = 1; - return 0; -} - -int -glthread_rwlock_rdlock_multithreaded (gl_rwlock_t *lock) -{ - if (!lock->initialized) - glthread_rwlock_init_multithreaded (lock); - if (!pth_mutex_acquire (&lock->lock, 0, NULL)) - return errno; - /* Test whether only readers are currently running, and whether the runcount - field will not overflow, and whether no writer is waiting. The latter - condition is because POSIX recommends that "write locks shall take - precedence over read locks", to avoid "writer starvation". */ - while (!(lock->runcount + 1 > 0 && lock->waiting_writers_count == 0)) - { - /* This thread has to wait for a while. Enqueue it among the - waiting_readers. */ - if (!pth_cond_await (&lock->waiting_readers, &lock->lock, NULL)) - { - int err = errno; - pth_mutex_release (&lock->lock); - return err; - } - } - lock->runcount++; - return (!pth_mutex_release (&lock->lock) ? errno : 0); -} - -int -glthread_rwlock_wrlock_multithreaded (gl_rwlock_t *lock) -{ - if (!lock->initialized) - glthread_rwlock_init_multithreaded (lock); - if (!pth_mutex_acquire (&lock->lock, 0, NULL)) - return errno; - /* 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++; - if (!pth_cond_await (&lock->waiting_writers, &lock->lock, NULL)) - { - int err = errno; - lock->waiting_writers_count--; - pth_mutex_release (&lock->lock); - return err; - } - lock->waiting_writers_count--; - } - lock->runcount--; /* runcount becomes -1 */ - return (!pth_mutex_release (&lock->lock) ? errno : 0); -} - -int -glthread_rwlock_unlock_multithreaded (gl_rwlock_t *lock) -{ - int err; - - if (!lock->initialized) - return EINVAL; - if (!pth_mutex_acquire (&lock->lock, 0, NULL)) - return errno; - if (lock->runcount < 0) - { - /* Drop a writer lock. */ - if (!(lock->runcount == -1)) - { - pth_mutex_release (&lock->lock); - return EINVAL; - } - lock->runcount = 0; - } - else - { - /* Drop a reader lock. */ - if (!(lock->runcount > 0)) - { - pth_mutex_release (&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. */ - if (!pth_cond_notify (&lock->waiting_writers, FALSE)) - { - int err = errno; - pth_mutex_release (&lock->lock); - return err; - } - } - else - { - /* Wake up all waiting readers. */ - if (!pth_cond_notify (&lock->waiting_readers, TRUE)) - { - int err = errno; - pth_mutex_release (&lock->lock); - return err; - } - } - } - return (!pth_mutex_release (&lock->lock) ? errno : 0); -} - -int -glthread_rwlock_destroy_multithreaded (gl_rwlock_t *lock) -{ - lock->initialized = 0; - return 0; -} - -# endif - -/* --------------------- 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_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 - { - /* Don't let lock->guard.started grow and wrap around. */ - InterlockedDecrement (&lock->guard.started); - /* 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, and whether no writer is waiting. The latter - condition is because POSIX recommends that "write locks shall take - precedence over read locks", to avoid "writer starvation". */ - if (!(lock->runcount + 1 > 0 && lock->waiting_writers.count == 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 - { - /* Don't let lock->guard.started grow and wrap around. */ - InterlockedDecrement (&lock->guard.started); - /* 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; -} - #endif /* ========================================================================= */ diff --git a/gettext-runtime/intl/lock.h b/gettext-runtime/intl/lock.h index e5cc1a606..2c8a5e424 100644 --- a/gettext-runtime/intl/lock.h +++ b/gettext-runtime/intl/lock.h @@ -15,8 +15,7 @@ along with this program. If not, see . */ /* Written by Bruno Haible , 2005. - Based on GCC's gthr-posix.h, gthr-posix95.h, gthr-solaris.h, - gthr-win32.h. */ + Based on GCC's gthr-posix.h, gthr-posix95.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 @@ -82,7 +81,7 @@ #include #if !defined c11_threads_in_use -# if HAVE_THREADS_H && (USE_POSIX_THREADS_WEAK || USE_PTH_THREADS_WEAK || USE_SOLARIS_THREADS_WEAK) +# if HAVE_THREADS_H && USE_POSIX_THREADS_WEAK # include # pragma weak thrd_exit # define c11_threads_in_use() (thrd_exit != NULL) @@ -406,292 +405,13 @@ extern int glthread_once_singlethreaded (pthread_once_t *once_control); /* ========================================================================= */ -#if USE_PTH_THREADS - -/* Use the GNU Pth threads library. */ - -# include - -# 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_cond_init -# pragma weak pth_cond_await -# pragma weak pth_cond_notify - -# pragma weak pth_cancel -# define pth_in_use() (pth_cancel != NULL || c11_threads_in_use ()) - -# 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 ------------------------- */ - -/* Pth pth_rwlock_acquire always prefers readers. No autoconf test so far. */ -# if HAVE_PTH_RWLOCK_ACQUIRE_PREFER_WRITER - -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) - -# else - -typedef struct - { - int initialized; - pth_mutex_t lock; /* protects the remaining fields */ - pth_cond_t waiting_readers; /* waiting readers */ - pth_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 \ - { 0 } -# define glthread_rwlock_init(LOCK) \ - (pth_in_use () ? glthread_rwlock_init_multithreaded (LOCK) : 0) -# define glthread_rwlock_rdlock(LOCK) \ - (pth_in_use () ? glthread_rwlock_rdlock_multithreaded (LOCK) : 0) -# define glthread_rwlock_wrlock(LOCK) \ - (pth_in_use () ? glthread_rwlock_wrlock_multithreaded (LOCK) : 0) -# define glthread_rwlock_unlock(LOCK) \ - (pth_in_use () ? glthread_rwlock_unlock_multithreaded (LOCK) : 0) -# define glthread_rwlock_destroy(LOCK) \ - (pth_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 --------------------- */ - -/* 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 -# include - -# 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 || c11_threads_in_use ()) - -# 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 -# include "windows-spinlock.h" # include "windows-mutex.h" +# include "windows-rwlock.h" # include "windows-recmutex.h" # include "windows-once.h" @@ -730,48 +450,23 @@ typedef glwthread_mutex_t gl_lock_t; /* ------------------------- 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 - { - glwthread_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; +typedef glwthread_rwlock_t 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 \ - { GLWTHREAD_SPINLOCK_INIT } + GLWTHREAD_RWLOCK_INIT # define glthread_rwlock_init(LOCK) \ - (glthread_rwlock_init_func (LOCK), 0) + (glwthread_rwlock_init (LOCK), 0) # define glthread_rwlock_rdlock(LOCK) \ - glthread_rwlock_rdlock_func (LOCK) + glwthread_rwlock_rdlock (LOCK) # define glthread_rwlock_wrlock(LOCK) \ - glthread_rwlock_wrlock_func (LOCK) + glwthread_rwlock_wrlock (LOCK) # define glthread_rwlock_unlock(LOCK) \ - glthread_rwlock_unlock_func (LOCK) + glwthread_rwlock_unlock (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); + glwthread_rwlock_destroy (LOCK) /* --------------------- gl_recursive_lock_t datatype --------------------- */ @@ -807,7 +502,7 @@ typedef glwthread_once_t gl_once_t; /* ========================================================================= */ -#if !(USE_POSIX_THREADS || USE_PTH_THREADS || USE_SOLARIS_THREADS || USE_WINDOWS_THREADS) +#if !(USE_POSIX_THREADS || USE_WINDOWS_THREADS) /* Provide dummy implementation if threads are not supported. */ diff --git a/gettext-runtime/intl/verify.h b/gettext-runtime/intl/verify.h index 33be83c66..3d0868cd0 100644 --- a/gettext-runtime/intl/verify.h +++ b/gettext-runtime/intl/verify.h @@ -259,9 +259,11 @@ template # define __has_builtin(x) 0 #endif -/* Assume that R always holds. This lets the compiler optimize - accordingly. R should not have side-effects; it may or may not be - evaluated. Behavior is undefined if R is false. */ +/* Assume that R always holds. Behavior is undefined if R is false, + fails to evaluate, or has side effects. Although assuming R can + help a compiler generate better code or diagnostics, performance + can suffer if R uses hard-to-optimize features such as function + calls not inlined by the compiler. */ #if (__has_builtin (__builtin_unreachable) \ || 4 < __GNUC__ + (5 <= __GNUC_MINOR__)) diff --git a/gettext-runtime/intl/windows-spinlock.h b/gettext-runtime/intl/windows-initguard.h similarity index 80% rename from gettext-runtime/intl/windows-spinlock.h rename to gettext-runtime/intl/windows-initguard.h index 6f9cbe15b..7a3aa6d43 100644 --- a/gettext-runtime/intl/windows-spinlock.h +++ b/gettext-runtime/intl/windows-initguard.h @@ -1,4 +1,4 @@ -/* Spinlocks (native Windows implementation). +/* Init guards, somewhat like spinlocks (native Windows implementation). Copyright (C) 2005-2019 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify @@ -17,8 +17,8 @@ /* Written by Bruno Haible , 2005. Based on GCC's gthr-win32.h. */ -#ifndef _WINDOWS_SPINLOCK_H -#define _WINDOWS_SPINLOCK_H +#ifndef _WINDOWS_INITGUARD_H +#define _WINDOWS_INITGUARD_H #define WIN32_LEAN_AND_MEAN /* avoid including junk */ #include @@ -28,8 +28,8 @@ typedef struct volatile int done; volatile LONG started; } - glwthread_spinlock_t; + glwthread_initguard_t; -#define GLWTHREAD_SPINLOCK_INIT { 0, -1 } +#define GLWTHREAD_INITGUARD_INIT { 0, -1 } -#endif /* _WINDOWS_SPINLOCK_H */ +#endif /* _WINDOWS_INITGUARD_H */ diff --git a/gettext-runtime/intl/windows-mutex.h b/gettext-runtime/intl/windows-mutex.h index 5a1b5506b..5d3d8e4db 100644 --- a/gettext-runtime/intl/windows-mutex.h +++ b/gettext-runtime/intl/windows-mutex.h @@ -23,16 +23,16 @@ #define WIN32_LEAN_AND_MEAN /* avoid including junk */ #include -#include "windows-spinlock.h" +#include "windows-initguard.h" typedef struct { - glwthread_spinlock_t guard; /* protects the initialization */ + glwthread_initguard_t guard; /* protects the initialization */ CRITICAL_SECTION lock; } glwthread_mutex_t; -#define GLWTHREAD_MUTEX_INIT { GLWTHREAD_SPINLOCK_INIT } +#define GLWTHREAD_MUTEX_INIT { GLWTHREAD_INITGUARD_INIT } #ifdef __cplusplus extern "C" { diff --git a/gettext-runtime/intl/windows-recmutex.h b/gettext-runtime/intl/windows-recmutex.h index 24eb12c1e..2586cc50e 100644 --- a/gettext-runtime/intl/windows-recmutex.h +++ b/gettext-runtime/intl/windows-recmutex.h @@ -23,7 +23,7 @@ #define WIN32_LEAN_AND_MEAN /* avoid including junk */ #include -#include "windows-spinlock.h" +#include "windows-initguard.h" /* The native Windows documentation says that CRITICAL_SECTION already implements a recursive lock. But we need not rely on it: It's easy to @@ -31,14 +31,14 @@ typedef struct { - glwthread_spinlock_t guard; /* protects the initialization */ + glwthread_initguard_t guard; /* protects the initialization */ DWORD owner; unsigned long depth; CRITICAL_SECTION lock; } glwthread_recmutex_t; -#define GLWTHREAD_RECMUTEX_INIT { GLWTHREAD_SPINLOCK_INIT, 0, 0 } +#define GLWTHREAD_RECMUTEX_INIT { GLWTHREAD_INITGUARD_INIT, 0, 0 } #ifdef __cplusplus extern "C" { diff --git a/gettext-runtime/intl/windows-rwlock.c b/gettext-runtime/intl/windows-rwlock.c new file mode 100644 index 000000000..c69427e98 --- /dev/null +++ b/gettext-runtime/intl/windows-rwlock.c @@ -0,0 +1,373 @@ +/* Read-write locks (native Windows implementation). + Copyright (C) 2005-2019 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.1 of the License, 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 . */ + +/* Written by Bruno Haible , 2005. + Based on GCC's gthr-win32.h. */ + +#include + +/* Specification. */ +#include "windows-rwlock.h" + +#include +#include + +/* In this file, the waitqueues are implemented as circular arrays. */ +#define glwthread_waitqueue_t glwthread_carray_waitqueue_t + +static void +glwthread_waitqueue_init (glwthread_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 +glwthread_waitqueue_add (glwthread_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 +glwthread_waitqueue_notify_first (glwthread_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 +glwthread_waitqueue_notify_all (glwthread_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 +glwthread_rwlock_init (glwthread_rwlock_t *lock) +{ + InitializeCriticalSection (&lock->lock); + glwthread_waitqueue_init (&lock->waiting_readers); + glwthread_waitqueue_init (&lock->waiting_writers); + lock->runcount = 0; + lock->guard.done = 1; +} + +int +glwthread_rwlock_rdlock (glwthread_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. */ + glwthread_rwlock_init (lock); + else + { + /* Don't let lock->guard.started grow and wrap around. */ + InterlockedDecrement (&lock->guard.started); + /* 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, and whether no writer is waiting. The latter + condition is because POSIX recommends that "write locks shall take + precedence over read locks", to avoid "writer starvation". */ + if (!(lock->runcount + 1 > 0 && lock->waiting_writers.count == 0)) + { + /* This thread has to wait for a while. Enqueue it among the + waiting_readers. */ + HANDLE event = glwthread_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 +glwthread_rwlock_wrlock (glwthread_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. */ + glwthread_rwlock_init (lock); + else + { + /* Don't let lock->guard.started grow and wrap around. */ + InterlockedDecrement (&lock->guard.started); + /* 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 = glwthread_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 +glwthread_rwlock_tryrdlock (glwthread_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. */ + glwthread_rwlock_init (lock); + else + { + /* Don't let lock->guard.started grow and wrap around. */ + InterlockedDecrement (&lock->guard.started); + /* Yield the CPU while waiting for another thread to finish + initializing this lock. */ + while (!lock->guard.done) + Sleep (0); + } + } + /* It's OK to wait for this critical section, because it is never taken for a + long time. */ + EnterCriticalSection (&lock->lock); + /* Test whether only readers are currently running, and whether the runcount + field will not overflow, and whether no writer is waiting. The latter + condition is because POSIX recommends that "write locks shall take + precedence over read locks", to avoid "writer starvation". */ + if (!(lock->runcount + 1 > 0 && lock->waiting_writers.count == 0)) + { + /* This thread would have to wait for a while. Return instead. */ + LeaveCriticalSection (&lock->lock); + return EBUSY; + } + lock->runcount++; + LeaveCriticalSection (&lock->lock); + return 0; +} + +int +glwthread_rwlock_trywrlock (glwthread_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. */ + glwthread_rwlock_init (lock); + else + { + /* Don't let lock->guard.started grow and wrap around. */ + InterlockedDecrement (&lock->guard.started); + /* Yield the CPU while waiting for another thread to finish + initializing this lock. */ + while (!lock->guard.done) + Sleep (0); + } + } + /* It's OK to wait for this critical section, because it is never taken for a + long time. */ + EnterCriticalSection (&lock->lock); + /* Test whether no readers or writers are currently running. */ + if (!(lock->runcount == 0)) + { + /* This thread would have to wait for a while. Return instead. */ + LeaveCriticalSection (&lock->lock); + return EBUSY; + } + lock->runcount--; /* runcount becomes -1 */ + LeaveCriticalSection (&lock->lock); + return 0; +} + +int +glwthread_rwlock_unlock (glwthread_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--; + glwthread_waitqueue_notify_first (&lock->waiting_writers); + } + else + { + /* Wake up all waiting readers. */ + lock->runcount += lock->waiting_readers.count; + glwthread_waitqueue_notify_all (&lock->waiting_readers); + } + } + LeaveCriticalSection (&lock->lock); + return 0; +} + +int +glwthread_rwlock_destroy (glwthread_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; +} diff --git a/gettext-runtime/intl/windows-rwlock.h b/gettext-runtime/intl/windows-rwlock.h new file mode 100644 index 000000000..8fc017c76 --- /dev/null +++ b/gettext-runtime/intl/windows-rwlock.h @@ -0,0 +1,68 @@ +/* Read-write locks (native Windows implementation). + Copyright (C) 2005-2019 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.1 of the License, 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 . */ + +/* Written by Bruno Haible , 2005. + Based on GCC's gthr-win32.h. */ + +#ifndef _WINDOWS_RWLOCK_H +#define _WINDOWS_RWLOCK_H + +#define WIN32_LEAN_AND_MEAN /* avoid including junk */ +#include + +#include "windows-initguard.h" + +/* 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 */ + } + glwthread_carray_waitqueue_t; +typedef struct + { + glwthread_initguard_t guard; /* protects the initialization */ + CRITICAL_SECTION lock; /* protects the remaining fields */ + glwthread_carray_waitqueue_t waiting_readers; /* waiting readers */ + glwthread_carray_waitqueue_t waiting_writers; /* waiting writers */ + int runcount; /* number of readers running, or -1 when a writer runs */ + } + glwthread_rwlock_t; + +#define GLWTHREAD_RWLOCK_INIT { GLWTHREAD_INITGUARD_INIT } + +#ifdef __cplusplus +extern "C" { +#endif + +extern void glwthread_rwlock_init (glwthread_rwlock_t *lock); +extern int glwthread_rwlock_rdlock (glwthread_rwlock_t *lock); +extern int glwthread_rwlock_wrlock (glwthread_rwlock_t *lock); +extern int glwthread_rwlock_tryrdlock (glwthread_rwlock_t *lock); +extern int glwthread_rwlock_trywrlock (glwthread_rwlock_t *lock); +extern int glwthread_rwlock_unlock (glwthread_rwlock_t *lock); +extern int glwthread_rwlock_destroy (glwthread_rwlock_t *lock); + +#ifdef __cplusplus +} +#endif + +#endif /* _WINDOWS_RWLOCK_H */ diff --git a/gnulib-local/lib/libxml/threads.c b/gnulib-local/lib/libxml/threads.c index 0433ac0f5..49ae00801 100644 --- a/gnulib-local/lib/libxml/threads.c +++ b/gnulib-local/lib/libxml/threads.c @@ -45,6 +45,7 @@ /* #define DEBUG_THREADS */ +#ifdef LIBXML_THREAD_ENABLED #ifdef HAVE_PTHREAD_H #if defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 303) && \ @@ -79,6 +80,7 @@ static int libxml_is_threaded = 1; #endif /* __GNUC__, __GLIBC__, __linux__ */ #endif /* HAVE_PTHREAD_H */ +#endif /* LIBXML_THREAD_ENABLED */ /* * TODO: this module still uses malloc/free and not xmlMalloc/xmlFree @@ -90,6 +92,7 @@ static int libxml_is_threaded = 1; * xmlMutex are a simple mutual exception locks */ struct _xmlMutex { +#ifdef LIBXML_THREAD_ENABLED #ifdef HAVE_PTHREAD_H pthread_mutex_t lock; #elif defined HAVE_WIN32_THREADS @@ -100,12 +103,16 @@ struct _xmlMutex { #else int empty; #endif +#else + int empty; +#endif }; /* * xmlRMutex are reentrant mutual exception locks */ struct _xmlRMutex { +#ifdef LIBXML_THREAD_ENABLED #ifdef HAVE_PTHREAD_H pthread_mutex_t lock; unsigned int held; @@ -122,6 +129,9 @@ struct _xmlRMutex { #else int empty; #endif +#else + int empty; +#endif }; /* @@ -130,6 +140,7 @@ struct _xmlRMutex { * - globalkey used for per-thread data */ +#ifdef LIBXML_THREAD_ENABLED #ifdef HAVE_PTHREAD_H static pthread_key_t globalkey; static pthread_t mainthread; @@ -158,6 +169,7 @@ int32 run_once_init = 0; static int32 global_init_lock = -1; static vint32 global_init_count = 0; #endif +#endif static xmlRMutexPtr xmlLibraryLock = NULL; @@ -180,6 +192,7 @@ xmlNewMutex(void) if ((tok = malloc(sizeof(xmlMutex))) == NULL) return (NULL); +#ifdef LIBXML_THREAD_ENABLED #ifdef HAVE_PTHREAD_H if (libxml_is_threaded != 0) pthread_mutex_init(&tok->lock, NULL); @@ -191,6 +204,7 @@ xmlNewMutex(void) return NULL; } tok->tid = -1; +#endif #endif return (tok); } @@ -208,6 +222,7 @@ xmlFreeMutex(xmlMutexPtr tok) if (tok == NULL) return; +#ifdef LIBXML_THREAD_ENABLED #ifdef HAVE_PTHREAD_H if (libxml_is_threaded != 0) pthread_mutex_destroy(&tok->lock); @@ -215,6 +230,7 @@ xmlFreeMutex(xmlMutexPtr tok) CloseHandle(tok->mutex); #elif defined HAVE_BEOS_THREADS delete_sem(tok->sem); +#endif #endif free(tok); } @@ -230,6 +246,7 @@ xmlMutexLock(xmlMutexPtr tok) { if (tok == NULL) return; +#ifdef LIBXML_THREAD_ENABLED #ifdef HAVE_PTHREAD_H if (libxml_is_threaded != 0) pthread_mutex_lock(&tok->lock); @@ -244,7 +261,7 @@ xmlMutexLock(xmlMutexPtr tok) } tok->tid = find_thread(NULL); #endif - +#endif } /** @@ -258,6 +275,7 @@ xmlMutexUnlock(xmlMutexPtr tok) { if (tok == NULL) return; +#ifdef LIBXML_THREAD_ENABLED #ifdef HAVE_PTHREAD_H if (libxml_is_threaded != 0) pthread_mutex_unlock(&tok->lock); @@ -269,6 +287,7 @@ xmlMutexUnlock(xmlMutexPtr tok) release_sem(tok->sem); } #endif +#endif } /** @@ -288,6 +307,7 @@ xmlNewRMutex(void) if ((tok = malloc(sizeof(xmlRMutex))) == NULL) return (NULL); +#ifdef LIBXML_THREAD_ENABLED #ifdef HAVE_PTHREAD_H if (libxml_is_threaded != 0) { pthread_mutex_init(&tok->lock, NULL); @@ -304,6 +324,7 @@ xmlNewRMutex(void) return NULL; } tok->count = 0; +#endif #endif return (tok); } @@ -320,6 +341,7 @@ xmlFreeRMutex(xmlRMutexPtr tok ATTRIBUTE_UNUSED) { if (tok == NULL) return; +#ifdef LIBXML_THREAD_ENABLED #ifdef HAVE_PTHREAD_H if (libxml_is_threaded != 0) { pthread_mutex_destroy(&tok->lock); @@ -329,6 +351,7 @@ xmlFreeRMutex(xmlRMutexPtr tok ATTRIBUTE_UNUSED) DeleteCriticalSection(&tok->cs); #elif defined HAVE_BEOS_THREADS xmlFreeMutex(tok->lock); +#endif #endif free(tok); } @@ -344,6 +367,7 @@ xmlRMutexLock(xmlRMutexPtr tok) { if (tok == NULL) return; +#ifdef LIBXML_THREAD_ENABLED #ifdef HAVE_PTHREAD_H if (libxml_is_threaded == 0) return; @@ -376,6 +400,7 @@ xmlRMutexLock(xmlRMutexPtr tok) tok->count = 1; } #endif +#endif } /** @@ -389,6 +414,7 @@ xmlRMutexUnlock(xmlRMutexPtr tok ATTRIBUTE_UNUSED) { if (tok == NULL) return; +#ifdef LIBXML_THREAD_ENABLED #ifdef HAVE_PTHREAD_H if (libxml_is_threaded == 0) return; @@ -415,6 +441,7 @@ xmlRMutexUnlock(xmlRMutexPtr tok ATTRIBUTE_UNUSED) return; } #endif +#endif } /** @@ -427,6 +454,7 @@ void __xmlGlobalInitMutexLock(void) { /* Make sure the global init lock is initialized and then lock it. */ +#ifdef LIBXML_THREAD_ENABLED #ifdef HAVE_PTHREAD_H /* The mutex is statically initialized, so we just lock it. */ #ifdef XML_PTHREAD_WEAK @@ -496,11 +524,13 @@ __xmlGlobalInitMutexLock(void) #endif } #endif +#endif } void __xmlGlobalInitMutexUnlock(void) { +#ifdef LIBXML_THREAD_ENABLED #ifdef HAVE_PTHREAD_H #ifdef XML_PTHREAD_WEAK if (pthread_mutex_unlock == NULL) @@ -514,6 +544,7 @@ __xmlGlobalInitMutexUnlock(void) #elif defined HAVE_BEOS_THREADS release_sem(global_init_lock); #endif +#endif } /** @@ -525,6 +556,7 @@ __xmlGlobalInitMutexUnlock(void) void __xmlGlobalInitMutexDestroy(void) { +#ifdef LIBXML_THREAD_ENABLED #ifdef HAVE_PTHREAD_H #elif defined HAVE_WIN32_THREADS if (global_init_lock != NULL) { @@ -533,6 +565,7 @@ __xmlGlobalInitMutexDestroy(void) global_init_lock = NULL; } #endif +#endif } /************************************************************************ @@ -590,6 +623,8 @@ xmlNewGlobalState(void) } #endif /* LIBXML_THREAD_ENABLED */ +#ifdef LIBXML_THREAD_ENABLED + #ifdef HAVE_PTHREAD_H #elif defined HAVE_WIN32_THREADS #if !defined(HAVE_COMPILER_TLS) @@ -643,6 +678,8 @@ xmlGlobalStateCleanup(void *data) } #endif +#endif /* LIBXML_THREAD_ENABLED */ + /** * xmlGetGlobalState: * @@ -653,6 +690,7 @@ xmlGlobalStateCleanup(void *data) xmlGlobalStatePtr xmlGetGlobalState(void) { +#ifdef LIBXML_THREAD_ENABLED #ifdef HAVE_PTHREAD_H xmlGlobalState *globalval; @@ -743,6 +781,9 @@ xmlGetGlobalState(void) #else return (NULL); #endif +#else + return (NULL); +#endif } /************************************************************************ @@ -763,6 +804,7 @@ xmlGetGlobalState(void) int xmlGetThreadId(void) { +#ifdef LIBXML_THREAD_ENABLED #ifdef HAVE_PTHREAD_H pthread_t id; int ret; @@ -780,6 +822,9 @@ xmlGetThreadId(void) #else return ((int) 0); #endif +#else + return ((int) 0); +#endif } /** @@ -792,6 +837,7 @@ xmlGetThreadId(void) int xmlIsMainThread(void) { +#ifdef LIBXML_THREAD_ENABLED #ifdef HAVE_PTHREAD_H if (libxml_is_threaded == -1) xmlInitThreads(); @@ -816,6 +862,9 @@ xmlIsMainThread(void) #else return (1); #endif +#else + return (1); +#endif } /** @@ -857,6 +906,7 @@ xmlUnlockLibrary(void) void xmlInitThreads(void) { +#ifdef LIBXML_THREAD_ENABLED #ifdef HAVE_PTHREAD_H #ifdef XML_PTHREAD_WEAK if (libxml_is_threaded == -1) { @@ -888,6 +938,7 @@ xmlInitThreads(void) #elif defined(HAVE_WIN32_THREADS) && !defined(HAVE_COMPILER_TLS) && (!defined(LIBXML_STATIC) || defined(LIBXML_STATIC_FOR_DLL)) InitializeCriticalSection(&cleanup_helpers_cs); #endif +#endif } /** @@ -910,6 +961,7 @@ xmlCleanupThreads(void) #ifdef DEBUG_THREADS xmlGenericError(xmlGenericErrorContext, "xmlCleanupThreads()\n"); #endif +#ifdef LIBXML_THREAD_ENABLED #ifdef HAVE_PTHREAD_H if (libxml_is_threaded != 0) pthread_key_delete(globalkey); @@ -934,6 +986,7 @@ xmlCleanupThreads(void) } DeleteCriticalSection(&cleanup_helpers_cs); #endif +#endif } #ifdef LIBXML_THREAD_ENABLED