From: Bruno Haible Date: Wed, 3 Jul 2019 21:58:02 +0000 (+0200) Subject: Update after gnulib changed. X-Git-Tag: v0.20.2~88 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d12084457b3bd3abe9fdda2b70a23718226c9280;p=thirdparty%2Fgettext.git Update after gnulib changed. * autogen.sh (GNULIB_MODULES_TOOLS_FOR_SRC_COMMON_DEPENDENCIES): Add windows-mutex, windows-once, windows-recmutex. * gettext-runtime/m4/flexmember.m4: Update from gnulib. * gettext-runtime/intl/flexmember.h: Likewise. * gettext-runtime/intl/localcharset.c: Likewise. * gettext-runtime/intl/windows-mutex.h: New file, from gnulib. * gettext-runtime/intl/windows-mutex.c: New file, from gnulib. * gettext-runtime/intl/windows-once.h: New file, from gnulib. * gettext-runtime/intl/windows-once.c: New file, from gnulib. * gettext-runtime/intl/windows-recmutex.h: New file, from gnulib. * gettext-runtime/intl/windows-recmutex.c: New file, from gnulib. * gettext-runtime/intl/windows-spinlock.h: New file, from gnulib. * gettext-runtime/intl/lock.h: Update from gnulib. * gettext-runtime/intl/lock.c: Likewise. * gettext-runtime/intl/Makefile.am (EXTRA_DIST): Add windows-*.h. (LIBINTLSOURCES): Conditionally add windows-*.c. (windows-mutex.lo, windows-recmutex.lo, windows-once.lo): New rules. (*.lo): Update dependencies. * gettext-runtime/configure.ac: New condition WINDOWS_NATIVE. * gettext-tools/configure.ac: Likewise. * Makefile.am (distcheck-hook): Check that gettext-runtime/intl/windows-*.[hc] are up-to-date. --- diff --git a/.gitignore b/.gitignore index e524b0f7c..db259acf1 100644 --- a/.gitignore +++ b/.gitignore @@ -239,6 +239,15 @@ /gettext-tools/libgettextpo/wctype-h.c /gettext-tools/libgettextpo/wctype.in.h /gettext-tools/libgettextpo/wcwidth.c +/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-tls.c +/gettext-tools/libgettextpo/windows-tls.h /gettext-tools/libgettextpo/xalloc-oversized.h /gettext-tools/libgettextpo/xalloc.h /gettext-tools/libgettextpo/xasprintf.c diff --git a/Makefile.am b/Makefile.am index 8d180a99b..5aeb7adf3 100644 --- a/Makefile.am +++ b/Makefile.am @@ -95,6 +95,13 @@ 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-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`" 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 5c28b6fd3..c0ce815ba 100755 --- a/autogen.sh +++ b/autogen.sh @@ -247,6 +247,9 @@ if ! $skip_gnulib; then verify wchar wctype-h + windows-mutex + windows-once + windows-recmutex ' GNULIB_MODULES_TOOLS_OTHER=' gettext-tools-misc diff --git a/gettext-runtime/configure.ac b/gettext-runtime/configure.ac index de203e758..dd2ab902e 100644 --- a/gettext-runtime/configure.ac +++ b/gettext-runtime/configure.ac @@ -84,6 +84,13 @@ case "$host_os" in esac AM_CONDITIONAL([WOE32], [test $is_woe32 = yes]) +dnl Some code is only meant to be compiled on native Windows. +case "$host_os" in + mingw*) is_windows_native=yes ;; + *) is_windows_native=no ;; +esac +AM_CONDITIONAL([WINDOWS_NATIVE], [test $is_windows_native = yes]) + dnl Checks for libraries. dnl These are the only lines required to internationalize the package. diff --git a/gettext-runtime/intl/Makefile.am b/gettext-runtime/intl/Makefile.am index 9f6e576f1..9cb70a1f5 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 \ + lock.h windows-spinlock.h windows-mutex.h windows-recmutex.h windows-once.h \ relocatable.h \ flexmember.h \ localename-table.in.h \ @@ -126,6 +126,12 @@ LIBINTLSOURCES = \ xsize.c \ osdep.c \ intl-compat.c +if WINDOWS_NATIVE +LIBINTLSOURCES += \ + windows-mutex.c \ + windows-recmutex.c \ + windows-once.c +endif # We must not install the libintl.h/libintl.la files if we are on a # system which has the GNU gettext() function in its C library or in a @@ -273,6 +279,12 @@ osdep.lo: $(srcdir)/osdep.c $(AM_V_CC)$(LTCOMPILE) -c -o $@ $(srcdir)/osdep.c 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-recmutex.lo: $(srcdir)/windows-recmutex.c + $(AM_V_CC)$(LTCOMPILE) -c -o $@ $(srcdir)/windows-recmutex.c +windows-once.lo: $(srcdir)/windows-once.c + $(AM_V_CC)$(LTCOMPILE) -c -o $@ $(srcdir)/windows-once.c # Dependencies. @@ -282,37 +294,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 -dcgettext.lo: ../config.h $(srcdir)/gettextP.h libgnuintl.h $(srcdir)/gmo.h $(srcdir)/loadinfo.h $(srcdir)/lock.h -dgettext.lo: ../config.h $(srcdir)/gettextP.h libgnuintl.h $(srcdir)/gmo.h $(srcdir)/loadinfo.h $(srcdir)/lock.h -gettext.lo: ../config.h $(srcdir)/gettextP.h libgnuintl.h $(srcdir)/gmo.h $(srcdir)/loadinfo.h $(srcdir)/lock.h -finddomain.lo: ../config.h $(srcdir)/gettextP.h libgnuintl.h $(srcdir)/gmo.h $(srcdir)/loadinfo.h $(srcdir)/lock.h +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 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)/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)/relocatable.h -textdomain.lo: ../config.h $(srcdir)/gettextP.h libgnuintl.h $(srcdir)/gmo.h $(srcdir)/loadinfo.h $(srcdir)/lock.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 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)/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 -dngettext.lo: ../config.h $(srcdir)/gettextP.h libgnuintl.h $(srcdir)/gmo.h $(srcdir)/loadinfo.h $(srcdir)/lock.h -ngettext.lo: ../config.h $(srcdir)/gettextP.h libgnuintl.h $(srcdir)/gmo.h $(srcdir)/loadinfo.h $(srcdir)/lock.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 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 +lock.lo: ../config.h $(srcdir)/lock.h $(srcdir)/windows-spinlock.h $(srcdir)/windows-mutex.h $(srcdir)/windows-recmutex.h $(srcdir)/windows-once.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)/flexmember.h localename-table.h -localename-table.lo: ../config.h localename-table.h $(srcdir)/lock.h -log.lo: ../config.h $(srcdir)/lock.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 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 +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 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 +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 +windows-once.lo: ../config.h $(srcdir)/windows-once.h # Version information according to Woe32 conventions. EXTRA_DIST += libintl.rc diff --git a/gettext-runtime/intl/flexmember.h b/gettext-runtime/intl/flexmember.h index e2ebe557e..5a531726e 100644 --- a/gettext-runtime/intl/flexmember.h +++ b/gettext-runtime/intl/flexmember.h @@ -1,6 +1,6 @@ /* Sizes of structs with flexible array members. - Copyright 2016-2017 Free Software Foundation, Inc. + Copyright 2016-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 @@ -30,11 +30,26 @@ # define FLEXALIGNOF(type) _Alignof (type) #endif -/* Upper bound on the size of a struct of type TYPE with a flexible - array member named MEMBER that is followed by N bytes of other data. - This is not simply sizeof (TYPE) + N, since it may require - alignment on unusually picky C11 platforms, and - FLEXIBLE_ARRAY_MEMBER may be 1 on pre-C11 platforms. +/* Yield a properly aligned upper bound on the size of a struct of + type TYPE with a flexible array member named MEMBER that is + followed by N bytes of other data. The result is suitable as an + argument to malloc. For example: + + struct s { int n; char d[FLEXIBLE_ARRAY_MEMBER]; }; + struct s *p = malloc (FLEXSIZEOF (struct s, d, n * sizeof (char))); + + FLEXSIZEOF (TYPE, MEMBER, N) is not simply (sizeof (TYPE) + N), + since FLEXIBLE_ARRAY_MEMBER may be 1 on pre-C11 platforms. Nor is + it simply (offsetof (TYPE, MEMBER) + N), as that might yield a size + that causes malloc to yield a pointer that is not properly aligned + for TYPE; for example, if sizeof (int) == alignof (int) == 4, + malloc (offsetof (struct s, d) + 3 * sizeof (char)) is equivalent + to malloc (7) and might yield a pointer that is not a multiple of 4 + (which means the pointer is not properly aligned for struct s), + whereas malloc (FLEXSIZEOF (struct s, d, 3 * sizeof (char))) is + equivalent to malloc (8) and must yield a pointer that is a + multiple of 4. + Yield a value less than N if and only if arithmetic overflow occurs. */ #define FLEXSIZEOF(type, member, n) \ diff --git a/gettext-runtime/intl/localcharset.c b/gettext-runtime/intl/localcharset.c index e4f47f6c5..1989efb65 100644 --- a/gettext-runtime/intl/localcharset.c +++ b/gettext-runtime/intl/localcharset.c @@ -1,6 +1,6 @@ /* Determine a canonical name for the current locale's character encoding. - Copyright (C) 2000-2006, 2008-2018 Free Software Foundation, Inc. + Copyright (C) 2000-2006, 2008-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 @@ -787,7 +787,12 @@ locale_charset (void) encoding is the best bet. */ sprintf (buf, "CP%u", GetACP ()); } - codeset = buf; + /* For a locale name such as "French_France.65001", in Windows 10, + setlocale now returns "French_France.utf8" instead. */ + if (strcmp (buf + 2, "65001") == 0 || strcmp (buf + 2, "utf8") == 0) + codeset = "UTF-8"; + else + codeset = buf; # elif defined OS2 diff --git a/gettext-runtime/intl/lock.c b/gettext-runtime/intl/lock.c index 7ee801006..ad2794baa 100644 --- a/gettext-runtime/intl/lock.c +++ b/gettext-runtime/intl/lock.c @@ -1,5 +1,5 @@ /* Locking in multithreaded situations. - Copyright (C) 2005-2008, 2012, 2017 Free Software Foundation, Inc. + Copyright (C) 2005-2008, 2012, 2017, 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 @@ -793,52 +793,6 @@ glthread_once_singlethreaded (gl_once_t *once_control) #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. */ @@ -951,10 +905,14 @@ glthread_rwlock_rdlock_func (gl_rwlock_t *lock) /* 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); + { + /* 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 @@ -1007,10 +965,14 @@ glthread_rwlock_wrlock_func (gl_rwlock_t *lock) /* 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); + { + /* 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. */ @@ -1111,111 +1073,6 @@ glthread_rwlock_destroy_func (gl_rwlock_t *lock) 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/gettext-runtime/intl/lock.h b/gettext-runtime/intl/lock.h index 53350ecd5..e5cc1a606 100644 --- a/gettext-runtime/intl/lock.h +++ b/gettext-runtime/intl/lock.h @@ -1,5 +1,5 @@ /* Locking in multithreaded situations. - Copyright (C) 2005-2008, 2015-2018 Free Software Foundation, Inc. + Copyright (C) 2005-2008, 2015-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 @@ -81,6 +81,16 @@ #include #include +#if !defined c11_threads_in_use +# if HAVE_THREADS_H && (USE_POSIX_THREADS_WEAK || USE_PTH_THREADS_WEAK || USE_SOLARIS_THREADS_WEAK) +# include +# pragma weak thrd_exit +# define c11_threads_in_use() (thrd_exit != NULL) +# else +# define c11_threads_in_use() 0 +# endif +#endif + /* ========================================================================= */ #if USE_POSIX_THREADS @@ -156,7 +166,8 @@ extern int glthread_in_use (void); pthread_rwlockattr_init */ # pragma weak pthread_mutexattr_gettype -# define pthread_in_use() (pthread_mutexattr_gettype != NULL) +# define pthread_in_use() \ + (pthread_mutexattr_gettype != NULL || c11_threads_in_use ()) # endif # else @@ -421,7 +432,7 @@ extern "C" { # pragma weak pth_cond_notify # pragma weak pth_cancel -# define pth_in_use() (pth_cancel != NULL) +# define pth_in_use() (pth_cancel != NULL || c11_threads_in_use ()) # else @@ -572,7 +583,7 @@ extern "C" { # pragma weak thr_self # pragma weak thr_suspend -# define thread_in_use() (thr_suspend != NULL) +# define thread_in_use() (thr_suspend != NULL || c11_threads_in_use ()) # else @@ -679,6 +690,11 @@ extern int glthread_once_singlethreaded (gl_once_t *once_control); # define WIN32_LEAN_AND_MEAN /* avoid including junk */ # include +# include "windows-spinlock.h" +# include "windows-mutex.h" +# include "windows-recmutex.h" +# include "windows-once.h" + # ifdef __cplusplus extern "C" { # endif @@ -694,34 +710,23 @@ extern "C" { /* 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; +typedef glwthread_mutex_t 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 } } + GLWTHREAD_MUTEX_INIT # define glthread_lock_init(LOCK) \ - (glthread_lock_init_func (LOCK), 0) + (glwthread_mutex_init (LOCK), 0) # define glthread_lock_lock(LOCK) \ - glthread_lock_lock_func (LOCK) + glwthread_mutex_lock (LOCK) # define glthread_lock_unlock(LOCK) \ - glthread_lock_unlock_func (LOCK) + glwthread_mutex_unlock (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); + glwthread_mutex_destroy (LOCK) /* ------------------------- gl_rwlock_t datatype ------------------------- */ @@ -739,7 +744,7 @@ typedef struct gl_carray_waitqueue_t; typedef struct { - gl_spinlock_t guard; /* protects the initialization */ + 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 */ @@ -751,7 +756,7 @@ typedef struct # define gl_rwlock_define_initialized(STORAGECLASS, NAME) \ STORAGECLASS gl_rwlock_t NAME = gl_rwlock_initializer; # define gl_rwlock_initializer \ - { { 0, -1 } } + { GLWTHREAD_SPINLOCK_INIT } # define glthread_rwlock_init(LOCK) \ (glthread_rwlock_init_func (LOCK), 0) # define glthread_rwlock_rdlock(LOCK) \ @@ -770,51 +775,29 @@ 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; +typedef glwthread_recmutex_t 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 } + GLWTHREAD_RECMUTEX_INIT # define glthread_recursive_lock_init(LOCK) \ - (glthread_recursive_lock_init_func (LOCK), 0) + (glwthread_recmutex_init (LOCK), 0) # define glthread_recursive_lock_lock(LOCK) \ - glthread_recursive_lock_lock_func (LOCK) + glwthread_recmutex_lock (LOCK) # define glthread_recursive_lock_unlock(LOCK) \ - glthread_recursive_lock_unlock_func (LOCK) + glwthread_recmutex_unlock (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); + glwthread_recmutex_destroy (LOCK) /* -------------------------- gl_once_t datatype -------------------------- */ -typedef struct - { - volatile int inited; - volatile long started; - CRITICAL_SECTION lock; - } - gl_once_t; +typedef glwthread_once_t gl_once_t; # define gl_once_define(STORAGECLASS, NAME) \ - STORAGECLASS gl_once_t NAME = { -1, -1 }; + STORAGECLASS gl_once_t NAME = GLWTHREAD_ONCE_INIT; # 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)); + (glwthread_once (ONCE_CONTROL, INITFUNCTION), 0) # ifdef __cplusplus } diff --git a/gettext-runtime/intl/windows-mutex.c b/gettext-runtime/intl/windows-mutex.c new file mode 100644 index 000000000..9c1f82aab --- /dev/null +++ b/gettext-runtime/intl/windows-mutex.c @@ -0,0 +1,95 @@ +/* Plain mutexes (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-mutex.h" + +#include + +void +glwthread_mutex_init (glwthread_mutex_t *mutex) +{ + InitializeCriticalSection (&mutex->lock); + mutex->guard.done = 1; +} + +int +glwthread_mutex_lock (glwthread_mutex_t *mutex) +{ + if (!mutex->guard.done) + { + if (InterlockedIncrement (&mutex->guard.started) == 0) + /* This thread is the first one to need this mutex. Initialize it. */ + glwthread_mutex_init (mutex); + else + { + /* Don't let mutex->guard.started grow and wrap around. */ + InterlockedDecrement (&mutex->guard.started); + /* Yield the CPU while waiting for another thread to finish + initializing this mutex. */ + while (!mutex->guard.done) + Sleep (0); + } + } + EnterCriticalSection (&mutex->lock); + return 0; +} + +int +glwthread_mutex_trylock (glwthread_mutex_t *mutex) +{ + if (!mutex->guard.done) + { + if (InterlockedIncrement (&mutex->guard.started) == 0) + /* This thread is the first one to need this mutex. Initialize it. */ + glwthread_mutex_init (mutex); + else + { + /* Don't let mutex->guard.started grow and wrap around. */ + InterlockedDecrement (&mutex->guard.started); + /* Let another thread finish initializing this mutex, and let it also + lock this mutex. */ + return EBUSY; + } + } + if (!TryEnterCriticalSection (&mutex->lock)) + return EBUSY; + return 0; +} + +int +glwthread_mutex_unlock (glwthread_mutex_t *mutex) +{ + if (!mutex->guard.done) + return EINVAL; + LeaveCriticalSection (&mutex->lock); + return 0; +} + +int +glwthread_mutex_destroy (glwthread_mutex_t *mutex) +{ + if (!mutex->guard.done) + return EINVAL; + DeleteCriticalSection (&mutex->lock); + mutex->guard.done = 0; + return 0; +} diff --git a/gettext-runtime/intl/windows-mutex.h b/gettext-runtime/intl/windows-mutex.h new file mode 100644 index 000000000..5a1b5506b --- /dev/null +++ b/gettext-runtime/intl/windows-mutex.h @@ -0,0 +1,51 @@ +/* Plain mutexes (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_MUTEX_H +#define _WINDOWS_MUTEX_H + +#define WIN32_LEAN_AND_MEAN /* avoid including junk */ +#include + +#include "windows-spinlock.h" + +typedef struct + { + glwthread_spinlock_t guard; /* protects the initialization */ + CRITICAL_SECTION lock; + } + glwthread_mutex_t; + +#define GLWTHREAD_MUTEX_INIT { GLWTHREAD_SPINLOCK_INIT } + +#ifdef __cplusplus +extern "C" { +#endif + +extern void glwthread_mutex_init (glwthread_mutex_t *mutex); +extern int glwthread_mutex_lock (glwthread_mutex_t *mutex); +extern int glwthread_mutex_trylock (glwthread_mutex_t *mutex); +extern int glwthread_mutex_unlock (glwthread_mutex_t *mutex); +extern int glwthread_mutex_destroy (glwthread_mutex_t *mutex); + +#ifdef __cplusplus +} +#endif + +#endif /* _WINDOWS_MUTEX_H */ diff --git a/gettext-runtime/intl/windows-once.c b/gettext-runtime/intl/windows-once.c new file mode 100644 index 000000000..73315b12f --- /dev/null +++ b/gettext-runtime/intl/windows-once.c @@ -0,0 +1,62 @@ +/* Once-only control (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-once.h" + +#include + +void +glwthread_once (glwthread_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 + { + /* Don't let once_control->started grow and wrap around. */ + 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 (); + } + } + } +} diff --git a/gettext-runtime/intl/windows-once.h b/gettext-runtime/intl/windows-once.h new file mode 100644 index 000000000..3beced439 --- /dev/null +++ b/gettext-runtime/intl/windows-once.h @@ -0,0 +1,47 @@ +/* Once-only control (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_ONCE_H +#define _WINDOWS_ONCE_H + +#define WIN32_LEAN_AND_MEAN /* avoid including junk */ +#include + +typedef struct + { + volatile int inited; + volatile LONG started; + CRITICAL_SECTION lock; + } + glwthread_once_t; + +#define GLWTHREAD_ONCE_INIT { -1, -1 } + +#ifdef __cplusplus +extern "C" { +#endif + +extern void glwthread_once (glwthread_once_t *once_control, + void (*initfunction) (void)); + +#ifdef __cplusplus +} +#endif + +#endif /* _WINDOWS_ONCE_H */ diff --git a/gettext-runtime/intl/windows-recmutex.c b/gettext-runtime/intl/windows-recmutex.c new file mode 100644 index 000000000..265fcbeb3 --- /dev/null +++ b/gettext-runtime/intl/windows-recmutex.c @@ -0,0 +1,127 @@ +/* Plain recursive mutexes (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-recmutex.h" + +#include + +void +glwthread_recmutex_init (glwthread_recmutex_t *mutex) +{ + mutex->owner = 0; + mutex->depth = 0; + InitializeCriticalSection (&mutex->lock); + mutex->guard.done = 1; +} + +int +glwthread_recmutex_lock (glwthread_recmutex_t *mutex) +{ + if (!mutex->guard.done) + { + if (InterlockedIncrement (&mutex->guard.started) == 0) + /* This thread is the first one to need this mutex. Initialize it. */ + glwthread_recmutex_init (mutex); + else + { + /* Don't let mutex->guard.started grow and wrap around. */ + InterlockedDecrement (&mutex->guard.started); + /* Yield the CPU while waiting for another thread to finish + initializing this mutex. */ + while (!mutex->guard.done) + Sleep (0); + } + } + { + DWORD self = GetCurrentThreadId (); + if (mutex->owner != self) + { + EnterCriticalSection (&mutex->lock); + mutex->owner = self; + } + if (++(mutex->depth) == 0) /* wraparound? */ + { + mutex->depth--; + return EAGAIN; + } + } + return 0; +} + +int +glwthread_recmutex_trylock (glwthread_recmutex_t *mutex) +{ + if (!mutex->guard.done) + { + if (InterlockedIncrement (&mutex->guard.started) == 0) + /* This thread is the first one to need this mutex. Initialize it. */ + glwthread_recmutex_init (mutex); + else + { + /* Don't let mutex->guard.started grow and wrap around. */ + InterlockedDecrement (&mutex->guard.started); + /* Let another thread finish initializing this mutex, and let it also + lock this mutex. */ + return EBUSY; + } + } + { + DWORD self = GetCurrentThreadId (); + if (mutex->owner != self) + { + if (!TryEnterCriticalSection (&mutex->lock)) + return EBUSY; + mutex->owner = self; + } + if (++(mutex->depth) == 0) /* wraparound? */ + { + mutex->depth--; + return EAGAIN; + } + } + return 0; +} + +int +glwthread_recmutex_unlock (glwthread_recmutex_t *mutex) +{ + if (mutex->owner != GetCurrentThreadId ()) + return EPERM; + if (mutex->depth == 0) + return EINVAL; + if (--(mutex->depth) == 0) + { + mutex->owner = 0; + LeaveCriticalSection (&mutex->lock); + } + return 0; +} + +int +glwthread_recmutex_destroy (glwthread_recmutex_t *mutex) +{ + if (mutex->owner != 0) + return EBUSY; + DeleteCriticalSection (&mutex->lock); + mutex->guard.done = 0; + return 0; +} diff --git a/gettext-runtime/intl/windows-recmutex.h b/gettext-runtime/intl/windows-recmutex.h new file mode 100644 index 000000000..24eb12c1e --- /dev/null +++ b/gettext-runtime/intl/windows-recmutex.h @@ -0,0 +1,57 @@ +/* Plain recursive mutexes (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_RECMUTEX_H +#define _WINDOWS_RECMUTEX_H + +#define WIN32_LEAN_AND_MEAN /* avoid including junk */ +#include + +#include "windows-spinlock.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 + implement a recursive lock without this assumption. */ + +typedef struct + { + glwthread_spinlock_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 } + +#ifdef __cplusplus +extern "C" { +#endif + +extern void glwthread_recmutex_init (glwthread_recmutex_t *mutex); +extern int glwthread_recmutex_lock (glwthread_recmutex_t *mutex); +extern int glwthread_recmutex_trylock (glwthread_recmutex_t *mutex); +extern int glwthread_recmutex_unlock (glwthread_recmutex_t *mutex); +extern int glwthread_recmutex_destroy (glwthread_recmutex_t *mutex); + +#ifdef __cplusplus +} +#endif + +#endif /* _WINDOWS_RECMUTEX_H */ diff --git a/gettext-runtime/intl/windows-spinlock.h b/gettext-runtime/intl/windows-spinlock.h new file mode 100644 index 000000000..6f9cbe15b --- /dev/null +++ b/gettext-runtime/intl/windows-spinlock.h @@ -0,0 +1,35 @@ +/* Spinlocks (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_SPINLOCK_H +#define _WINDOWS_SPINLOCK_H + +#define WIN32_LEAN_AND_MEAN /* avoid including junk */ +#include + +typedef struct + { + volatile int done; + volatile LONG started; + } + glwthread_spinlock_t; + +#define GLWTHREAD_SPINLOCK_INIT { 0, -1 } + +#endif /* _WINDOWS_SPINLOCK_H */ diff --git a/gettext-runtime/m4/flexmember.m4 b/gettext-runtime/m4/flexmember.m4 index 1347068fe..c245ab025 100644 --- a/gettext-runtime/m4/flexmember.m4 +++ b/gettext-runtime/m4/flexmember.m4 @@ -34,12 +34,10 @@ AC_DEFUN([AC_C_FLEXIBLE_ARRAY_MEMBER], AC_DEFINE([FLEXIBLE_ARRAY_MEMBER], [], [Define to nothing if C supports flexible array members, and to 1 if it does not. That way, with a declaration like 'struct s - { int n; double d@<:@FLEXIBLE_ARRAY_MEMBER@:>@; };', the struct hack + { int n; short d@<:@FLEXIBLE_ARRAY_MEMBER@:>@; };', the struct hack can be used with pre-C99 compilers. - When computing the size of such an object, don't use 'sizeof (struct s)' - as it overestimates the size. Use 'offsetof (struct s, d)' instead. - Don't use 'offsetof (struct s, d@<:@0@:>@)', as this doesn't work with - MSVC and with C++ compilers.]) + Use 'FLEXSIZEOF (struct s, d, N * sizeof (short))' to calculate + the size in bytes of such a struct containing an N-element array.]) else AC_DEFINE([FLEXIBLE_ARRAY_MEMBER], [1]) fi diff --git a/gettext-tools/configure.ac b/gettext-tools/configure.ac index cf1dd734d..6d8d75265 100644 --- a/gettext-tools/configure.ac +++ b/gettext-tools/configure.ac @@ -102,6 +102,13 @@ esac AM_CONDITIONAL([WOE32], [test $special_makefile_rules = woe32]) AM_CONDITIONAL([OS2], [test $special_makefile_rules = os2]) +dnl Some code is only meant to be compiled on native Windows. +case "$host_os" in + mingw*) is_windows_native=yes ;; + *) is_windows_native=no ;; +esac +AM_CONDITIONAL([WINDOWS_NATIVE], [test $is_windows_native = yes]) + dnl On Cygwin 1.7.10-1 or later, error_* variables are defined in the dnl Cygwin DLL. To avoid any conflict with gettext DLLs, always link dnl to gnulib's error.c. See GETTEXTLIB_EXPORTS_FLAGS setting below.