root/maint/gnulib/tests/test-setlocale_null-mt-one.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_xxx, ...).
   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_MAX];
  75 
  76       if (setlocale_null_r (LC_NUMERIC, 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_MAX];
  94 
  95       setlocale_null_r (LC_NUMERIC, buf, sizeof (buf));
  96       setlocale_null_r (LC_TIME, 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_NUMERIC, 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 2 seconds.  */
 128   {
 129     struct timespec duration;
 130     duration.tv_sec = 2;
 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            OK
 157 macOS                OK
 158 FreeBSD              OK
 159 NetBSD               OK
 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                OK
 169 Cygwin               OK
 170 mingw                OK
 171 MSVC                 OK (assuming compiler option /MD !)
 172 */

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