This is the mail archive of the libc-alpha@sources.redhat.com mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Potential locking issue in newlocale


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]