]> git.ipfire.org Git - thirdparty/gettext.git/commitdiff
Update after gnulib changed.
authorBruno Haible <bruno@clisp.org>
Wed, 3 Jul 2019 21:58:02 +0000 (23:58 +0200)
committerBruno Haible <bruno@clisp.org>
Mon, 13 Apr 2020 08:05:38 +0000 (10:05 +0200)
* 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.

18 files changed:
.gitignore
Makefile.am
autogen.sh
gettext-runtime/configure.ac
gettext-runtime/intl/Makefile.am
gettext-runtime/intl/flexmember.h
gettext-runtime/intl/localcharset.c
gettext-runtime/intl/lock.c
gettext-runtime/intl/lock.h
gettext-runtime/intl/windows-mutex.c [new file with mode: 0644]
gettext-runtime/intl/windows-mutex.h [new file with mode: 0644]
gettext-runtime/intl/windows-once.c [new file with mode: 0644]
gettext-runtime/intl/windows-once.h [new file with mode: 0644]
gettext-runtime/intl/windows-recmutex.c [new file with mode: 0644]
gettext-runtime/intl/windows-recmutex.h [new file with mode: 0644]
gettext-runtime/intl/windows-spinlock.h [new file with mode: 0644]
gettext-runtime/m4/flexmember.m4
gettext-tools/configure.ac

index e524b0f7cf106615627dc96159145cc0ca30ae0a..db259acf16066181ec507ba615c023bf1dd6757a 100644 (file)
 /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
index 8d180a99b105910c695ca7e64678161de0988212..5aeb7adf358cd4a6ea72346235ce0a43ed52e94a 100644 (file)
@@ -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
index 5c28b6fd33623f43bf5a6b1a4a9ecc9da43dadb4..c0ce815bab04d387119b19ec4c851f965b14d3b5 100755 (executable)
@@ -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
index de203e75805b68651fd55eeb10ee6977bdd9efbe..dd2ab902e8fc25b655f14aab4cae99354be03a1f 100644 (file)
@@ -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.
index 9f6e576f14232054204316b8402cb469eb8a5e4f..9cb70a1f5b97d9526a4c2fe24524ede6816b2903 100644 (file)
@@ -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
index e2ebe557e3f15cb5f7d1c304107179e7e8c5a25a..5a531726ef85e463a1bf51fb65904baabd3eb003 100644 (file)
@@ -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
 # 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) \
index e4f47f6c5beca60936de70a622de0547eee7e8d6..1989efb650597b1fe4ff6958591d0fe64ace017e 100644 (file)
@@ -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
 
index 7ee8010060a43c72e011d22933e8f203d5118432..ad2794baa00d43bfac257bbda79ca865db98e42e 100644 (file)
@@ -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
 
 /* ========================================================================= */
index 53350ecd50a2e4758b9de255dfda354b020fc3f8..e5cc1a606490c1c0ee6242c71b8ba1e5a1bbf6f7 100644 (file)
@@ -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
 #include <errno.h>
 #include <stdlib.h>
 
+#if !defined c11_threads_in_use
+# if HAVE_THREADS_H && (USE_POSIX_THREADS_WEAK || USE_PTH_THREADS_WEAK || USE_SOLARIS_THREADS_WEAK)
+#  include <threads.h>
+#  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 <windows.h>
 
+# 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 (file)
index 0000000..9c1f82a
--- /dev/null
@@ -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 <https://www.gnu.org/licenses/>.  */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2005.
+   Based on GCC's gthr-win32.h.  */
+
+#include <config.h>
+
+/* Specification.  */
+#include "windows-mutex.h"
+
+#include <errno.h>
+
+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 (file)
index 0000000..5a1b550
--- /dev/null
@@ -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 <https://www.gnu.org/licenses/>.  */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 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 <windows.h>
+
+#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 (file)
index 0000000..73315b1
--- /dev/null
@@ -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 <https://www.gnu.org/licenses/>.  */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2005.
+   Based on GCC's gthr-win32.h.  */
+
+#include <config.h>
+
+/* Specification.  */
+#include "windows-once.h"
+
+#include <stdlib.h>
+
+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 (file)
index 0000000..3beced4
--- /dev/null
@@ -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 <https://www.gnu.org/licenses/>.  */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 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 <windows.h>
+
+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 (file)
index 0000000..265fcbe
--- /dev/null
@@ -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 <https://www.gnu.org/licenses/>.  */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2005.
+   Based on GCC's gthr-win32.h.  */
+
+#include <config.h>
+
+/* Specification.  */
+#include "windows-recmutex.h"
+
+#include <errno.h>
+
+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 (file)
index 0000000..24eb12c
--- /dev/null
@@ -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 <https://www.gnu.org/licenses/>.  */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 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 <windows.h>
+
+#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 (file)
index 0000000..6f9cbe1
--- /dev/null
@@ -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 <https://www.gnu.org/licenses/>.  */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 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 <windows.h>
+
+typedef struct
+        {
+          volatile int done;
+          volatile LONG started;
+        }
+        glwthread_spinlock_t;
+
+#define GLWTHREAD_SPINLOCK_INIT { 0, -1 }
+
+#endif /* _WINDOWS_SPINLOCK_H */
index 1347068fe3c6fc01c158be8004aa213d547b0913..c245ab025f61eddc56a209f25a53ee38fad39e73 100644 (file)
@@ -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
index cf1dd734d782f27ff8d8ad2de18696f10861c373..6d8d752656aa9036b69550d07a48b17b4b415b17 100644 (file)
@@ -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.