mirror of
https://sourceware.org/git/glibc.git
synced 2024-11-22 04:50:07 +00:00
* intl/dcigettext.c (_nl_find_msg): Reread nconversions after
acquiring wrlock. Do conv_tab allocation while holding lock. * intl/Makefile: Add rules to build and run tst-gettext6. * intl/tst-gettext6.c: New test. * intl/tst-gettext6.sh: New file.
This commit is contained in:
parent
faa091c673
commit
2ecc7d93b8
@ -1,3 +1,11 @@
|
|||||||
|
2008-03-30 Jakub Jelinek <jakub@redhat.com>
|
||||||
|
|
||||||
|
* intl/dcigettext.c (_nl_find_msg): Reread nconversions after
|
||||||
|
acquiring wrlock. Do conv_tab allocation while holding lock.
|
||||||
|
* intl/Makefile: Add rules to build and run tst-gettext6.
|
||||||
|
* intl/tst-gettext6.c: New test.
|
||||||
|
* intl/tst-gettext6.sh: New file.
|
||||||
|
|
||||||
2008-03-30 Ulrich Drepper <drepper@redhat.com>
|
2008-03-30 Ulrich Drepper <drepper@redhat.com>
|
||||||
|
|
||||||
* po/nl.po: Update from translation team.
|
* po/nl.po: Update from translation team.
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
# Copyright (C) 1995-2003, 2005 Free Software Foundation, Inc.
|
# Copyright (C) 1995-2003, 2005, 2008 Free Software Foundation, Inc.
|
||||||
# This file is part of the GNU C Library.
|
# This file is part of the GNU C Library.
|
||||||
|
|
||||||
# The GNU C Library is free software; you can redistribute it and/or
|
# The GNU C Library is free software; you can redistribute it and/or
|
||||||
@ -32,11 +32,11 @@ distribute = gmo.h gettextP.h hash-string.h loadinfo.h locale.alias \
|
|||||||
tst-codeset.sh tstcodeset.po \
|
tst-codeset.sh tstcodeset.po \
|
||||||
tst-gettext3.sh \
|
tst-gettext3.sh \
|
||||||
tst-gettext4.sh tst-gettext4-de.po tst-gettext4-fr.po \
|
tst-gettext4.sh tst-gettext4-de.po tst-gettext4-fr.po \
|
||||||
tst-gettext5.sh
|
tst-gettext5.sh tst-gettext6.sh
|
||||||
|
|
||||||
include ../Makeconfig
|
include ../Makeconfig
|
||||||
|
|
||||||
multithread-test-srcs := tst-gettext4 tst-gettext5
|
multithread-test-srcs := tst-gettext4 tst-gettext5 tst-gettext6
|
||||||
test-srcs := tst-gettext tst-translit tst-gettext2 tst-codeset tst-gettext3
|
test-srcs := tst-gettext tst-translit tst-gettext2 tst-codeset tst-gettext3
|
||||||
ifeq ($(have-thread-library),yes)
|
ifeq ($(have-thread-library),yes)
|
||||||
test-srcs += $(multithread-test-srcs)
|
test-srcs += $(multithread-test-srcs)
|
||||||
@ -67,7 +67,8 @@ ifneq ($(strip $(MSGFMT)),:)
|
|||||||
tests: $(objpfx)tst-translit.out $(objpfx)tst-gettext2.out \
|
tests: $(objpfx)tst-translit.out $(objpfx)tst-gettext2.out \
|
||||||
$(objpfx)tst-codeset.out $(objpfx)tst-gettext3.out
|
$(objpfx)tst-codeset.out $(objpfx)tst-gettext3.out
|
||||||
ifeq ($(have-thread-library),yes)
|
ifeq ($(have-thread-library),yes)
|
||||||
tests: $(objpfx)tst-gettext4.out $(objpfx)tst-gettext5.out
|
tests: $(objpfx)tst-gettext4.out $(objpfx)tst-gettext5.out \
|
||||||
|
$(objpfx)tst-gettext6.out
|
||||||
endif
|
endif
|
||||||
ifneq (no,$(PERL))
|
ifneq (no,$(PERL))
|
||||||
tests: $(objpfx)mtrace-tst-gettext
|
tests: $(objpfx)mtrace-tst-gettext
|
||||||
@ -90,6 +91,8 @@ $(objpfx)tst-gettext4.out: tst-gettext4.sh $(objpfx)tst-gettext4
|
|||||||
$(SHELL) -e $< $(common-objpfx) '$(run-program-prefix)' $(common-objpfx)intl/
|
$(SHELL) -e $< $(common-objpfx) '$(run-program-prefix)' $(common-objpfx)intl/
|
||||||
$(objpfx)tst-gettext5.out: tst-gettext5.sh $(objpfx)tst-gettext5
|
$(objpfx)tst-gettext5.out: tst-gettext5.sh $(objpfx)tst-gettext5
|
||||||
$(SHELL) -e $< $(common-objpfx) '$(run-program-prefix)' $(common-objpfx)intl/
|
$(SHELL) -e $< $(common-objpfx) '$(run-program-prefix)' $(common-objpfx)intl/
|
||||||
|
$(objpfx)tst-gettext6.out: tst-gettext6.sh $(objpfx)tst-gettext6
|
||||||
|
$(SHELL) -e $< $(common-objpfx) '$(run-program-prefix)' $(common-objpfx)intl/
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
@ -104,6 +107,7 @@ CFLAGS-tst-codeset.c = -DOBJPFX=\"$(objpfx)\"
|
|||||||
CFLAGS-tst-gettext3.c = -DOBJPFX=\"$(objpfx)\"
|
CFLAGS-tst-gettext3.c = -DOBJPFX=\"$(objpfx)\"
|
||||||
CFLAGS-tst-gettext4.c = -DOBJPFX=\"$(objpfx)\"
|
CFLAGS-tst-gettext4.c = -DOBJPFX=\"$(objpfx)\"
|
||||||
CFLAGS-tst-gettext5.c = -DOBJPFX=\"$(objpfx)\"
|
CFLAGS-tst-gettext5.c = -DOBJPFX=\"$(objpfx)\"
|
||||||
|
CFLAGS-tst-gettext6.c = -DOBJPFX=\"$(objpfx)\"
|
||||||
|
|
||||||
ifeq ($(have-thread-library),yes)
|
ifeq ($(have-thread-library),yes)
|
||||||
ifeq (yes,$(build-shared))
|
ifeq (yes,$(build-shared))
|
||||||
@ -122,6 +126,7 @@ $(objpfx)tst-codeset.out: $(objpfx)tst-gettext.out
|
|||||||
$(objpfx)tst-gettext3.out: $(objpfx)tst-gettext.out
|
$(objpfx)tst-gettext3.out: $(objpfx)tst-gettext.out
|
||||||
$(objpfx)tst-gettext4.out: $(objpfx)tst-gettext.out
|
$(objpfx)tst-gettext4.out: $(objpfx)tst-gettext.out
|
||||||
$(objpfx)tst-gettext5.out: $(objpfx)tst-gettext.out
|
$(objpfx)tst-gettext5.out: $(objpfx)tst-gettext.out
|
||||||
|
$(objpfx)tst-gettext6.out: $(objpfx)tst-gettext.out
|
||||||
|
|
||||||
CPPFLAGS += -D'LOCALEDIR="$(msgcatdir)"' \
|
CPPFLAGS += -D'LOCALEDIR="$(msgcatdir)"' \
|
||||||
-D'LOCALE_ALIAS_PATH="$(msgcatdir)"'
|
-D'LOCALE_ALIAS_PATH="$(msgcatdir)"'
|
||||||
|
@ -879,6 +879,7 @@ _nl_find_msg (domain_file, domainbinding, msgid, convert, lengthp)
|
|||||||
{
|
{
|
||||||
/* We have to allocate a new conversions table. */
|
/* We have to allocate a new conversions table. */
|
||||||
__libc_rwlock_wrlock (domain->conversions_lock);
|
__libc_rwlock_wrlock (domain->conversions_lock);
|
||||||
|
nconversions = domain->nconversions;
|
||||||
|
|
||||||
/* Maybe in the meantime somebody added the translation.
|
/* Maybe in the meantime somebody added the translation.
|
||||||
Recheck. */
|
Recheck. */
|
||||||
@ -1033,6 +1034,7 @@ _nl_find_msg (domain_file, domainbinding, msgid, convert, lengthp)
|
|||||||
# endif
|
# endif
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
__libc_lock_define_initialized (static, lock)
|
||||||
/* We are supposed to do a conversion. First allocate an
|
/* We are supposed to do a conversion. First allocate an
|
||||||
appropriate table with the same structure as the table
|
appropriate table with the same structure as the table
|
||||||
of translations in the file, where we can put the pointers
|
of translations in the file, where we can put the pointers
|
||||||
@ -1042,13 +1044,21 @@ _nl_find_msg (domain_file, domainbinding, msgid, convert, lengthp)
|
|||||||
handle this case by converting RESULTLEN bytes, including
|
handle this case by converting RESULTLEN bytes, including
|
||||||
NULs. */
|
NULs. */
|
||||||
|
|
||||||
if (convd->conv_tab == NULL
|
if (__builtin_expect (convd->conv_tab == NULL, 0))
|
||||||
&& ((convd->conv_tab =
|
{
|
||||||
(char **) calloc (nstrings + domain->n_sysdep_strings,
|
__libc_lock_lock (lock);
|
||||||
sizeof (char *)))
|
if (convd->conv_tab == NULL)
|
||||||
== NULL))
|
{
|
||||||
|
convd->conv_tab
|
||||||
|
= calloc (nstrings + domain->n_sysdep_strings,
|
||||||
|
sizeof (char *));
|
||||||
|
if (convd->conv_tab != NULL)
|
||||||
|
goto not_translated_yet;
|
||||||
/* Mark that we didn't succeed allocating a table. */
|
/* Mark that we didn't succeed allocating a table. */
|
||||||
convd->conv_tab = (char **) -1;
|
convd->conv_tab = (char **) -1;
|
||||||
|
}
|
||||||
|
__libc_lock_unlock (lock);
|
||||||
|
}
|
||||||
|
|
||||||
if (__builtin_expect (convd->conv_tab == (char **) -1, 0))
|
if (__builtin_expect (convd->conv_tab == (char **) -1, 0))
|
||||||
/* Nothing we can do, no more memory. We cannot use the
|
/* Nothing we can do, no more memory. We cannot use the
|
||||||
@ -1057,12 +1067,14 @@ _nl_find_msg (domain_file, domainbinding, msgid, convert, lengthp)
|
|||||||
|
|
||||||
if (convd->conv_tab[act] == NULL)
|
if (convd->conv_tab[act] == NULL)
|
||||||
{
|
{
|
||||||
|
__libc_lock_lock (lock);
|
||||||
|
not_translated_yet:;
|
||||||
|
|
||||||
/* We haven't used this string so far, so it is not
|
/* We haven't used this string so far, so it is not
|
||||||
translated yet. Do this now. */
|
translated yet. Do this now. */
|
||||||
/* We use a bit more efficient memory handling.
|
/* We use a bit more efficient memory handling.
|
||||||
We allocate always larger blocks which get used over
|
We allocate always larger blocks which get used over
|
||||||
time. This is faster than many small allocations. */
|
time. This is faster than many small allocations. */
|
||||||
__libc_lock_define_initialized (static, lock)
|
|
||||||
# define INITIAL_BLOCK_SIZE 4080
|
# define INITIAL_BLOCK_SIZE 4080
|
||||||
static unsigned char *freemem;
|
static unsigned char *freemem;
|
||||||
static size_t freemem_size;
|
static size_t freemem_size;
|
||||||
@ -1074,8 +1086,6 @@ _nl_find_msg (domain_file, domainbinding, msgid, convert, lengthp)
|
|||||||
transmem_block_t *transmem_list = NULL;
|
transmem_block_t *transmem_list = NULL;
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
__libc_lock_lock (lock);
|
|
||||||
|
|
||||||
inbuf = (const unsigned char *) result;
|
inbuf = (const unsigned char *) result;
|
||||||
outbuf = freemem + sizeof (size_t);
|
outbuf = freemem + sizeof (size_t);
|
||||||
|
|
||||||
|
86
intl/tst-gettext6.c
Normal file
86
intl/tst-gettext6.c
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
/* Test that gettext() in multithreaded applications works correctly.
|
||||||
|
Copyright (C) 2008 Free Software Foundation, Inc.
|
||||||
|
This file is part of the GNU C Library.
|
||||||
|
Contributed by Jakub Jelinek <jakub@redhat.com>, 2008.
|
||||||
|
|
||||||
|
The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2.1 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
The GNU C Library is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public
|
||||||
|
License along with the GNU C Library; if not, write to the Free
|
||||||
|
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||||
|
02111-1307 USA. */
|
||||||
|
|
||||||
|
#include <libintl.h>
|
||||||
|
#include <locale.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
pthread_barrier_t b;
|
||||||
|
|
||||||
|
static void *
|
||||||
|
tf (void *arg)
|
||||||
|
{
|
||||||
|
pthread_barrier_wait (&b);
|
||||||
|
return gettext ("Operation not permitted");
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
test (void)
|
||||||
|
{
|
||||||
|
pthread_t th[4];
|
||||||
|
unsetenv ("LANGUAGE");
|
||||||
|
unsetenv ("OUTPUT_CHARSET");
|
||||||
|
textdomain ("tstgettext6");
|
||||||
|
bindtextdomain ("tstgettext6", OBJPFX "domaindir");
|
||||||
|
setlocale (LC_ALL, "ja_JP.UTF-8");
|
||||||
|
pthread_barrier_init (&b, NULL, 4);
|
||||||
|
for (int i = 0; i < 4; i++)
|
||||||
|
if (pthread_create (&th[i], NULL, tf, NULL))
|
||||||
|
{
|
||||||
|
puts ("pthread_create failed");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
for (int i = 0; i < 4; i++)
|
||||||
|
pthread_join (th[i], NULL);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main (void)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < 300; i++)
|
||||||
|
{
|
||||||
|
pid_t p = fork ();
|
||||||
|
if (p == -1)
|
||||||
|
{
|
||||||
|
printf ("fork failed: %m\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (p == 0)
|
||||||
|
_exit (test ());
|
||||||
|
int status;
|
||||||
|
wait (&status);
|
||||||
|
if (WIFEXITED (status) && WEXITSTATUS (status) != 0)
|
||||||
|
{
|
||||||
|
printf ("child exited with %d\n", WEXITSTATUS (status));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else if (WIFSIGNALED (status))
|
||||||
|
{
|
||||||
|
printf ("child killed by signal %d\n", WTERMSIG (status));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
41
intl/tst-gettext6.sh
Normal file
41
intl/tst-gettext6.sh
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
#! /bin/sh
|
||||||
|
# Test that gettext() in multithreaded applications works correctly.
|
||||||
|
# Copyright (C) 2008 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
|
||||||
|
# modify it under the terms of the GNU Lesser General Public
|
||||||
|
# License as published by the Free Software Foundation; either
|
||||||
|
# version 2.1 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
# The GNU C Library is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
# Lesser General Public License for more details.
|
||||||
|
|
||||||
|
# You should have received a copy of the GNU Lesser General Public
|
||||||
|
# License along with the GNU C Library; if not, write to the Free
|
||||||
|
# Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||||
|
# 02111-1307 USA.
|
||||||
|
|
||||||
|
common_objpfx=$1
|
||||||
|
run_program_prefix=$2
|
||||||
|
objpfx=$3
|
||||||
|
|
||||||
|
LC_ALL=C
|
||||||
|
export LC_ALL
|
||||||
|
|
||||||
|
# Create the domain directory.
|
||||||
|
mkdir -p ${objpfx}domaindir/ja_JP/LC_MESSAGES
|
||||||
|
# Populate it.
|
||||||
|
msgfmt -o ${objpfx}domaindir/ja_JP/LC_MESSAGES/tstgettext6.mo ../po/ja.po
|
||||||
|
|
||||||
|
GCONV_PATH=${common_objpfx}iconvdata
|
||||||
|
export GCONV_PATH
|
||||||
|
LOCPATH=${common_objpfx}localedata
|
||||||
|
export LOCPATH
|
||||||
|
|
||||||
|
${run_program_prefix} ${objpfx}tst-gettext6 > ${objpfx}tst-gettext6.out
|
||||||
|
|
||||||
|
exit $?
|
@ -133,7 +133,8 @@ LOCALES := de_DE.ISO-8859-1 de_DE.UTF-8 en_US.ANSI_X3.4-1968 \
|
|||||||
en_US.ISO-8859-1 ja_JP.EUC-JP da_DK.ISO-8859-1 \
|
en_US.ISO-8859-1 ja_JP.EUC-JP da_DK.ISO-8859-1 \
|
||||||
hr_HR.ISO-8859-2 sv_SE.ISO-8859-1 ja_JP.SJIS fr_FR.ISO-8859-1 \
|
hr_HR.ISO-8859-2 sv_SE.ISO-8859-1 ja_JP.SJIS fr_FR.ISO-8859-1 \
|
||||||
vi_VN.TCVN5712-1 nb_NO.ISO-8859-1 nn_NO.ISO-8859-1 \
|
vi_VN.TCVN5712-1 nb_NO.ISO-8859-1 nn_NO.ISO-8859-1 \
|
||||||
tr_TR.UTF-8 cs_CZ.UTF-8 zh_TW.EUC-TW fa_IR.UTF-8 fr_FR.UTF-8
|
tr_TR.UTF-8 cs_CZ.UTF-8 zh_TW.EUC-TW fa_IR.UTF-8 fr_FR.UTF-8 \
|
||||||
|
ja_JP.UTF-8
|
||||||
LOCALE_SRCS := $(shell echo "$(LOCALES)"|sed 's/\([^ .]*\)[^ ]*/\1/g')
|
LOCALE_SRCS := $(shell echo "$(LOCALES)"|sed 's/\([^ .]*\)[^ ]*/\1/g')
|
||||||
CHARMAPS := $(shell echo "$(LOCALES)" | \
|
CHARMAPS := $(shell echo "$(LOCALES)" | \
|
||||||
sed -e 's/[^ .]*[.]\([^ ]*\)/\1/g' -e s/SJIS/SHIFT_JIS/g)
|
sed -e 's/[^ .]*[.]\([^ ]*\)/\1/g' -e s/SJIS/SHIFT_JIS/g)
|
||||||
|
Loading…
Reference in New Issue
Block a user