diff options
| author | Jörg Frings-Fürst <debian@jff.email> | 2022-01-08 11:51:39 +0100 | 
|---|---|---|
| committer | Jörg Frings-Fürst <debian@jff.email> | 2022-01-08 11:51:39 +0100 | 
| commit | 2959e59fab3bab834368adefd90bd4b1b094366b (patch) | |
| tree | 7d0ae09775ea950056193eaa2ca93844299d46f1 /lib/setlocale-lock.c | |
| parent | c78359d9542c86b972aac373efcf7bc7a8a560e5 (diff) | |
| parent | be8efac78d067c138ad8dda03df4336e73f94887 (diff) | |
Update upstream source from tag 'upstream/1.0'
Update to upstream version '1.0'
with Debian dir 4875e7dc9f7277205f0086a63ee21ccdb1d54593
Diffstat (limited to 'lib/setlocale-lock.c')
| -rw-r--r-- | lib/setlocale-lock.c | 150 | 
1 files changed, 150 insertions, 0 deletions
| diff --git a/lib/setlocale-lock.c b/lib/setlocale-lock.c new file mode 100644 index 00000000..4e7540e1 --- /dev/null +++ b/lib/setlocale-lock.c @@ -0,0 +1,150 @@ +/* Return the internal lock used by setlocale_null_r. +   Copyright (C) 2019-2022 Free Software Foundation, Inc. + +   This file is free software: you can redistribute it and/or modify +   it under the terms of the GNU Lesser General Public License as +   published by the Free Software Foundation; either version 2.1 of the +   License, or (at your option) any later version. + +   This file is distributed in the hope that it will be useful, +   but WITHOUT ANY WARRANTY; without even the implied warranty of +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the +   GNU Lesser General Public License for more details. + +   You should have received a copy of the GNU Lesser General Public License +   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */ + +/* Written by Bruno Haible <bruno@clisp.org>, 2019.  */ + +#include <config.h> + +/* When it is known that the gl_get_setlocale_null_lock function is defined +   by a dependency library, it should not be defined here.  */ +#if OMIT_SETLOCALE_LOCK + +/* This declaration is solely to ensure that after preprocessing +   this file is never empty.  */ +typedef int dummy; + +#else + +/* This file defines the internal lock used by setlocale_null_r. +   It is a separate compilation unit, so that only one copy of it is +   present when linking statically.  */ + +/* Prohibit renaming this symbol.  */ +# undef gl_get_setlocale_null_lock + +/* Macro for exporting a symbol (function, not variable) defined in this file, +   when compiled into a shared library.  */ +# ifndef DLL_EXPORTED +#  if HAVE_VISIBILITY +  /* Override the effect of the compiler option '-fvisibility=hidden'.  */ +#   define DLL_EXPORTED __attribute__((__visibility__("default"))) +#  elif defined _WIN32 || defined __CYGWIN__ +#   define DLL_EXPORTED __declspec(dllexport) +#  else +#   define DLL_EXPORTED +#  endif +# endif + +# if defined _WIN32 && !defined __CYGWIN__ + +#  define WIN32_LEAN_AND_MEAN  /* avoid including junk */ +#  include <windows.h> + +#  include "windows-initguard.h" + +/* The return type is a 'CRITICAL_SECTION *', not a 'glwthread_mutex_t *', +   because the latter is not guaranteed to be a stable ABI in the future.  */ + +/* Make sure the function gets exported from DLLs.  */ +DLL_EXPORTED CRITICAL_SECTION *gl_get_setlocale_null_lock (void); + +static glwthread_initguard_t guard = GLWTHREAD_INITGUARD_INIT; +static CRITICAL_SECTION lock; + +/* Returns the internal lock used by setlocale_null_r.  */ +CRITICAL_SECTION * +gl_get_setlocale_null_lock (void) +{ +  if (!guard.done) +    { +      if (InterlockedIncrement (&guard.started) == 0) +        { +          /* This thread is the first one to need the lock.  Initialize it.  */ +          InitializeCriticalSection (&lock); +          guard.done = 1; +        } +      else +        { +          /* Don't let guard.started grow and wrap around.  */ +          InterlockedDecrement (&guard.started); +          /* Yield the CPU while waiting for another thread to finish +             initializing this mutex.  */ +          while (!guard.done) +            Sleep (0); +        } +    } +  return &lock; +} + +# elif HAVE_PTHREAD_API + +#  include <pthread.h> + +static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; + +/* Make sure the function gets exported from shared libraries.  */ +DLL_EXPORTED pthread_mutex_t *gl_get_setlocale_null_lock (void); + +/* Returns the internal lock used by setlocale_null_r.  */ +pthread_mutex_t * +gl_get_setlocale_null_lock (void) +{ +  return &mutex; +} + +# elif HAVE_THREADS_H + +#  include <threads.h> +#  include <stdlib.h> + +static int volatile init_needed = 1; +static once_flag init_once = ONCE_FLAG_INIT; +static mtx_t mutex; + +static void +atomic_init (void) +{ +  if (mtx_init (&mutex, mtx_plain) != thrd_success) +    abort (); +  init_needed = 0; +} + +/* Make sure the function gets exported from shared libraries.  */ +DLL_EXPORTED mtx_t *gl_get_setlocale_null_lock (void); + +/* Returns the internal lock used by setlocale_null_r.  */ +mtx_t * +gl_get_setlocale_null_lock (void) +{ +  if (init_needed) +    call_once (&init_once, atomic_init); +  return &mutex; +} + +# endif + +# if (defined _WIN32 || defined __CYGWIN__) && !defined _MSC_VER +/* Make sure the '__declspec(dllimport)' in setlocale_null.c does not cause +   a link failure when no DLLs are involved.  */ +#  if defined _WIN64 || defined _LP64 +#   define IMP(x) __imp_##x +#  else +#   define IMP(x) _imp__##x +#  endif +void * IMP(gl_get_setlocale_null_lock) = &gl_get_setlocale_null_lock; +# endif + +#endif | 
