(root)/
glibc-2.38/
intl/
tst-gettext4.c
       1  /* Test that gettext() in multithreaded applications works correctly if
       2     different threads operate in different locales with the same encoding.
       3     Copyright (C) 2005-2023 Free Software Foundation, Inc.
       4     This file is part of the GNU C Library.
       5  
       6     The GNU C Library is free software; you can redistribute it and/or
       7     modify it under the terms of the GNU Lesser General Public
       8     License as published by the Free Software Foundation; either
       9     version 2.1 of the License, or (at your option) any later version.
      10  
      11     The GNU C Library is distributed in the hope that it will be useful,
      12     but WITHOUT ANY WARRANTY; without even the implied warranty of
      13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      14     Lesser General Public License for more details.
      15  
      16     You should have received a copy of the GNU Lesser General Public
      17     License along with the GNU C Library; if not, see
      18     <https://www.gnu.org/licenses/>.  */
      19  
      20  #include <libintl.h>
      21  #include <locale.h>
      22  #include <pthread.h>
      23  #include <stdio.h>
      24  #include <stdlib.h>
      25  #include <string.h>
      26  
      27  /* Set to 1 if the program is not behaving correctly.  */
      28  int result;
      29  
      30  /* Denotes which thread should run next.  */
      31  int flipflop;
      32  /* Lock and wait queue used to switch between the threads.  */
      33  pthread_mutex_t lock;
      34  pthread_cond_t waitqueue;
      35  
      36  /* Waits until the flipflop has a given value.
      37     Before the call, the lock is unlocked.  After the call, it is locked.  */
      38  static void
      39  waitfor (int value)
      40  {
      41    if (pthread_mutex_lock (&lock))
      42      exit (10);
      43    while (flipflop != value)
      44      if (pthread_cond_wait (&waitqueue, &lock))
      45        exit (11);
      46  }
      47  
      48  /* Sets the flipflop to a given value.
      49     Before the call, the lock is locked.  After the call, it is unlocked.  */
      50  static void
      51  setto (int value)
      52  {
      53    flipflop = value;
      54    if (pthread_cond_signal (&waitqueue))
      55      exit (20);
      56    if (pthread_mutex_unlock (&lock))
      57      exit (21);
      58  }
      59  
      60  void *
      61  thread1_execution (void *arg)
      62  {
      63    char *s;
      64  
      65    waitfor (1);
      66    uselocale (newlocale (LC_ALL_MASK, "de_DE.ISO-8859-1", NULL));
      67    setto (2);
      68  
      69    waitfor (1);
      70    s = gettext ("beauty");
      71    puts (s);
      72    if (strcmp (s, "Sch\366nheit"))
      73      {
      74        fprintf (stderr, "thread 1 call 1 returned: %s\n", s);
      75        result = 1;
      76      }
      77    setto (2);
      78  
      79    waitfor (1);
      80    s = gettext ("beauty");
      81    puts (s);
      82    if (strcmp (s, "Sch\366nheit"))
      83      {
      84        fprintf (stderr, "thread 1 call 2 returned: %s\n", s);
      85        result = 1;
      86      }
      87    setto (2);
      88  
      89    return NULL;
      90  }
      91  
      92  void *
      93  thread2_execution (void *arg)
      94  {
      95    char *s;
      96  
      97    waitfor (2);
      98    uselocale (newlocale (LC_ALL_MASK, "fr_FR.ISO-8859-1", NULL));
      99    setto (1);
     100  
     101    waitfor (2);
     102    s = gettext ("beauty");
     103    puts (s);
     104    if (strcmp (s, "beaut\351"))
     105      {
     106        fprintf (stderr, "thread 2 call 1 returned: %s\n", s);
     107        result = 1;
     108      }
     109    setto (1);
     110  
     111    waitfor (2);
     112    s = gettext ("beauty");
     113    puts (s);
     114    if (strcmp (s, "beaut\351"))
     115      {
     116        fprintf (stderr, "thread 2 call 2 returned: %s\n", s);
     117        result = 1;
     118      }
     119    setto (1);
     120  
     121    return NULL;
     122  }
     123  
     124  int
     125  main (void)
     126  {
     127    pthread_t thread1;
     128    pthread_t thread2;
     129  
     130    unsetenv ("LANGUAGE");
     131    unsetenv ("OUTPUT_CHARSET");
     132    textdomain ("multithread");
     133    bindtextdomain ("multithread", OBJPFX "domaindir");
     134    result = 0;
     135  
     136    flipflop = 1;
     137    if (pthread_mutex_init (&lock, NULL))
     138      exit (2);
     139    if (pthread_cond_init (&waitqueue, NULL))
     140      exit (2);
     141    if (pthread_create (&thread1, NULL, &thread1_execution, NULL))
     142      exit (2);
     143    if (pthread_create (&thread2, NULL, &thread2_execution, NULL))
     144      exit (2);
     145    if (pthread_join (thread2, NULL))
     146      exit (3);
     147  
     148    return result;
     149  }