From: Bruno Haible Date: Fri, 27 May 2005 10:40:37 +0000 (+0000) Subject: Make libintl multithread-safe. X-Git-Tag: v0.15~510 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a23ee1fb190a57b21c18ebed2ee7bc8cbde3f944;p=thirdparty%2Fgettext.git Make libintl multithread-safe. --- diff --git a/gettext-runtime/intl/ChangeLog b/gettext-runtime/intl/ChangeLog index 17ba17634..9f3127546 100644 --- a/gettext-runtime/intl/ChangeLog +++ b/gettext-runtime/intl/ChangeLog @@ -1,3 +1,35 @@ +2005-05-05 Bruno Haible + + Make libintl multithread-safe outside glibc. + * bindtextdom.c: Include THREAD_H. + (__libc_rwlock_*): Define also for USE_POSIX_THREADS or + USE_PTH_THREADS. + * dcigettext.c: Include THREAD_H. + (__libc_lock_*, __libc_rwlock_*): Define also for USE_POSIX_THREADS or + USE_PTH_THREADS. + (_nl_state_lock): Define always. + (tree_lock): Define outside DCIGETTEXT. + (DCIGETTEXT): ... not here. + * finddomain.c: Include THREAD_H. + (__libc_rwlock_*): Define also for USE_POSIX_THREADS or + USE_PTH_THREADS. + * loadmsgcat.c: Include THREAD_H. + (__libc_lock_*_recursive): Define also for USE_POSIX_THREADS or + USE_PTH_THREADS. + (_nl_load_domain): Remove extraneous comma. + * localealias.c: Include THREAD_H. + (__libc_lock_*): Define also for USE_POSIX_THREADS or USE_PTH_THREADS. + (lock): Define always. + (_nl_expand_alias): Use lock always. + * textdomain.c: Include THREAD_H. + (__libc_rwlock_*): Define also for USE_POSIX_THREADS or + USE_PTH_THREADS. + * log.c: Include THREAD_H. + (__libc_lock_*): Define also for USE_POSIX_THREADS or USE_PTH_THREADS. + (last_logfilename, last_logfile, lock): New variables. + (_nl_log_untranslated_locked): Renamed from _nl_log_untranslated. + (_nl_log_untranslated): Rewritten. + 2005-02-16 Roland McGrath * dcigettext.c (_nl_find_msg): Add a cast. diff --git a/gettext-runtime/intl/bindtextdom.c b/gettext-runtime/intl/bindtextdom.c index 950698045..4c34f6176 100644 --- a/gettext-runtime/intl/bindtextdom.c +++ b/gettext-runtime/intl/bindtextdom.c @@ -31,14 +31,45 @@ #endif #include "gettextP.h" +/* Handle multi-threaded applications. */ +#ifdef THREAD_H +# include THREAD_H +#endif #ifdef _LIBC -/* We have to handle multi-threaded applications. */ # include #else -/* Provide dummy implementation if this is outside glibc. */ -# define __libc_rwlock_define(CLASS, NAME) -# define __libc_rwlock_wrlock(NAME) -# define __libc_rwlock_unlock(NAME) +# if USE_POSIX_THREADS +# define __libc_rwlock_define(CLASS, NAME) \ + CLASS pthread_rwlock_t NAME; +# define __libc_rwlock_define_initialized(CLASS, NAME) \ + CLASS pthread_rwlock_t NAME = PTHREAD_RWLOCK_INITIALIZER; +# define __libc_rwlock_rdlock(NAME) \ + if (pthread_rwlock_rdlock (&NAME) != 0) abort () +# define __libc_rwlock_wrlock(NAME) \ + if (pthread_rwlock_wrlock (&NAME) != 0) abort () +# define __libc_rwlock_unlock(NAME) \ + if (pthread_rwlock_unlock (&NAME) != 0) abort () +# else +# if USE_PTH_THREADS +# define __libc_rwlock_define(CLASS, NAME) \ + CLASS pth_rwlock_t NAME; +# define __libc_rwlock_define_initialized(CLASS, NAME) \ + CLASS pth_rwlock_t NAME = PTH_RWLOCK_INIT; +# define __libc_rwlock_rdlock(NAME) \ + if (!pth_rwlock_acquire (&NAME, PTH_RWLOCK_RD, 0, NULL)) abort () +# define __libc_rwlock_wrlock(NAME) \ + if (!pth_rwlock_acquire (&NAME, PTH_RWLOCK_RW, 0, NULL)) abort () +# define __libc_rwlock_unlock(NAME) \ + if (!pth_rwlock_release (&NAME)) abort () +# else +/* Provide dummy implementation if threads are not supported. */ +# define __libc_rwlock_define(CLASS, NAME) +# define __libc_rwlock_define_initialized(CLASS, NAME) +# define __libc_rwlock_rdlock(NAME) +# define __libc_rwlock_wrlock(NAME) +# define __libc_rwlock_unlock(NAME) +# endif +# endif #endif /* The internal variables in the standalone libintl.a must have different diff --git a/gettext-runtime/intl/dcigettext.c b/gettext-runtime/intl/dcigettext.c index c56ac3a10..5763cf38d 100644 --- a/gettext-runtime/intl/dcigettext.c +++ b/gettext-runtime/intl/dcigettext.c @@ -100,18 +100,65 @@ extern int errno; #endif #include "hash-string.h" -/* Thread safetyness. */ +/* Handle multi-threaded applications. */ +#ifdef THREAD_H +# include THREAD_H +#endif #ifdef _LIBC # include #else -/* Provide dummy implementation if this is outside glibc. */ -# define __libc_lock_define_initialized(CLASS, NAME) -# define __libc_lock_lock(NAME) -# define __libc_lock_unlock(NAME) -# define __libc_rwlock_define_initialized(CLASS, NAME) -# define __libc_rwlock_rdlock(NAME) -# define __libc_rwlock_wrlock(NAME) -# define __libc_rwlock_unlock(NAME) +# if USE_POSIX_THREADS +# define __libc_lock_define(CLASS, NAME) \ + CLASS pthread_mutex_t NAME; +# define __libc_lock_define_initialized(CLASS, NAME) \ + CLASS pthread_mutex_t NAME = PTHREAD_MUTEX_INITIALIZER; +# define __libc_lock_lock(NAME) \ + if (pthread_mutex_lock (&NAME) != 0) abort () +# define __libc_lock_unlock(NAME) \ + if (pthread_mutex_unlock (&NAME) != 0) abort () +# define __libc_rwlock_define(CLASS, NAME) \ + CLASS pthread_rwlock_t NAME; +# define __libc_rwlock_define_initialized(CLASS, NAME) \ + CLASS pthread_rwlock_t NAME = PTHREAD_RWLOCK_INITIALIZER; +# define __libc_rwlock_rdlock(NAME) \ + if (pthread_rwlock_rdlock (&NAME) != 0) abort () +# define __libc_rwlock_wrlock(NAME) \ + if (pthread_rwlock_wrlock (&NAME) != 0) abort () +# define __libc_rwlock_unlock(NAME) \ + if (pthread_rwlock_unlock (&NAME) != 0) abort () +# else +# if USE_PTH_THREADS +# define __libc_lock_define(CLASS, NAME) \ + CLASS pth_mutex_t NAME; +# define __libc_lock_define_initialized(CLASS, NAME) \ + CLASS pth_mutex_t NAME = PTH_MUTEX_INIT; +# define __libc_lock_lock(NAME) \ + if (!pth_mutex_acquire (&NAME, 0, NULL)) abort () +# define __libc_lock_unlock(NAME) \ + if (!pth_mutex_release (&NAME)) abort () +# define __libc_rwlock_define(CLASS, NAME) \ + CLASS pth_rwlock_t NAME; +# define __libc_rwlock_define_initialized(CLASS, NAME) \ + CLASS pth_rwlock_t NAME = PTH_RWLOCK_INIT; +# define __libc_rwlock_rdlock(NAME) \ + if (!pth_rwlock_acquire (&NAME, PTH_RWLOCK_RD, 0, NULL)) abort () +# define __libc_rwlock_wrlock(NAME) \ + if (!pth_rwlock_acquire (&NAME, PTH_RWLOCK_RW, 0, NULL)) abort () +# define __libc_rwlock_unlock(NAME) \ + if (!pth_rwlock_release (&NAME)) abort () +# else +/* Provide dummy implementation if threads are not supported. */ +# define __libc_lock_define(CLASS, NAME) +# define __libc_lock_define_initialized(CLASS, NAME) +# define __libc_lock_lock(NAME) +# define __libc_lock_unlock(NAME) +# define __libc_rwlock_define(CLASS, NAME) +# define __libc_rwlock_define_initialized(CLASS, NAME) +# define __libc_rwlock_rdlock(NAME) +# define __libc_rwlock_wrlock(NAME) +# define __libc_rwlock_unlock(NAME) +# endif +# endif #endif /* Alignment of types. */ @@ -260,6 +307,8 @@ struct known_translation_t #if defined HAVE_TSEARCH || defined _LIBC # include +__libc_rwlock_define_initialized (static, tree_lock); + static void *root; # ifdef _LIBC @@ -407,9 +456,7 @@ typedef unsigned char transmem_block_t; #endif /* Lock variable to protect the global data in the gettext implementation. */ -#ifdef _LIBC __libc_rwlock_define_initialized (, _nl_state_lock attribute_hidden) -#endif /* Checking whether the binaries runs SUID must be done and glibc provides easier methods therefore we make a difference here. */ @@ -536,7 +583,6 @@ DCIGETTEXT (const char *domainname, const char *msgid1, const char *msgid2, /* Since tfind/tsearch manage a balanced tree, concurrent tfind and tsearch calls can be fatal. */ - __libc_rwlock_define_initialized (static, tree_lock); __libc_rwlock_rdlock (tree_lock); foundp = (struct known_translation_t **) tfind (search, &root, transcmp); diff --git a/gettext-runtime/intl/finddomain.c b/gettext-runtime/intl/finddomain.c index 8523ea8bf..a7a024dcf 100644 --- a/gettext-runtime/intl/finddomain.c +++ b/gettext-runtime/intl/finddomain.c @@ -37,13 +37,45 @@ # include "libgnuintl.h" #endif +/* Handle multi-threaded applications. */ +#ifdef THREAD_H +# include THREAD_H +#endif #ifdef _LIBC # include #else -# define __libc_rwlock_define_initialized(CLASS, NAME) -# define __libc_rwlock_rdlock(NAME) -# define __libc_rwlock_wrlock(NAME) -# define __libc_rwlock_unlock(NAME) +# if USE_POSIX_THREADS +# define __libc_rwlock_define(CLASS, NAME) \ + CLASS pthread_rwlock_t NAME; +# define __libc_rwlock_define_initialized(CLASS, NAME) \ + CLASS pthread_rwlock_t NAME = PTHREAD_RWLOCK_INITIALIZER; +# define __libc_rwlock_rdlock(NAME) \ + if (pthread_rwlock_rdlock (&NAME) != 0) abort () +# define __libc_rwlock_wrlock(NAME) \ + if (pthread_rwlock_wrlock (&NAME) != 0) abort () +# define __libc_rwlock_unlock(NAME) \ + if (pthread_rwlock_unlock (&NAME) != 0) abort () +# else +# if USE_PTH_THREADS +# define __libc_rwlock_define(CLASS, NAME) \ + CLASS pth_rwlock_t NAME; +# define __libc_rwlock_define_initialized(CLASS, NAME) \ + CLASS pth_rwlock_t NAME = PTH_RWLOCK_INIT; +# define __libc_rwlock_rdlock(NAME) \ + if (!pth_rwlock_acquire (&NAME, PTH_RWLOCK_RD, 0, NULL)) abort () +# define __libc_rwlock_wrlock(NAME) \ + if (!pth_rwlock_acquire (&NAME, PTH_RWLOCK_RW, 0, NULL)) abort () +# define __libc_rwlock_unlock(NAME) \ + if (!pth_rwlock_release (&NAME)) abort () +# else +/* Provide dummy implementation if threads are not supported. */ +# define __libc_rwlock_define(CLASS, NAME) +# define __libc_rwlock_define_initialized(CLASS, NAME) +# define __libc_rwlock_rdlock(NAME) +# define __libc_rwlock_wrlock(NAME) +# define __libc_rwlock_unlock(NAME) +# endif +# endif #endif /* @@ end of prolog @@ */ diff --git a/gettext-runtime/intl/loadmsgcat.c b/gettext-runtime/intl/loadmsgcat.c index 26d0b87b1..babed6365 100644 --- a/gettext-runtime/intl/loadmsgcat.c +++ b/gettext-runtime/intl/loadmsgcat.c @@ -92,11 +92,67 @@ char *alloca (); #ifdef _LIBC # include "../locale/localeinfo.h" # include +#endif + +/* Handle multi-threaded applications. */ +#ifdef THREAD_H +# include THREAD_H +#endif +#ifdef _LIBC # include #else -# define __libc_lock_define_initialized_recursive(CLASS, NAME) -# define __libc_lock_lock_recursive(NAME) -# define __libc_lock_unlock_recursive(NAME) +# if USE_POSIX_THREADS +# define __libc_lock_define_recursive(CLASS, NAME) \ + CLASS pthread_mutex_t NAME; +# define __libc_lock_define_initialized_recursive(CLASS, NAME) \ + CLASS pthread_mutex_t NAME; \ + static pthread_mutex_t NAME##_aux = PTHREAD_MUTEX_INITIALIZER; \ + static int NAME##_initialized = 0; \ + auto int NAME##_dummy = \ + ((NAME##_initialized == 0 \ + ? mutex_init_recursive (&NAME, &NAME##_aux), NAME##_initialized = 1, 0 \ + : 0), NAME##_dummy); +static inline void +mutex_init_recursive (pthread_mutex_t *mutex, pthread_mutex_t *mutex_aux) +{ + pthread_mutexattr_t attributes; + + if (pthread_mutex_lock (mutex_aux) != 0) + abort (); + if (pthread_mutexattr_init (&attributes) != 0) + abort (); + if (pthread_mutexattr_settype (&attributes, PTHREAD_MUTEX_RECURSIVE) != 0) + abort (); + if (pthread_mutex_init (mutex, &attributes) != 0) + abort (); + if (pthread_mutexattr_destroy (&attributes) != 0) + abort (); + if (pthread_mutex_unlock (mutex_aux) != 0) + abort (); +} +# define __libc_lock_lock_recursive(NAME) \ + if (pthread_mutex_lock (&NAME) != 0) abort () +# define __libc_lock_unlock_recursive(NAME) \ + if (pthread_mutex_unlock (&NAME) != 0) abort () +# else +# if USE_PTH_THREADS + /* In Pth, mutexes are recursive by default. */ +# define __libc_lock_define_recursive(CLASS, NAME) \ + CLASS pth_mutex_t NAME; +# define __libc_lock_define_initialized_recursive(CLASS, NAME) \ + CLASS pth_mutex_t NAME = PTH_MUTEX_INIT; +# define __libc_lock_lock_recursive(NAME) \ + if (!pth_mutex_acquire (&NAME, 0, NULL)) abort () +# define __libc_lock_unlock_recursive(NAME) \ + if (!pth_mutex_release (&NAME)) abort () +# else +/* Provide dummy implementation if threads are not supported. */ +# define __libc_lock_define_recursive(CLASS, NAME) +# define __libc_lock_define_initialized_recursive(CLASS, NAME) +# define __libc_lock_lock_recursive(NAME) +# define __libc_lock_unlock_recursive(NAME) +# endif +# endif #endif /* Provide fallback values for macros that ought to be defined in . @@ -778,7 +834,7 @@ internal_function _nl_load_domain (struct loaded_l10nfile *domain_file, struct binding *domainbinding) { - __libc_lock_define_initialized_recursive (static, lock); + __libc_lock_define_initialized_recursive (static, lock) int fd = -1; size_t size; #ifdef _LIBC diff --git a/gettext-runtime/intl/localealias.c b/gettext-runtime/intl/localealias.c index de7fca496..6dfcc8bd8 100644 --- a/gettext-runtime/intl/localealias.c +++ b/gettext-runtime/intl/localealias.c @@ -81,11 +81,43 @@ char *alloca (); # endif # define HAVE_MEMPCPY 1 # define HAVE___FSETLOCKING 1 +#endif -/* We need locking here since we can be called from different places. */ +/* Handle multi-threaded applications. + We need locking here since we can be called from different places. */ +#ifdef THREAD_H +# include THREAD_H +#endif +#ifdef _LIBC # include - -__libc_lock_define_initialized (static, lock); +#else +# if USE_POSIX_THREADS +# define __libc_lock_define(CLASS, NAME) \ + CLASS pthread_mutex_t NAME; +# define __libc_lock_define_initialized(CLASS, NAME) \ + CLASS pthread_mutex_t NAME = PTHREAD_MUTEX_INITIALIZER; +# define __libc_lock_lock(NAME) \ + if (pthread_mutex_lock (&NAME) != 0) abort () +# define __libc_lock_unlock(NAME) \ + if (pthread_mutex_unlock (&NAME) != 0) abort () +# else +# if USE_PTH_THREADS +# define __libc_lock_define(CLASS, NAME) \ + CLASS pth_mutex_t NAME; +# define __libc_lock_define_initialized(CLASS, NAME) \ + CLASS pth_mutex_t NAME = PTH_MUTEX_INIT; +# define __libc_lock_lock(NAME) \ + if (!pth_mutex_acquire (&NAME, 0, NULL)) abort () +# define __libc_lock_unlock(NAME) \ + if (!pth_mutex_release (&NAME)) abort () +# else +/* Provide dummy implementation if threads are not supported. */ +# define __libc_lock_define(CLASS, NAME) +# define __libc_lock_define_initialized(CLASS, NAME) +# define __libc_lock_lock(NAME) +# define __libc_lock_unlock(NAME) +# endif +# endif #endif #ifndef internal_function @@ -120,6 +152,9 @@ __libc_lock_define_initialized (static, lock); #endif +__libc_lock_define_initialized (static, lock) + + struct alias_map { const char *alias; @@ -155,9 +190,7 @@ _nl_expand_alias (const char *name) const char *result = NULL; size_t added; -#ifdef _LIBC __libc_lock_lock (lock); -#endif if (locale_alias_path == NULL) locale_alias_path = LOCALE_ALIAS_PATH; @@ -204,9 +237,7 @@ _nl_expand_alias (const char *name) } while (added != 0); -#ifdef _LIBC __libc_lock_unlock (lock); -#endif return result; } diff --git a/gettext-runtime/intl/log.c b/gettext-runtime/intl/log.c index 89f82dfd1..92b4daba4 100644 --- a/gettext-runtime/intl/log.c +++ b/gettext-runtime/intl/log.c @@ -1,5 +1,5 @@ /* Log file output. - Copyright (C) 2003 Free Software Foundation, Inc. + Copyright (C) 2003, 2005 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published @@ -26,6 +26,38 @@ #include #include +/* Handle multi-threaded applications. */ +#ifdef THREAD_H +# include THREAD_H +#endif +#if USE_POSIX_THREADS +# define __libc_lock_define(CLASS, NAME) \ + CLASS pthread_mutex_t NAME; +# define __libc_lock_define_initialized(CLASS, NAME) \ + CLASS pthread_mutex_t NAME = PTHREAD_MUTEX_INITIALIZER; +# define __libc_lock_lock(NAME) \ + if (pthread_mutex_lock (&NAME) != 0) abort () +# define __libc_lock_unlock(NAME) \ + if (pthread_mutex_unlock (&NAME) != 0) abort () +#else +# if USE_PTH_THREADS +# define __libc_lock_define(CLASS, NAME) \ + CLASS pth_mutex_t NAME; +# define __libc_lock_define_initialized(CLASS, NAME) \ + CLASS pth_mutex_t NAME = PTH_MUTEX_INIT; +# define __libc_lock_lock(NAME) \ + if (!pth_mutex_acquire (&NAME, 0, NULL)) abort () +# define __libc_lock_unlock(NAME) \ + if (!pth_mutex_release (&NAME)) abort () +# else +/* Provide dummy implementation if threads are not supported. */ +# define __libc_lock_define(CLASS, NAME) +# define __libc_lock_define_initialized(CLASS, NAME) +# define __libc_lock_lock(NAME) +# define __libc_lock_unlock(NAME) +# endif +#endif + /* Print an ASCII string with quotes and escape sequences where needed. */ static void print_escaped (FILE *stream, const char *str) @@ -48,13 +80,14 @@ print_escaped (FILE *stream, const char *str) putc ('"', stream); } -/* Add to the log file an entry denoting a failed translation. */ -void -_nl_log_untranslated (const char *logfilename, const char *domainname, - const char *msgid1, const char *msgid2, int plural) +static char *last_logfilename = NULL; +static FILE *last_logfile = NULL; +__libc_lock_define_initialized (static, lock) + +static inline void +_nl_log_untranslated_locked (const char *logfilename, const char *domainname, + const char *msgid1, const char *msgid2, int plural) { - static char *last_logfilename = NULL; - static FILE *last_logfile = NULL; FILE *logfile; /* Can we reuse the last opened logfile? */ @@ -96,3 +129,13 @@ _nl_log_untranslated (const char *logfilename, const char *domainname, fprintf (logfile, "\nmsgstr \"\"\n"); putc ('\n', logfile); } + +/* Add to the log file an entry denoting a failed translation. */ +void +_nl_log_untranslated (const char *logfilename, const char *domainname, + const char *msgid1, const char *msgid2, int plural) +{ + __libc_lock_lock (lock); + _nl_log_untranslated_locked (logfilename, domainname, msgid1, msgid2, plural); + __libc_lock_unlock (lock); +} diff --git a/gettext-runtime/intl/textdomain.c b/gettext-runtime/intl/textdomain.c index 2bf62407d..d484df585 100644 --- a/gettext-runtime/intl/textdomain.c +++ b/gettext-runtime/intl/textdomain.c @@ -1,5 +1,5 @@ /* Implementation of the textdomain(3) function. - Copyright (C) 1995-1998, 2000-2003 Free Software Foundation, Inc. + Copyright (C) 1995-1998, 2000-2003, 2005 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published @@ -30,14 +30,45 @@ #endif #include "gettextP.h" +/* Handle multi-threaded applications. */ +#ifdef THREAD_H +# include THREAD_H +#endif #ifdef _LIBC -/* We have to handle multi-threaded applications. */ # include #else -/* Provide dummy implementation if this is outside glibc. */ -# define __libc_rwlock_define(CLASS, NAME) -# define __libc_rwlock_wrlock(NAME) -# define __libc_rwlock_unlock(NAME) +# if USE_POSIX_THREADS +# define __libc_rwlock_define(CLASS, NAME) \ + CLASS pthread_rwlock_t NAME; +# define __libc_rwlock_define_initialized(CLASS, NAME) \ + CLASS pthread_rwlock_t NAME = PTHREAD_RWLOCK_INITIALIZER; +# define __libc_rwlock_rdlock(NAME) \ + if (pthread_rwlock_rdlock (&NAME) != 0) abort () +# define __libc_rwlock_wrlock(NAME) \ + if (pthread_rwlock_wrlock (&NAME) != 0) abort () +# define __libc_rwlock_unlock(NAME) \ + if (pthread_rwlock_unlock (&NAME) != 0) abort () +# else +# if USE_PTH_THREADS +# define __libc_rwlock_define(CLASS, NAME) \ + CLASS pth_rwlock_t NAME; +# define __libc_rwlock_define_initialized(CLASS, NAME) \ + CLASS pth_rwlock_t NAME = PTH_RWLOCK_INIT; +# define __libc_rwlock_rdlock(NAME) \ + if (!pth_rwlock_acquire (&NAME, PTH_RWLOCK_RD, 0, NULL)) abort () +# define __libc_rwlock_wrlock(NAME) \ + if (!pth_rwlock_acquire (&NAME, PTH_RWLOCK_RW, 0, NULL)) abort () +# define __libc_rwlock_unlock(NAME) \ + if (!pth_rwlock_release (&NAME)) abort () +# else +/* Provide dummy implementation if threads are not supported. */ +# define __libc_rwlock_define(CLASS, NAME) +# define __libc_rwlock_define_initialized(CLASS, NAME) +# define __libc_rwlock_rdlock(NAME) +# define __libc_rwlock_wrlock(NAME) +# define __libc_rwlock_unlock(NAME) +# endif +# endif #endif /* The internal variables in the standalone libintl.a must have different diff --git a/gettext-runtime/m4/ChangeLog b/gettext-runtime/m4/ChangeLog index ed5eca42c..ad7638ca7 100644 --- a/gettext-runtime/m4/ChangeLog +++ b/gettext-runtime/m4/ChangeLog @@ -1,3 +1,9 @@ +2005-05-05 Bruno Haible + + * gettext.m4 (AM_GNU_GETTEXT): Add LIBTHREAD to LIBINTL and + LTLIBTHREAD to LTLIBINTL. + (AM_INTL_SUBDIR): Check for thread library. Set LIBTHREAD, LTLIBTHREAD. + 2005-03-13 Bruno Haible * po.m4 (AM_PO_SUBDIRS): Use AC_CONFIG_COMMANDS instead of diff --git a/gettext-runtime/m4/gettext.m4 b/gettext-runtime/m4/gettext.m4 index dc6274338..e42a8e327 100644 --- a/gettext-runtime/m4/gettext.m4 +++ b/gettext-runtime/m4/gettext.m4 @@ -1,4 +1,4 @@ -# gettext.m4 serial 39 (gettext-0.15) +# gettext.m4 serial 40 (gettext-0.15) dnl Copyright (C) 1995-2005 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -234,8 +234,8 @@ return * gettext ("")]ifelse([$2], [need-ngettext], [ + * ngettext ("", "", 0)], dnl Mark actions used to generate GNU NLS library. BUILD_INCLUDED_LIBINTL=yes USE_INCLUDED_LIBINTL=yes - LIBINTL="ifelse([$3],[],\${top_builddir}/intl,[$3])/libintl.[]gt_libtool_suffix_prefix[]a $LIBICONV" - LTLIBINTL="ifelse([$3],[],\${top_builddir}/intl,[$3])/libintl.[]gt_libtool_suffix_prefix[]a $LTLIBICONV" + LIBINTL="ifelse([$3],[],\${top_builddir}/intl,[$3])/libintl.[]gt_libtool_suffix_prefix[]a $LIBICONV $LIBTHREAD" + LTLIBINTL="ifelse([$3],[],\${top_builddir}/intl,[$3])/libintl.[]gt_libtool_suffix_prefix[]a $LTLIBICONV $LTLIBTHREAD" LIBS=`echo " $LIBS " | sed -e 's/ -lintl / /' -e 's/^ //' -e 's/ $//'` fi @@ -444,7 +444,7 @@ __fsetlocking]) gt_LC_MESSAGES fi - dnl glibc >= 2.4 has a NL_LOCALE_NAME macro when _GNU_SOUURCE is defined, + dnl glibc >= 2.4 has a NL_LOCALE_NAME macro when _GNU_SOURCE is defined, dnl and a _NL_LOCALE_NAME macro always. AC_CACHE_CHECK([for NL_LOCALE_NAME macro], gt_cv_nl_locale_name, [AC_TRY_LINK([#include ], @@ -454,9 +454,68 @@ __fsetlocking]) ]) if test $gt_cv_nl_locale_name = yes; then AC_DEFINE(HAVE_NL_LOCALE_NAME, 1, - [Define if you have and it defines the NL_LOCALE_NAME macro if _GNU_SOUURCE is defined.]) + [Define if you have and it defines the NL_LOCALE_NAME macro if _GNU_SOURCE is defined.]) fi + dnl Check for multithreading. + AC_ARG_ENABLE(threads, + AC_HELP_STRING([--disable-threads], [build without multithread safety]), + gt_use_threads=$enableval, gt_use_threads=yes) + LIBTHREAD= + LTLIBTHREAD= + if test "$gt_use_threads" != no; then + THREAD_H= + if test "$gt_use_threads" = yes || test "$gt_use_threads" = posix; then + AC_CHECK_HEADER(pthread.h, gt_have_pthread_h=yes, gt_have_pthread_h=no) + if test "$gt_have_pthread_h" = yes; then + # Other possible tests: + # compiler flag -pthread + # -lc_r (AIX, FreeBSD) + # -lpthreads (FSU threads, PCthreads) + # -lthread + # -lgthreads + gt_have_pthread= + if test -z "$gt_have_pthread"; then + AC_CHECK_LIB(pthread, pthread_self, + [gt_have_pthread=yes LIBTHREAD=-lpthread LTLIBTHREAD=-lpthread]) + fi + if test -n "$gt_have_pthread"; then + THREAD_H='' + CPPFLAGS="$CPPFLAGS -DUSE_POSIX_THREADS" + case "$host_os" in + # aix*) CPPFLAGS="$CPPFLAGS -D_THREAD_SAFE" ;; + # freebsd*) CPPFLAGS="$CPPFLAGS -D_THREAD_SAFE" ;; + # linux*) CPPFLAGS="$CPPFLAGS -D_REENTRANT" ;; + solaris*) CPPFLAGS="$CPPFLAGS -D_REENTRANT" ;; + esac + fi + fi + fi + if test "$gt_use_threads" = pth; then + gt_save_CPPFLAGS="$CPPFLAGS" + AC_LIB_LINKFLAGS(pth) + gt_have_pth= + gt_save_LIBS="$LIBS" + LIBS="$LIBS -lpth" + AC_TRY_LINK([#include ], [pth_self();], gt_have_pth=yes) + LIBS="$gt_save_LIBS" + if test -n "$gt_have_pth"; then + LIBTHREAD="$LIBPTH" + LTLIBTHREAD="$LTLIBPTH" + THREAD_H='' + CPPFLAGS="$CPPFLAGS -DUSE_PTH_THREADS" + else + CPPFLAGS="$gt_save_CPPFLAGS" + fi + fi + if test -n "$THREAD_H"; then + AC_DEFINE_UNQUOTED(THREAD_H, [$THREAD_H], + [Define to the header that declares multithreading facilities.]) + fi + fi + AC_SUBST(LIBTHREAD) + AC_SUBST(LTLIBTHREAD) + dnl intl/plural.c is generated from intl/plural.y. It requires bison, dnl because plural.y uses bison specific features. It requires at least dnl bison-1.26 because earlier versions generate a plural.c that doesn't diff --git a/gettext-tools/tests/ChangeLog b/gettext-tools/tests/ChangeLog index cb2e9a2d9..657305ae8 100644 --- a/gettext-tools/tests/ChangeLog +++ b/gettext-tools/tests/ChangeLog @@ -1,3 +1,7 @@ +2005-05-05 Bruno Haible + + * Makefile.am (LDADD_yes, LDADD_no): Add @LTLIBTHREAD@. + 2005-05-01 Bruno Haible * xgettext-sh-4: New file. diff --git a/gettext-tools/tests/Makefile.am b/gettext-tools/tests/Makefile.am index bd059f2ff..b1fee6a9a 100644 --- a/gettext-tools/tests/Makefile.am +++ b/gettext-tools/tests/Makefile.am @@ -171,8 +171,8 @@ DEFS = -DLOCALEDIR=\"$(localedir)\" @DEFS@ # INTL_MACOSX_LIBS is needed because the programs depend on libintl.la # but libtool doesn't put -Wl,-framework options into .la files. LDADD = $(LDADD_@USE_INCLUDED_LIBINTL@) @INTL_MACOSX_LIBS@ -LDADD_yes = ../intl/libintl.la -LDADD_no = ../intl/libgnuintl.la @LTLIBINTL@ +LDADD_yes = ../intl/libintl.la @LTLIBTHREAD@ +LDADD_no = ../intl/libgnuintl.la @LTLIBTHREAD@ @LTLIBINTL@ noinst_PROGRAMS = tstgettext tstngettext testlocale gettext-3-prg gettext-4-prg gettext-5-prg gettext-6-prg gettext-7-prg cake fc3 fc4 fc5 tstgettext_SOURCES = tstgettext.c setlocale.c tstgettext_CFLAGS = -DINSTALLDIR=\".\"