This is the mail archive of the
libc-alpha@sources.redhat.com
mailing list for the glibc project.
Re: Potential locking issue in newlocale
- From: Jakub Jelinek <jakub at redhat dot com>
- To: Paolo Carlini <pcarlini at suse dot de>
- Cc: libc-alpha at sources dot redhat dot com, Ulrich dot Weigand at de dot ibm dot com, libstdc++ <libstdc++ at gcc dot gnu dot org>
- Date: Fri, 16 Jul 2004 12:28:02 +0200
- Subject: Re: Potential locking issue in newlocale
- References: <40F79EAB.1060107@suse.de> <20040716092207.GF30497@sunsite.ms.mff.cuni.cz>
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
Hi!
Actually, the previous rewrite into C was incomplete, here is a full rewrite
of all C/libpthread library calls with the exception of
malloc, free, strcpy, strlen, memcpy, memset, strchr, nl_langinfo_l, strcmp
which are either unrelated to the locale stuff, or in case of nl_langinfo_l
it is just querying of locale data and should not modify anything (nor use
locks).
#include <locale.h>
#include <pthread.h>
#include <wchar.h>
void *
tf (void *arg)
{
int n;
locale_t C = newlocale (LC_ALL_MASK, "C", NULL);
locale_t old = uselocale (C);
for (n = 0; n <= 127; ++n)
wctob ((wint_t) n);
for (n = 0; n <= 255; ++n)
btowc (n);
const char *types[] = { "upper", "lower", "alpha", "digit", "xdigit",
"space", "print", "cntrl", "punct" };
for (n = 0; n < 9; ++n)
wctype_l (types[n], C);
uselocale (old);
uselocale (C);
const char *dig = "-+xX0123456789abcdef0123456789ABCDEF-=xX0123456789abcdefABCDEF";
for (n = 0; n < strlen (dig); ++n)
btowc (dig[n]);
uselocale (old);
wcslen (L"true");
wcslen (L"false");
const char *dig2 = "-0123456789";
for (n = 0; n < strlen (dig2); ++n)
btowc (dig2[n]);
for (n = 0; n < strlen (dig2); ++n)
btowc (dig2[n]);
int i, j;
struct { locale_t l; locale_t d[10]; } s[10];
for (i = 0; i < 10; ++i)
{
locale_t l = newlocale (LC_ALL_MASK, (i & 1) ? "en_US" : "fr_FR",
NULL);
s[i].d[0] = duplocale (l);
s[i].d[1] = duplocale (l);
s[i].d[2] = duplocale (l);
s[i].d[3] = duplocale (l);
s[i].d[4] = duplocale (l);
s[i].d[5] = duplocale (l);
old = uselocale (s[i].d[5]);
for (n = 0; n <= 127; ++n)
wctob ((wint_t) n);
for (n = 0; n <= 255; ++n)
btowc (n);
for (n = 0; n < 9; ++n)
wctype_l (types[n], C);
uselocale (old);
s[i].d[6] = duplocale (l);
wcslen (L"true");
wcslen (L"false");
s[i].d[7] = duplocale (l);
old = uselocale (l);
wcslen (L"");
const char *m = "-";
wchar_t arr[7];
mbstate_t state;
memset (&state, 0, sizeof (state));
mbsrtowcs (arr, &m, 2, &state);
wcslen (arr);
m = (i & 1) ? "$" : "EUR";
mbsrtowcs (arr, &m, strlen (m), &state);
wcslen (arr);
uselocale (old);
uselocale (l);
wcslen (L"");
mbsrtowcs (arr, &m, 2, &state);
wcslen (arr);
m = (i & 1) ? "USD " : "EUR ";
mbsrtowcs (arr, &m, 5, &state);
wcslen (arr);
uselocale (old);
s[i].d[8] = duplocale (l);
s[i].d[9] = duplocale (l);
freelocale (l);
}
for (n = 0; n < 100000; ++n)
{
i = n % 11;
setlocale (LC_ALL, i == 10 ? "C" : ((i & 1) ? "en_US" : "fr_FR"));
if ((n % 37) == 0 && n > 0 && n <= 370)
freelocale (s[i - 1].d[0]);
}
for (i = 0; i < 10; ++i)
for (j = 1; j < 10; ++j)
freelocale (s[i].d[j]);
freelocale (C);
return NULL;
}
int
main ()
{
pthread_t pth[20];
int i;
for (i = 0; i < 20; ++i)
pthread_create (&pth[i], NULL, tf, NULL);
for (i = 0; i < 20; i++)
pthread_join (pth[i], NULL);
return 0;
}
Jakub