mirror of
git://sourceware.org/git/glibc.git
synced 2024-11-21 01:12:26 +08:00
* sysdeps/i386/i686/memcmp.S: Move misplaced END.
2005-03-27 Bruno Haible <bruno@clisp.org> Make it possible for multiple threads to use gettext() in different locales. * intl/dcigettext.c (HAVE_PER_THREAD_LOCALE): New macro. (struct known_translation_t): If HAVE_PER_THREAD_LOCALE, add localename field. (transcmp): If HAVE_PER_THREAD_LOCALE, compare localename fields. (DCIGETTEXT): If HAVE_PER_THREAD_LOCALE, fill the localename field in search and newp. * intl/tst-gettext4.c: New file. * intl/tst-gettext4.sh: New file. * intl/tst-gettext4-de.po: New file. * intl/tst-gettext4-fr.po: New file. * intl/tst-gettext5.c: New file. * intl/tst-gettext5.sh: New file. * intl/Makefile (distribute): Add tst-gettext4.sh, tst-gettext4-de.po, tst-gettext4-fr.po, tst-gettext5.sh. (multithread-test-srcs): New variable. (test-srcs): Add its contents. (tests): Depend on tst-gettext4.out, tst-gettext5.out. (tst-gettext4.out, tst-gettext5.out): New rules. (CFLAGS-tst-gettext4.c, CFLAGS-tst-gettext5.c): New variables. Add rule for linking the multithread-test-srcs with the appropriate thread-library. 2005-04-28 Ulrich Drepper <drepper@redhat.com> * po/rw.po: New file. From translation team.
This commit is contained in:
parent
572028fa7e
commit
8406a53a25
33
ChangeLog
33
ChangeLog
@ -1,5 +1,38 @@
|
||||
2005-04-28 Ulrich Drepper <drepper@redhat.com>
|
||||
|
||||
* sysdeps/i386/i686/memcmp.S: Move misplaced END.
|
||||
|
||||
2005-03-27 Bruno Haible <bruno@clisp.org>
|
||||
|
||||
Make it possible for multiple threads to use gettext() in different
|
||||
locales.
|
||||
* intl/dcigettext.c (HAVE_PER_THREAD_LOCALE): New macro.
|
||||
(struct known_translation_t): If HAVE_PER_THREAD_LOCALE, add localename
|
||||
field.
|
||||
(transcmp): If HAVE_PER_THREAD_LOCALE, compare localename fields.
|
||||
(DCIGETTEXT): If HAVE_PER_THREAD_LOCALE, fill the localename field in
|
||||
search and newp.
|
||||
|
||||
* intl/tst-gettext4.c: New file.
|
||||
* intl/tst-gettext4.sh: New file.
|
||||
* intl/tst-gettext4-de.po: New file.
|
||||
* intl/tst-gettext4-fr.po: New file.
|
||||
* intl/tst-gettext5.c: New file.
|
||||
* intl/tst-gettext5.sh: New file.
|
||||
* intl/Makefile (distribute): Add tst-gettext4.sh, tst-gettext4-de.po,
|
||||
tst-gettext4-fr.po, tst-gettext5.sh.
|
||||
(multithread-test-srcs): New variable.
|
||||
(test-srcs): Add its contents.
|
||||
(tests): Depend on tst-gettext4.out, tst-gettext5.out.
|
||||
(tst-gettext4.out, tst-gettext5.out): New rules.
|
||||
(CFLAGS-tst-gettext4.c, CFLAGS-tst-gettext5.c): New variables.
|
||||
Add rule for linking the multithread-test-srcs with the appropriate
|
||||
thread-library.
|
||||
|
||||
2005-04-28 Ulrich Drepper <drepper@redhat.com>
|
||||
|
||||
* po/rw.po: New file. From translation team.
|
||||
|
||||
* scripts/config.guess: Update from upstream.
|
||||
* scripts/config.sub: Likewise.
|
||||
|
||||
|
@ -30,9 +30,17 @@ distribute = gmo.h gettextP.h hash-string.h loadinfo.h locale.alias \
|
||||
tst-translit.sh translit.po \
|
||||
tst-gettext2.sh tstlang1.po tstlang2.po \
|
||||
tst-codeset.sh tstcodeset.po \
|
||||
tst-gettext3.sh
|
||||
tst-gettext3.sh \
|
||||
tst-gettext4.sh tst-gettext4-de.po tst-gettext4-fr.po \
|
||||
tst-gettext5.sh
|
||||
|
||||
include ../Makeconfig
|
||||
|
||||
multithread-test-srcs := tst-gettext4 tst-gettext5
|
||||
test-srcs := tst-gettext tst-translit tst-gettext2 tst-codeset tst-gettext3
|
||||
ifeq ($(have-thread-library),yes)
|
||||
test-srcs += $(multithread-test-srcs)
|
||||
endif
|
||||
tests = tst-ngettext
|
||||
|
||||
before-compile = $(objpfx)msgs.h
|
||||
@ -42,8 +50,6 @@ install-others = $(inst_msgcatdir)/locale.alias
|
||||
generated = msgs.h mtrace-tst-gettext tst-gettext.mtrace
|
||||
generated-dirs := domaindir localedir
|
||||
|
||||
include ../Makeconfig
|
||||
|
||||
ifneq (no,$(BISON))
|
||||
plural.c: plural.y
|
||||
$(BISON) $(BISONFLAGS) $@ $^
|
||||
@ -60,6 +66,9 @@ ifeq (yes,$(build-shared))
|
||||
ifneq ($(strip $(MSGFMT)),:)
|
||||
tests: $(objpfx)tst-translit.out $(objpfx)tst-gettext2.out \
|
||||
$(objpfx)tst-codeset.out $(objpfx)tst-gettext3.out
|
||||
ifeq ($(have-thread-library),yes)
|
||||
tests: $(objpfx)tst-gettext4.out $(objpfx)tst-gettext5.out
|
||||
endif
|
||||
ifneq (no,$(PERL))
|
||||
tests: $(objpfx)mtrace-tst-gettext
|
||||
endif
|
||||
@ -77,6 +86,10 @@ $(objpfx)tst-codeset.out: tst-codeset.sh $(objpfx)tst-codeset
|
||||
$(SHELL) -e $< $(common-objpfx) $(common-objpfx)intl/
|
||||
$(objpfx)tst-gettext3.out: tst-gettext3.sh $(objpfx)tst-gettext3
|
||||
$(SHELL) -e $< $(common-objpfx) $(common-objpfx)intl/
|
||||
$(objpfx)tst-gettext4.out: tst-gettext4.sh $(objpfx)tst-gettext4
|
||||
$(SHELL) -e $< $(common-objpfx) $(common-objpfx)intl/
|
||||
$(objpfx)tst-gettext5.out: tst-gettext5.sh $(objpfx)tst-gettext5
|
||||
$(SHELL) -e $< $(common-objpfx) $(common-objpfx)intl/
|
||||
endif
|
||||
endif
|
||||
|
||||
@ -89,11 +102,26 @@ CFLAGS-tst-translit.c = -DOBJPFX=\"$(objpfx)\"
|
||||
CFLAGS-tst-gettext2.c = -DOBJPFX=\"$(objpfx)\"
|
||||
CFLAGS-tst-codeset.c = -DOBJPFX=\"$(objpfx)\"
|
||||
CFLAGS-tst-gettext3.c = -DOBJPFX=\"$(objpfx)\"
|
||||
CFLAGS-tst-gettext4.c = -DOBJPFX=\"$(objpfx)\"
|
||||
CFLAGS-tst-gettext5.c = -DOBJPFX=\"$(objpfx)\"
|
||||
|
||||
ifeq ($(have-thread-library),yes)
|
||||
ifeq (yes,$(build-shared))
|
||||
$(addprefix $(objpfx),$(multithread-test-srcs)): $(shared-thread-library)
|
||||
else
|
||||
$(addprefix $(objpfx),$(multithread-test-srcs)): $(static-thread-library)
|
||||
endif
|
||||
ifeq (yes,$(build-bounded))
|
||||
$(multithread-test-srcs:%=$(objpfx)%-bp): $(bounded-thread-library)
|
||||
endif
|
||||
endif
|
||||
|
||||
$(objpfx)tst-translit.out: $(objpfx)tst-gettext.out
|
||||
$(objpfx)tst-gettext2.out: $(objpfx)tst-gettext.out
|
||||
$(objpfx)tst-codeset.out: $(objpfx)tst-gettext.out
|
||||
$(objpfx)tst-gettext3.out: $(objpfx)tst-gettext.out
|
||||
$(objpfx)tst-gettext4.out: $(objpfx)tst-gettext.out
|
||||
$(objpfx)tst-gettext5.out: $(objpfx)tst-gettext.out
|
||||
|
||||
CPPFLAGS += -D'LOCALEDIR="$(msgcatdir)"' \
|
||||
-D'LOCALE_ALIAS_PATH="$(msgcatdir)"'
|
||||
|
@ -172,6 +172,11 @@ static void *mempcpy PARAMS ((void *dest, const void *src, size_t n));
|
||||
# define PATH_MAX _POSIX_PATH_MAX
|
||||
#endif
|
||||
|
||||
/* Whether to support different locales in different threads. */
|
||||
#if defined _LIBC || HAVE_NL_LOCALE_NAME
|
||||
# define HAVE_PER_THREAD_LOCALE
|
||||
#endif
|
||||
|
||||
/* This is the type used for the search tree where known translations
|
||||
are stored. */
|
||||
struct known_translation_t
|
||||
@ -182,6 +187,11 @@ struct known_translation_t
|
||||
/* The category. */
|
||||
int category;
|
||||
|
||||
#ifdef HAVE_PER_THREAD_LOCALE
|
||||
/* Name of the relevant locale category, or "" for the global locale. */
|
||||
const char *localename;
|
||||
#endif
|
||||
|
||||
/* State of the catalog counter at the point the string was found. */
|
||||
int counter;
|
||||
|
||||
@ -226,10 +236,16 @@ transcmp (p1, p2)
|
||||
{
|
||||
result = strcmp (s1->domainname, s2->domainname);
|
||||
if (result == 0)
|
||||
/* We compare the category last (though this is the cheapest
|
||||
operation) since it is hopefully always the same (namely
|
||||
LC_MESSAGES). */
|
||||
result = s1->category - s2->category;
|
||||
{
|
||||
#ifdef HAVE_PER_THREAD_LOCALE
|
||||
result = strcmp (s1->localename, s2->localename);
|
||||
if (result == 0)
|
||||
#endif
|
||||
/* We compare the category last (though this is the cheapest
|
||||
operation) since it is hopefully always the same (namely
|
||||
LC_MESSAGES). */
|
||||
result = s1->category - s2->category;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
@ -408,6 +424,9 @@ DCIGETTEXT (domainname, msgid1, msgid2, plural, n, category)
|
||||
struct known_translation_t *search;
|
||||
struct known_translation_t **foundp = NULL;
|
||||
size_t msgid_len;
|
||||
# ifdef HAVE_PER_THREAD_LOCALE
|
||||
const char *localename;
|
||||
# endif
|
||||
#endif
|
||||
size_t domainname_len;
|
||||
|
||||
@ -442,6 +461,12 @@ DCIGETTEXT (domainname, msgid1, msgid2, plural, n, category)
|
||||
memcpy (search->msgid, msgid1, msgid_len);
|
||||
search->domainname = domainname;
|
||||
search->category = category;
|
||||
# ifdef HAVE_PER_THREAD_LOCALE
|
||||
# ifdef _LIBC
|
||||
localename = __current_locale_name (category);
|
||||
# endif
|
||||
search->localename = localename;
|
||||
# endif
|
||||
|
||||
/* Since tfind/tsearch manage a balanced tree, concurrent tfind and
|
||||
tsearch calls can be fatal. */
|
||||
@ -629,19 +654,33 @@ DCIGETTEXT (domainname, msgid1, msgid2, plural, n, category)
|
||||
if (foundp == NULL)
|
||||
{
|
||||
/* Create a new entry and add it to the search tree. */
|
||||
size_t size;
|
||||
struct known_translation_t *newp;
|
||||
|
||||
newp = (struct known_translation_t *)
|
||||
malloc (offsetof (struct known_translation_t, msgid)
|
||||
+ msgid_len + domainname_len + 1);
|
||||
size = offsetof (struct known_translation_t, msgid)
|
||||
+ msgid_len + domainname_len + 1;
|
||||
# ifdef HAVE_PER_THREAD_LOCALE
|
||||
size += strlen (localename) + 1;
|
||||
# endif
|
||||
newp = (struct known_translation_t *) malloc (size);
|
||||
if (newp != NULL)
|
||||
{
|
||||
char *new_domainname;
|
||||
# ifdef HAVE_PER_THREAD_LOCALE
|
||||
char *new_localename;
|
||||
# endif
|
||||
|
||||
new_domainname = mempcpy (newp->msgid, msgid1, msgid_len);
|
||||
memcpy (new_domainname, domainname, domainname_len + 1);
|
||||
# ifdef HAVE_PER_THREAD_LOCALE
|
||||
new_localename = new_domainname + domainname_len + 1;
|
||||
strcpy (new_localename, localename);
|
||||
# endif
|
||||
newp->domainname = new_domainname;
|
||||
newp->category = category;
|
||||
# ifdef HAVE_PER_THREAD_LOCALE
|
||||
newp->localename = new_localename;
|
||||
# endif
|
||||
newp->counter = _nl_msg_cat_cntr;
|
||||
newp->domain = domain;
|
||||
newp->translation = retval;
|
||||
|
8
intl/tst-gettext4-de.po
Normal file
8
intl/tst-gettext4-de.po
Normal file
@ -0,0 +1,8 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=ISO-8859-1\n"
|
||||
"Content-Transfer-Encoding: 8-bit\n"
|
||||
|
||||
msgid "beauty"
|
||||
msgstr "Schönheit"
|
8
intl/tst-gettext4-fr.po
Normal file
8
intl/tst-gettext4-fr.po
Normal file
@ -0,0 +1,8 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=ISO-8859-1\n"
|
||||
"Content-Transfer-Encoding: 8-bit\n"
|
||||
|
||||
msgid "beauty"
|
||||
msgstr "beauté"
|
151
intl/tst-gettext4.c
Normal file
151
intl/tst-gettext4.c
Normal file
@ -0,0 +1,151 @@
|
||||
/* Test that gettext() in multithreaded applications works correctly if
|
||||
different threads operate in different locales with the same encoding.
|
||||
Copyright (C) 2005 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Bruno Haible <bruno@clisp.org>, 2005.
|
||||
|
||||
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 <string.h>
|
||||
|
||||
/* Set to 1 if the program is not behaving correctly. */
|
||||
int result;
|
||||
|
||||
/* Denotes which thread should run next. */
|
||||
int flipflop;
|
||||
/* Lock and wait queue used to switch between the threads. */
|
||||
pthread_mutex_t lock;
|
||||
pthread_cond_t waitqueue;
|
||||
|
||||
/* Waits until the flipflop has a given value.
|
||||
Before the call, the lock is unlocked. After the call, it is locked. */
|
||||
static void
|
||||
waitfor (int value)
|
||||
{
|
||||
if (pthread_mutex_lock (&lock))
|
||||
exit (10);
|
||||
while (flipflop != value)
|
||||
if (pthread_cond_wait (&waitqueue, &lock))
|
||||
exit (11);
|
||||
}
|
||||
|
||||
/* Sets the flipflop to a given value.
|
||||
Before the call, the lock is locked. After the call, it is unlocked. */
|
||||
static void
|
||||
setto (int value)
|
||||
{
|
||||
flipflop = value;
|
||||
if (pthread_cond_signal (&waitqueue))
|
||||
exit (20);
|
||||
if (pthread_mutex_unlock (&lock))
|
||||
exit (21);
|
||||
}
|
||||
|
||||
void *
|
||||
thread1_execution (void *arg)
|
||||
{
|
||||
char *s;
|
||||
|
||||
waitfor (1);
|
||||
uselocale (newlocale (LC_ALL_MASK, "de_DE.ISO-8859-1", NULL));
|
||||
setto (2);
|
||||
|
||||
waitfor (1);
|
||||
s = gettext ("beauty");
|
||||
puts (s);
|
||||
if (strcmp (s, "Sch\366nheit"))
|
||||
{
|
||||
fprintf (stderr, "thread 1 call 1 returned: %s\n", s);
|
||||
result = 1;
|
||||
}
|
||||
setto (2);
|
||||
|
||||
waitfor (1);
|
||||
s = gettext ("beauty");
|
||||
puts (s);
|
||||
if (strcmp (s, "Sch\366nheit"))
|
||||
{
|
||||
fprintf (stderr, "thread 1 call 2 returned: %s\n", s);
|
||||
result = 1;
|
||||
}
|
||||
setto (2);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void *
|
||||
thread2_execution (void *arg)
|
||||
{
|
||||
char *s;
|
||||
|
||||
waitfor (2);
|
||||
uselocale (newlocale (LC_ALL_MASK, "fr_FR.ISO-8859-1", NULL));
|
||||
setto (1);
|
||||
|
||||
waitfor (2);
|
||||
s = gettext ("beauty");
|
||||
puts (s);
|
||||
if (strcmp (s, "beaut\351"))
|
||||
{
|
||||
fprintf (stderr, "thread 2 call 1 returned: %s\n", s);
|
||||
result = 1;
|
||||
}
|
||||
setto (1);
|
||||
|
||||
waitfor (2);
|
||||
s = gettext ("beauty");
|
||||
puts (s);
|
||||
if (strcmp (s, "beaut\351"))
|
||||
{
|
||||
fprintf (stderr, "thread 2 call 2 returned: %s\n", s);
|
||||
result = 1;
|
||||
}
|
||||
setto (1);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
pthread_t thread1;
|
||||
pthread_t thread2;
|
||||
|
||||
unsetenv ("LANGUAGE");
|
||||
unsetenv ("OUTPUT_CHARSET");
|
||||
textdomain ("multithread");
|
||||
bindtextdomain ("multithread", OBJPFX "domaindir");
|
||||
result = 0;
|
||||
|
||||
flipflop = 1;
|
||||
if (pthread_mutex_init (&lock, NULL))
|
||||
exit (2);
|
||||
if (pthread_cond_init (&waitqueue, NULL))
|
||||
exit (2);
|
||||
if (pthread_create (&thread1, NULL, &thread1_execution, NULL))
|
||||
exit (2);
|
||||
if (pthread_create (&thread2, NULL, &thread2_execution, NULL))
|
||||
exit (2);
|
||||
if (pthread_join (thread2, NULL))
|
||||
exit (3);
|
||||
|
||||
return result;
|
||||
}
|
48
intl/tst-gettext4.sh
Executable file
48
intl/tst-gettext4.sh
Executable file
@ -0,0 +1,48 @@
|
||||
#! /bin/sh
|
||||
# Test that gettext() in multithreaded applications works correctly if
|
||||
# different threads operate in different locales with the same encoding.
|
||||
# Copyright (C) 2001, 2002, 2005 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
|
||||
objpfx=$2
|
||||
|
||||
LC_ALL=C
|
||||
export LC_ALL
|
||||
|
||||
# Generate the test data.
|
||||
test -d ${objpfx}domaindir || mkdir ${objpfx}domaindir
|
||||
# Create the domain directories.
|
||||
test -d ${objpfx}domaindir/de_DE || mkdir ${objpfx}domaindir/de_DE
|
||||
test -d ${objpfx}domaindir/de_DE/LC_MESSAGES || mkdir ${objpfx}domaindir/de_DE/LC_MESSAGES
|
||||
test -d ${objpfx}domaindir/fr_FR || mkdir ${objpfx}domaindir/fr_FR
|
||||
test -d ${objpfx}domaindir/fr_FR/LC_MESSAGES || mkdir ${objpfx}domaindir/fr_FR/LC_MESSAGES
|
||||
# Populate them.
|
||||
msgfmt -o ${objpfx}domaindir/de_DE/LC_MESSAGES/multithread.mo tst-gettext4-de.po
|
||||
msgfmt -o ${objpfx}domaindir/fr_FR/LC_MESSAGES/multithread.mo tst-gettext4-fr.po
|
||||
|
||||
GCONV_PATH=${common_objpfx}iconvdata
|
||||
export GCONV_PATH
|
||||
LOCPATH=${common_objpfx}localedata
|
||||
export LOCPATH
|
||||
|
||||
${common_objpfx}elf/ld.so --library-path $common_objpfx \
|
||||
${objpfx}tst-gettext4 > ${objpfx}tst-gettext4.out
|
||||
|
||||
exit $?
|
156
intl/tst-gettext5.c
Normal file
156
intl/tst-gettext5.c
Normal file
@ -0,0 +1,156 @@
|
||||
/* Test that gettext() in multithreaded applications works correctly if
|
||||
different threads operate in different locales referring to the same
|
||||
catalog file but with different encodings.
|
||||
Copyright (C) 2005 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Bruno Haible <bruno@clisp.org>, 2005.
|
||||
|
||||
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 <string.h>
|
||||
|
||||
/* Set to 1 if the program is not behaving correctly. */
|
||||
int result;
|
||||
|
||||
/* Denotes which thread should run next. */
|
||||
int flipflop;
|
||||
/* Lock and wait queue used to switch between the threads. */
|
||||
pthread_mutex_t lock;
|
||||
pthread_cond_t waitqueue;
|
||||
|
||||
/* Waits until the flipflop has a given value.
|
||||
Before the call, the lock is unlocked. After the call, it is locked. */
|
||||
static void
|
||||
waitfor (int value)
|
||||
{
|
||||
if (pthread_mutex_lock (&lock))
|
||||
exit (10);
|
||||
while (flipflop != value)
|
||||
if (pthread_cond_wait (&waitqueue, &lock))
|
||||
exit (11);
|
||||
}
|
||||
|
||||
/* Sets the flipflop to a given value.
|
||||
Before the call, the lock is locked. After the call, it is unlocked. */
|
||||
static void
|
||||
setto (int value)
|
||||
{
|
||||
flipflop = value;
|
||||
if (pthread_cond_signal (&waitqueue))
|
||||
exit (20);
|
||||
if (pthread_mutex_unlock (&lock))
|
||||
exit (21);
|
||||
}
|
||||
|
||||
void *
|
||||
thread1_execution (void *arg)
|
||||
{
|
||||
char *s;
|
||||
|
||||
waitfor (1);
|
||||
uselocale (newlocale (LC_ALL_MASK, "de_DE.ISO-8859-1", NULL));
|
||||
setto (2);
|
||||
|
||||
/* Here we expect output in ISO-8859-1. */
|
||||
|
||||
waitfor (1);
|
||||
s = gettext ("cheese");
|
||||
puts (s);
|
||||
if (strcmp (s, "K\344se"))
|
||||
{
|
||||
fprintf (stderr, "thread 1 call 1 returned: %s\n", s);
|
||||
result = 1;
|
||||
}
|
||||
setto (2);
|
||||
|
||||
waitfor (1);
|
||||
s = gettext ("cheese");
|
||||
puts (s);
|
||||
if (strcmp (s, "K\344se"))
|
||||
{
|
||||
fprintf (stderr, "thread 1 call 2 returned: %s\n", s);
|
||||
result = 1;
|
||||
}
|
||||
setto (2);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void *
|
||||
thread2_execution (void *arg)
|
||||
{
|
||||
char *s;
|
||||
|
||||
waitfor (2);
|
||||
uselocale (newlocale (LC_ALL_MASK, "de_DE.UTF-8", NULL));
|
||||
setto (1);
|
||||
|
||||
/* Here we expect output in UTF-8. */
|
||||
|
||||
waitfor (2);
|
||||
s = gettext ("cheese");
|
||||
puts (s);
|
||||
if (strcmp (s, "K\303\244se"))
|
||||
{
|
||||
fprintf (stderr, "thread 2 call 1 returned: %s\n", s);
|
||||
result = 1;
|
||||
}
|
||||
setto (1);
|
||||
|
||||
waitfor (2);
|
||||
s = gettext ("cheese");
|
||||
puts (s);
|
||||
if (strcmp (s, "K\303\244se"))
|
||||
{
|
||||
fprintf (stderr, "thread 2 call 2 returned: %s\n", s);
|
||||
result = 1;
|
||||
}
|
||||
setto (1);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
pthread_t thread1;
|
||||
pthread_t thread2;
|
||||
|
||||
unsetenv ("LANGUAGE");
|
||||
unsetenv ("OUTPUT_CHARSET");
|
||||
textdomain ("codeset");
|
||||
bindtextdomain ("codeset", OBJPFX "domaindir");
|
||||
result = 0;
|
||||
|
||||
flipflop = 1;
|
||||
if (pthread_mutex_init (&lock, NULL))
|
||||
exit (2);
|
||||
if (pthread_cond_init (&waitqueue, NULL))
|
||||
exit (2);
|
||||
if (pthread_create (&thread1, NULL, &thread1_execution, NULL))
|
||||
exit (2);
|
||||
if (pthread_create (&thread2, NULL, &thread2_execution, NULL))
|
||||
exit (2);
|
||||
if (pthread_join (thread2, NULL))
|
||||
exit (3);
|
||||
|
||||
return result;
|
||||
}
|
46
intl/tst-gettext5.sh
Executable file
46
intl/tst-gettext5.sh
Executable file
@ -0,0 +1,46 @@
|
||||
#! /bin/sh
|
||||
# Test that gettext() in multithreaded applications works correctly if
|
||||
# different threads operate in different locales referring to the same
|
||||
# catalog file but with different encodings.
|
||||
# Copyright (C) 2001, 2002, 2005 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
|
||||
objpfx=$2
|
||||
|
||||
LC_ALL=C
|
||||
export LC_ALL
|
||||
|
||||
# Generate the test data.
|
||||
test -d ${objpfx}domaindir || mkdir ${objpfx}domaindir
|
||||
# Create the domain directories.
|
||||
test -d ${objpfx}domaindir/de_DE || mkdir ${objpfx}domaindir/de_DE
|
||||
test -d ${objpfx}domaindir/de_DE/LC_MESSAGES || mkdir ${objpfx}domaindir/de_DE/LC_MESSAGES
|
||||
# Populate them.
|
||||
msgfmt -o ${objpfx}domaindir/de_DE/LC_MESSAGES/codeset.mo tstcodeset.po
|
||||
|
||||
GCONV_PATH=${common_objpfx}iconvdata
|
||||
export GCONV_PATH
|
||||
LOCPATH=${common_objpfx}localedata
|
||||
export LOCPATH
|
||||
|
||||
${common_objpfx}elf/ld.so --library-path $common_objpfx \
|
||||
${objpfx}tst-gettext5 > ${objpfx}tst-gettext5.out
|
||||
|
||||
exit $?
|
@ -1,5 +1,5 @@
|
||||
/* Compare two memory blocks for differences in the first COUNT bytes.
|
||||
Copyright (C) 2004 Free Software Foundation, Inc.
|
||||
Copyright (C) 2004, 2005 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
|
||||
@ -350,6 +350,7 @@ L(set):
|
||||
sbbl $-1, %eax
|
||||
popl %esi
|
||||
RETURN
|
||||
END (BP_SYM (memcmp))
|
||||
|
||||
.section .rodata
|
||||
ALIGN (2)
|
||||
@ -387,7 +388,6 @@ L(table_32bytes) :
|
||||
.long L(30bytes) - . + 0x78
|
||||
.long L(31bytes) - . + 0x7c
|
||||
|
||||
END (BP_SYM (memcmp))
|
||||
|
||||
#undef bcmp
|
||||
weak_alias (BP_SYM (memcmp), BP_SYM (bcmp))
|
||||
|
Loading…
Reference in New Issue
Block a user