root/maint/gnulib/tests/test-setlocale_null-mt-all.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. thread1_func
  2. thread2_func
  3. main
  4. main

   1 /* Multithread-safety test for setlocale_null_r (LC_ALL, ...).
   2    Copyright (C) 2019-2021 Free Software Foundation, Inc.
   3 
   4    This program is free software: you can redistribute it and/or modify
   5    it under the terms of the GNU General Public License as published by
   6    the Free Software Foundation; either version 3 of the License, or
   7    (at your option) any later version.
   8 
   9    This program is distributed in the hope that it will be useful,
  10    but WITHOUT ANY WARRANTY; without even the implied warranty of
  11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12    GNU General Public License for more details.
  13 
  14    You should have received a copy of the GNU General Public License
  15    along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
  16 
  17 /* Written by Bruno Haible <bruno@clisp.org>, 2019.  */
  18 
  19 #include <config.h>
  20 
  21 /* Work around GCC bug 44511.  */
  22 #if 4 < __GNUC__ + (3 <= __GNUC_MINOR__)
  23 # pragma GCC diagnostic ignored "-Wreturn-type"
  24 #endif
  25 
  26 #if USE_ISOC_THREADS || USE_POSIX_THREADS || USE_ISOC_AND_POSIX_THREADS || USE_WINDOWS_THREADS
  27 
  28 /* Specification.  */
  29 #include <locale.h>
  30 
  31 #include <stdio.h>
  32 #include <stdlib.h>
  33 #include <string.h>
  34 #include <time.h>
  35 
  36 #include "glthread/thread.h"
  37 
  38 /* We want to use the system's setlocale() function here, not the gnulib
  39    override.  */
  40 #undef setlocale
  41 
  42 
  43 /* Some common locale names.  */
  44 
  45 #if defined _WIN32 && !defined __CYGWIN__
  46 # define ENGLISH "English_United States"
  47 # define GERMAN  "German_Germany"
  48 # define FRENCH  "French_France"
  49 # define ENCODING ".1252"
  50 #else
  51 # define ENGLISH "en_US"
  52 # define GERMAN  "de_DE"
  53 # define FRENCH  "fr_FR"
  54 # if defined __sgi
  55 #  define ENCODING ".ISO8859-15"
  56 # elif defined __hpux
  57 #  define ENCODING ".utf8"
  58 # else
  59 #  define ENCODING ".UTF-8"
  60 # endif
  61 #endif
  62 
  63 static const char LOCALE1[] = ENGLISH ENCODING;
  64 static const char LOCALE2[] = GERMAN ENCODING;
  65 static const char LOCALE3[] = FRENCH ENCODING;
  66 
  67 static char *expected;
  68 
  69 static void *
  70 thread1_func (void *arg)
     /* [previous][next][first][last][top][bottom][index][help] */
  71 {
  72   for (;;)
  73     {
  74       char buf[SETLOCALE_NULL_ALL_MAX];
  75 
  76       if (setlocale_null_r (LC_ALL, buf, sizeof (buf)))
  77         abort ();
  78       if (strcmp (expected, buf) != 0)
  79         {
  80           fprintf (stderr, "thread1 disturbed by thread2!\n"); fflush (stderr);
  81           abort ();
  82         }
  83     }
  84 
  85   /*NOTREACHED*/
  86 }
  87 
  88 static void *
  89 thread2_func (void *arg)
     /* [previous][next][first][last][top][bottom][index][help] */
  90 {
  91   for (;;)
  92     {
  93       char buf[SETLOCALE_NULL_ALL_MAX];
  94 
  95       setlocale_null_r (LC_NUMERIC, buf, sizeof (buf));
  96       setlocale_null_r (LC_ALL, buf, sizeof (buf));
  97     }
  98 
  99   /*NOTREACHED*/
 100 }
 101 
 102 int
 103 main (int argc, char *argv[])
     /* [previous][next][first][last][top][bottom][index][help] */
 104 {
 105   if (setlocale (LC_ALL, LOCALE1) == NULL)
 106     {
 107       fprintf (stderr, "Skipping test: LOCALE1 not recognized\n");
 108       return 77;
 109     }
 110   if (setlocale (LC_NUMERIC, LOCALE2) == NULL)
 111     {
 112       fprintf (stderr, "Skipping test: LOCALE2 not recognized\n");
 113       return 77;
 114     }
 115   if (setlocale (LC_TIME, LOCALE3) == NULL)
 116     {
 117       fprintf (stderr, "Skipping test: LOCALE3 not recognized\n");
 118       return 77;
 119     }
 120 
 121   expected = strdup (setlocale (LC_ALL, NULL));
 122 
 123   /* Create the two threads.  */
 124   gl_thread_create (thread1_func, NULL);
 125   gl_thread_create (thread2_func, NULL);
 126 
 127   /* Let them run for 5 seconds.  */
 128   {
 129     struct timespec duration;
 130     duration.tv_sec = 5;
 131     duration.tv_nsec = 0;
 132 
 133     nanosleep (&duration, NULL);
 134   }
 135 
 136   return 0;
 137 }
 138 
 139 #else
 140 
 141 /* No multithreading available.  */
 142 
 143 #include <stdio.h>
 144 
 145 int
 146 main ()
     /* [previous][next][first][last][top][bottom][index][help] */
 147 {
 148   fputs ("Skipping test: multithreading not enabled\n", stderr);
 149   return 77;
 150 }
 151 
 152 #endif
 153 
 154 /* Without locking, the results of this test would be:
 155 glibc                OK
 156 musl libc            crash < 10 sec
 157 macOS                crash < 1 sec
 158 FreeBSD              crash < 1 sec
 159 NetBSD               crash < 2 sec
 160 OpenBSD              crash < 1 sec
 161 AIX                  crash < 2 sec
 162 HP-UX                OK
 163 IRIX                 OK
 164 Solaris 10           OK
 165 Solaris 11.0         OK
 166 Solaris 11.4         OK
 167 Solaris OpenIndiana  OK
 168 Haiku                crash < 1 sec
 169 Cygwin               crash < 1 sec
 170 mingw                OK
 171 MSVC                 OK (assuming compiler option /MD !)
 172 */

/* [previous][next][first][last][top][bottom][index][help] */