+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.
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;
}
}
+ 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 =
: 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;
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;
if (__builtin_expect (r != __GCONV_NULCONV, 1))
{
free ((char *) encoding);
+ gl_rwlock_unlock (domain->conversions_lock);
return NULL;
}
convd->conv_tab = NULL;
/* Here domain->conversions is still == new_conversions. */
domain->nconversions++;
+
+ found_convd:
+ gl_rwlock_unlock (domain->conversions_lock);
}
if (
# 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);
/* 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;
/* 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
}
if (domain->conversions != NULL)
free (domain->conversions);
+ __libc_rwlock_fini (domain->conversions_lock);
if (domain->malloced)
free (domain->malloced);