summaryrefslogtreecommitdiff
path: root/libc/intl
diff options
context:
space:
mode:
authorjoseph <joseph@7b3dc134-2b1b-0410-93df-9e9f96275f8d>2007-09-25 15:22:16 +0000
committerjoseph <joseph@7b3dc134-2b1b-0410-93df-9e9f96275f8d>2007-09-25 15:22:16 +0000
commit39214d562d474c17d8242008f5454e9c9ca710ad (patch)
tree1c44f1babbdb5d368fc0e1032b4e9d013af2263a /libc/intl
parent9238710d492f92f0221bba03ee01c08ccbd6387c (diff)
Merge changes between r3467 and r3614 from /fsf/trunk.
git-svn-id: svn://svn.eglibc.org/trunk@3615 7b3dc134-2b1b-0410-93df-9e9f96275f8d
Diffstat (limited to 'libc/intl')
-rw-r--r--libc/intl/dcigettext.c35
-rw-r--r--libc/intl/gettextP.h1
-rw-r--r--libc/intl/loadmsgcat.c4
3 files changed, 35 insertions, 5 deletions
diff --git a/libc/intl/dcigettext.c b/libc/intl/dcigettext.c
index 767e43add..1d8ed919c 100644
--- a/libc/intl/dcigettext.c
+++ b/libc/intl/dcigettext.c
@@ -854,6 +854,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;
@@ -870,8 +873,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 =
@@ -880,9 +900,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;
@@ -891,7 +915,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;
@@ -993,6 +1017,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/libc/intl/gettextP.h b/libc/intl/gettextP.h
index f680a9a0a..f1aa329e4 100644
--- a/libc/intl/gettextP.h
+++ b/libc/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/libc/intl/loadmsgcat.c b/libc/intl/loadmsgcat.c
index 1c47475ec..537fd6013 100644
--- a/libc/intl/loadmsgcat.c
+++ b/libc/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);