root/maint/gnulib/lib/setlocale-lock.c

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

DEFINITIONS

This source file includes following definitions.
  1. gl_get_setlocale_null_lock
  2. gl_get_setlocale_null_lock
  3. atomic_init
  4. gl_get_setlocale_null_lock

   1 /* Return the internal lock used by setlocale_null_r.
   2    Copyright (C) 2019-2021 Free Software Foundation, Inc.
   3 
   4    This file is free software: you can redistribute it and/or modify
   5    it under the terms of the GNU Lesser General Public License as
   6    published by the Free Software Foundation; either version 2.1 of the
   7    License, or (at your option) any later version.
   8 
   9    This file 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 Lesser General Public License for more details.
  13 
  14    You should have received a copy of the GNU Lesser 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 /* When it is known that the gl_get_setlocale_null_lock function is defined
  22    by a dependency library, it should not be defined here.  */
  23 #if OMIT_SETLOCALE_LOCK
  24 
  25 /* This declaration is solely to ensure that after preprocessing
  26    this file is never empty.  */
  27 typedef int dummy;
  28 
  29 #else
  30 
  31 /* This file defines the internal lock used by setlocale_null_r.
  32    It is a separate compilation unit, so that only one copy of it is
  33    present when linking statically.  */
  34 
  35 /* Prohibit renaming this symbol.  */
  36 # undef gl_get_setlocale_null_lock
  37 
  38 /* Macro for exporting a symbol (function, not variable) defined in this file,
  39    when compiled into a shared library.  */
  40 # ifndef DLL_EXPORTED
  41 #  if HAVE_VISIBILITY
  42   /* Override the effect of the compiler option '-fvisibility=hidden'.  */
  43 #   define DLL_EXPORTED __attribute__((__visibility__("default")))
  44 #  elif defined _WIN32 || defined __CYGWIN__
  45 #   define DLL_EXPORTED __declspec(dllexport)
  46 #  else
  47 #   define DLL_EXPORTED
  48 #  endif
  49 # endif
  50 
  51 # if defined _WIN32 && !defined __CYGWIN__
  52 
  53 #  define WIN32_LEAN_AND_MEAN  /* avoid including junk */
  54 #  include <windows.h>
  55 
  56 #  include "windows-initguard.h"
  57 
  58 /* The return type is a 'CRITICAL_SECTION *', not a 'glwthread_mutex_t *',
  59    because the latter is not guaranteed to be a stable ABI in the future.  */
  60 
  61 /* Make sure the function gets exported from DLLs.  */
  62 DLL_EXPORTED CRITICAL_SECTION *gl_get_setlocale_null_lock (void);
  63 
  64 static glwthread_initguard_t guard = GLWTHREAD_INITGUARD_INIT;
  65 static CRITICAL_SECTION lock;
  66 
  67 /* Returns the internal lock used by setlocale_null_r.  */
  68 CRITICAL_SECTION *
  69 gl_get_setlocale_null_lock (void)
     /* [previous][next][first][last][top][bottom][index][help] */
  70 {
  71   if (!guard.done)
  72     {
  73       if (InterlockedIncrement (&guard.started) == 0)
  74         {
  75           /* This thread is the first one to need the lock.  Initialize it.  */
  76           InitializeCriticalSection (&lock);
  77           guard.done = 1;
  78         }
  79       else
  80         {
  81           /* Don't let guard.started grow and wrap around.  */
  82           InterlockedDecrement (&guard.started);
  83           /* Yield the CPU while waiting for another thread to finish
  84              initializing this mutex.  */
  85           while (!guard.done)
  86             Sleep (0);
  87         }
  88     }
  89   return &lock;
  90 }
  91 
  92 # elif HAVE_PTHREAD_API
  93 
  94 #  include <pthread.h>
  95 
  96 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
  97 
  98 /* Make sure the function gets exported from shared libraries.  */
  99 DLL_EXPORTED pthread_mutex_t *gl_get_setlocale_null_lock (void);
 100 
 101 /* Returns the internal lock used by setlocale_null_r.  */
 102 pthread_mutex_t *
 103 gl_get_setlocale_null_lock (void)
     /* [previous][next][first][last][top][bottom][index][help] */
 104 {
 105   return &mutex;
 106 }
 107 
 108 # elif HAVE_THREADS_H
 109 
 110 #  include <threads.h>
 111 #  include <stdlib.h>
 112 
 113 static int volatile init_needed = 1;
 114 static once_flag init_once = ONCE_FLAG_INIT;
 115 static mtx_t mutex;
 116 
 117 static void
 118 atomic_init (void)
     /* [previous][next][first][last][top][bottom][index][help] */
 119 {
 120   if (mtx_init (&mutex, mtx_plain) != thrd_success)
 121     abort ();
 122   init_needed = 0;
 123 }
 124 
 125 /* Make sure the function gets exported from shared libraries.  */
 126 DLL_EXPORTED mtx_t *gl_get_setlocale_null_lock (void);
 127 
 128 /* Returns the internal lock used by setlocale_null_r.  */
 129 mtx_t *
 130 gl_get_setlocale_null_lock (void)
     /* [previous][next][first][last][top][bottom][index][help] */
 131 {
 132   if (init_needed)
 133     call_once (&init_once, atomic_init);
 134   return &mutex;
 135 }
 136 
 137 # endif
 138 
 139 # if (defined _WIN32 || defined __CYGWIN__) && !defined _MSC_VER
 140 /* Make sure the '__declspec(dllimport)' in setlocale_null.c does not cause
 141    a link failure when no DLLs are involved.  */
 142 #  if defined _WIN64 || defined _LP64
 143 #   define IMP(x) __imp_##x
 144 #  else
 145 #   define IMP(x) _imp__##x
 146 #  endif
 147 void * IMP(gl_get_setlocale_null_lock) = &gl_get_setlocale_null_lock;
 148 # endif
 149 
 150 #endif

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