diff options
author | Jakub Jelinek <jakub@redhat.com> | 2007-09-29 19:10:50 +0000 |
---|---|---|
committer | Jakub Jelinek <jakub@redhat.com> | 2007-09-29 19:10:50 +0000 |
commit | 441097af93882803bbb3296dd1fdbdd4a7773deb (patch) | |
tree | a221d657b763bcf793ea407fcd8b81d91ac06a5a /intl | |
parent | 62beba6902f315a14113c26ed3e068342e101399 (diff) | |
download | glibc-441097af93882803bbb3296dd1fdbdd4a7773deb.tar.gz glibc-441097af93882803bbb3296dd1fdbdd4a7773deb.tar.xz glibc-441097af93882803bbb3296dd1fdbdd4a7773deb.zip |
Updated to fedora-glibc-20070929T1859 cvs/fedora-glibc-2_6_90-16
Diffstat (limited to 'intl')
-rw-r--r-- | intl/dcigettext.c | 35 | ||||
-rw-r--r-- | intl/gettextP.h | 1 | ||||
-rw-r--r-- | intl/loadmsgcat.c | 4 |
3 files changed, 35 insertions, 5 deletions
diff --git a/intl/dcigettext.c b/intl/dcigettext.c index ad2835f930..55dcaabd80 100644 --- a/intl/dcigettext.c +++ b/intl/dcigettext.c @@ -850,6 +850,9 @@ _nl_find_msg (domain_file, domainbinding, msgid, convert, lengthp) /* We are supposed to do a conversion. */ const char *encoding = get_output_charset (domainbinding); + /* Protect against reallocation of the table. */ + __libc_rwlock_rdlock (domain->conversions_lock); + /* Search whether a table with converted translations for this encoding has already been allocated. */ size_t nconversions = domain->nconversions; @@ -866,8 +869,25 @@ _nl_find_msg (domain_file, domainbinding, msgid, convert, lengthp) } } + __libc_rwlock_unlock (domain->conversions_lock); + if (convd == NULL) { + /* We have to allocate a new conversions table. */ + __libc_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 = @@ -876,9 +896,13 @@ _nl_find_msg (domain_file, domainbinding, msgid, convert, lengthp) (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: + __libc_rwlock_unlock (domain->conversions_lock); + return (char *) -1; + } domain->conversions = new_conversions; @@ -887,7 +911,7 @@ _nl_find_msg (domain_file, domainbinding, msgid, convert, lengthp) 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; @@ -989,6 +1013,9 @@ _nl_find_msg (domain_file, domainbinding, msgid, convert, lengthp) convd->conv_tab = NULL; /* Here domain->conversions is still == new_conversions. */ domain->nconversions++; + + found_convd: + __libc_rwlock_unlock (domain->conversions_lock); } if ( diff --git a/intl/gettextP.h b/intl/gettextP.h index f680a9a0a1..f1aa329e47 100644 --- a/intl/gettextP.h +++ b/intl/gettextP.h @@ -147,6 +147,7 @@ struct loaded_domain /* Cache of charset conversions of the translated strings. */ struct converted_domain *conversions; size_t nconversions; + __libc_rwlock_define (, conversions_lock); const struct expression *plural; unsigned long int nplurals; diff --git a/intl/loadmsgcat.c b/intl/loadmsgcat.c index 1c47475ec6..537fd6013c 100644 --- a/intl/loadmsgcat.c +++ b/intl/loadmsgcat.c @@ -1,5 +1,5 @@ /* Load needed message catalogs. - Copyright (C) 1995-2005 Free Software Foundation, Inc. + Copyright (C) 1995-2005, 2007 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -1252,6 +1252,7 @@ _nl_load_domain (domain_file, domainbinding) /* No caches of converted translations so far. */ domain->conversions = NULL; domain->nconversions = 0; + __libc_rwlock_init (domain->conversions_lock); /* Get the header entry and look for a plural specification. */ nullentry = _nl_find_msg (domain_file, domainbinding, "", 0, &nullentrylen); @@ -1290,6 +1291,7 @@ _nl_unload_domain (domain) } if (domain->conversions != NULL) free (domain->conversions); + __libc_rwlock_fini (domain->conversions_lock); if (domain->malloced) free (domain->malloced); |