From: Bruno Haible Date: Sat, 13 Oct 2007 16:28:12 +0000 (+0000) Subject: 2007-10-13 Bruno Haible X-Git-Tag: v0.17~134 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d66f54b9168c6d3122f4d83dcd1fb2d8132619d5;p=thirdparty%2Fgettext.git 2007-10-13 Bruno Haible From glibc: 2007-09-24 Ulrich Drepper --- diff --git a/gettext-runtime/intl/ChangeLog b/gettext-runtime/intl/ChangeLog index 88ac1ac9f..6cf933270 100644 --- a/gettext-runtime/intl/ChangeLog +++ b/gettext-runtime/intl/ChangeLog @@ -1,3 +1,20 @@ +2007-10-13 Bruno Haible + + * gettextP.h: Include or lock.h. + * dcigettext.c (_nl_find_msg): Unlock the conversions_lock when + exiting. + +2007-09-24 Ulrich Drepper + + [BZ #5058] + http://sourceware.org/bugzilla/show_bug.cgi?id=5058 + http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=443660 + * gettextP.h (struct loaded_domain): Add conversions_lock member. + * loadmsgcat.c (_nl_load_domain): Initialize conversions_lock. + (_nl_unload_domain): Finalize conversions_lock. + * dcigettext.c (_nl_find_msg): Take conversions_lock before handling + table of known conversions. + 2007-08-03 Jakub Jelinek * dcigettext.c (_nl_find_msg): Free encoding if __gconv_open failed. diff --git a/gettext-runtime/intl/dcigettext.c b/gettext-runtime/intl/dcigettext.c index 289aab308..6fc50c607 100644 --- a/gettext-runtime/intl/dcigettext.c +++ b/gettext-runtime/intl/dcigettext.c @@ -1002,6 +1002,9 @@ _nl_find_msg (struct loaded_l10nfile *domain_file, const char *encoding = get_output_charset (domainbinding); # endif + /* Protect against reallocation of the table. */ + gl_rwlock_rdlock (domain->conversions_lock); + /* Search whether a table with converted translations for this encoding has already been allocated. */ size_t nconversions = domain->nconversions; @@ -1018,8 +1021,25 @@ _nl_find_msg (struct loaded_l10nfile *domain_file, } } + gl_rwlock_unlock (domain->conversions_lock); + if (convd == NULL) { + /* We have to allocate a new conversions table. */ + gl_rwlock_wrlock (domain->conversions_lock); + + /* Maybe in the meantime somebody added the translation. + Recheck. */ + for (i = nconversions; i > 0; ) + { + i--; + if (strcmp (domain->conversions[i].encoding, encoding) == 0) + { + convd = &domain->conversions[i]; + goto found_convd; + } + } + /* Allocate a table for the converted translations for this encoding. */ struct converted_domain *new_conversions = @@ -1030,9 +1050,13 @@ _nl_find_msg (struct loaded_l10nfile *domain_file, : malloc ((nconversions + 1) * sizeof (struct converted_domain))); if (__builtin_expect (new_conversions == NULL, 0)) - /* Nothing we can do, no more memory. We cannot use the - translation because it might be encoded incorrectly. */ - return (char *) -1; + { + /* Nothing we can do, no more memory. We cannot use the + translation because it might be encoded incorrectly. */ + unlock_fail: + gl_rwlock_unlock (domain->conversions_lock); + return (char *) -1; + } domain->conversions = new_conversions; @@ -1041,7 +1065,7 @@ _nl_find_msg (struct loaded_l10nfile *domain_file, if (__builtin_expect (encoding == NULL, 0)) /* Nothing we can do, no more memory. We cannot use the translation because it might be encoded incorrectly. */ - return (char *) -1; + goto unlock_fail; convd = &new_conversions[nconversions]; convd->encoding = encoding; @@ -1111,6 +1135,7 @@ _nl_find_msg (struct loaded_l10nfile *domain_file, if (__builtin_expect (r != __GCONV_NULCONV, 1)) { free ((char *) encoding); + gl_rwlock_unlock (domain->conversions_lock); return NULL; } @@ -1149,6 +1174,9 @@ _nl_find_msg (struct loaded_l10nfile *domain_file, convd->conv_tab = NULL; /* Here domain->conversions is still == new_conversions. */ domain->nconversions++; + + found_convd: + gl_rwlock_unlock (domain->conversions_lock); } if ( diff --git a/gettext-runtime/intl/gettextP.h b/gettext-runtime/intl/gettextP.h index 8a464de4e..5706fb505 100644 --- a/gettext-runtime/intl/gettextP.h +++ b/gettext-runtime/intl/gettextP.h @@ -30,6 +30,14 @@ # endif #endif +/* Handle multi-threaded applications. */ +#ifdef _LIBC +# include +# define gl_rwlock_define __libc_rwlock_define +#else +# include "lock.h" +#endif + #ifdef _LIBC extern char *__gettext (const char *__msgid); extern char *__dgettext (const char *__domainname, const char *__msgid); @@ -185,6 +193,7 @@ struct loaded_domain /* Cache of charset conversions of the translated strings. */ struct converted_domain *conversions; size_t nconversions; + gl_rwlock_define (, conversions_lock) const struct expression *plural; unsigned long int nplurals; diff --git a/gettext-runtime/intl/loadmsgcat.c b/gettext-runtime/intl/loadmsgcat.c index ec766bc71..3432a8c1c 100644 --- a/gettext-runtime/intl/loadmsgcat.c +++ b/gettext-runtime/intl/loadmsgcat.c @@ -1275,6 +1275,7 @@ _nl_load_domain (struct loaded_l10nfile *domain_file, /* No caches of converted translations so far. */ domain->conversions = NULL; domain->nconversions = 0; + gl_rwlock_init (domain->conversions_lock); /* Get the header entry and look for a plural specification. */ #ifdef IN_LIBGLOCALE @@ -1318,6 +1319,7 @@ _nl_unload_domain (struct loaded_domain *domain) } if (domain->conversions != NULL) free (domain->conversions); + __libc_rwlock_fini (domain->conversions_lock); if (domain->malloced) free (domain->malloced);