]> git.ipfire.org Git - thirdparty/gettext.git/commitdiff
2007-10-13 Bruno Haible <bruno@clisp.org>
authorBruno Haible <bruno@clisp.org>
Sat, 13 Oct 2007 16:28:12 +0000 (16:28 +0000)
committerBruno Haible <bruno@clisp.org>
Tue, 23 Jun 2009 10:15:17 +0000 (12:15 +0200)
From glibc: 2007-09-24  Ulrich Drepper  <drepper@redhat.com>

gettext-runtime/intl/ChangeLog
gettext-runtime/intl/dcigettext.c
gettext-runtime/intl/gettextP.h
gettext-runtime/intl/loadmsgcat.c

index 88ac1ac9fce5751a5160d76ed43f45e381aacf67..6cf9332705160613210d2d9b43df4d5f0074db87 100644 (file)
@@ -1,3 +1,20 @@
+2007-10-13  Bruno Haible  <bruno@clisp.org>
+
+       * gettextP.h: Include <bits/libc-lock.h> or lock.h.
+       * dcigettext.c (_nl_find_msg): Unlock the conversions_lock when
+       exiting.
+
+2007-09-24  Ulrich Drepper  <drepper@redhat.com>
+
+       [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  <jakub@redhat.com>
 
        * dcigettext.c (_nl_find_msg): Free encoding if __gconv_open failed.
index 289aab3085b4f69333c707850c86bbe8de00b7e9..6fc50c6075a9d6936568e1ea79b760c23f4cda9d 100644 (file)
@@ -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 (
index 8a464de4e7b2c04b2b044540dadc090f9c09cfae..5706fb505618dcc600ca501bc0652edf41fa9d84 100644 (file)
 # endif
 #endif
 
+/* Handle multi-threaded applications.  */
+#ifdef _LIBC
+# include <bits/libc-lock.h>
+# 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;
index ec766bc713978379b3061dc0645c7b9ed022a735..3432a8c1c9351da2d78be3916366bae7cd5c35b1 100644 (file)
@@ -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);