[BZ #5058]
authorUlrich Drepper <drepper@redhat.com>
Mon, 24 Sep 2007 16:09:09 +0000 (16:09 +0000)
committerUlrich Drepper <drepper@redhat.com>
Mon, 24 Sep 2007 16:09:09 +0000 (16:09 +0000)
2007-09-24  Ulrich Drepper  <drepper@redhat.com>
[BZ #5058]
* intl/gettextP.h (struct loaded_domain): Add conversions_lock member.
* intl/loadmsgcat.c (_nl_load_domain): Initialize conversions_lock.
(_nl_unload_domain): Finalize conversions_lock.
* intl/dcigettext.c (_nl_find_msg): Take conversions_lock before
handling table of known conversions.

* posix/regcomp.c (lookup_collation_sequence_value): Check that

ChangeLog
intl/dcigettext.c
intl/loadmsgcat.c

index 122201c..682c2e3 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2007-09-24  Ulrich Drepper  <drepper@redhat.com>
+
+       [BZ #5058]
+       * intl/gettextP.h (struct loaded_domain): Add conversions_lock member.
+       * intl/loadmsgcat.c (_nl_load_domain): Initialize conversions_lock.
+       (_nl_unload_domain): Finalize conversions_lock.
+       * intl/dcigettext.c (_nl_find_msg): Take conversions_lock before
+       handling table of known conversions.
+
 2007-09-24  Jakub Jelinek  <jakub@redhat.com>
 
        * sysdeps/posix/getaddrinfo.c (getaddrinfo): Use
@@ -6,7 +15,7 @@
 2007-09-13  Aurelien Jarno  <aurelien@aurel32.net>
 
        [BZ #5028]
-       * posix/regcomp.c (lookup_collation_sequence_value): check that
+       * posix/regcomp.c (lookup_collation_sequence_value): Check that
        nrules != 0 for multibyte chars.
 
 2007-09-23  Ulrich Drepper  <drepper@redhat.com>
index ad2835f..55dcaab 100644 (file)
@@ -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 (
index 1c47475..537fd60 100644 (file)
@@ -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);