(root)/
tar-1.35/
gnu/
mbtowc-lock.h
       1  /* Use the internal lock used by mbrtowc and mbrtoc32.
       2     Copyright (C) 2019-2023 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-2020.  */
      18  
      19  /* Use a lock, so that no two threads can invoke mbtowc at the same time.  */
      20  
      21  static inline int
      22  mbtowc_unlocked (wchar_t *pwc, const char *p, size_t m)
      23  {
      24    /* Put the hidden internal state of mbtowc into its initial state.
      25       This is needed at least with glibc, uClibc, and MSVC CRT.
      26       See <https://sourceware.org/bugzilla/show_bug.cgi?id=9674>.  */
      27    mbtowc (NULL, NULL, 0);
      28  
      29    return mbtowc (pwc, p, m);
      30  }
      31  
      32  /* Prohibit renaming this symbol.  */
      33  #undef gl_get_mbtowc_lock
      34  
      35  #if GNULIB_MBRTOWC_SINGLE_THREAD
      36  
      37  /* All uses of this function are in a single thread.  No locking needed.  */
      38  
      39  static int
      40  mbtowc_with_lock (wchar_t *pwc, const char *p, size_t m)
      41  {
      42    return mbtowc_unlocked (pwc, p, m);
      43  }
      44  
      45  #elif defined _WIN32 && !defined __CYGWIN__
      46  
      47  extern __declspec(dllimport) CRITICAL_SECTION *gl_get_mbtowc_lock (void);
      48  
      49  static int
      50  mbtowc_with_lock (wchar_t *pwc, const char *p, size_t m)
      51  {
      52    CRITICAL_SECTION *lock = gl_get_mbtowc_lock ();
      53    int ret;
      54  
      55    EnterCriticalSection (lock);
      56    ret = mbtowc_unlocked (pwc, p, m);
      57    LeaveCriticalSection (lock);
      58  
      59    return ret;
      60  }
      61  
      62  #elif HAVE_PTHREAD_API /* AIX, IRIX, Cygwin */
      63  
      64  extern
      65  # if defined _WIN32 || defined __CYGWIN__
      66    __declspec(dllimport)
      67  # endif
      68    pthread_mutex_t *gl_get_mbtowc_lock (void);
      69  
      70  # if HAVE_WEAK_SYMBOLS /* IRIX */
      71  
      72     /* Avoid the need to link with '-lpthread'.  */
      73  #  pragma weak pthread_mutex_lock
      74  #  pragma weak pthread_mutex_unlock
      75  
      76     /* Determine whether libpthread is in use.  */
      77  #  pragma weak pthread_mutexattr_gettype
      78     /* See the comments in lock.h.  */
      79  #  define pthread_in_use() \
      80       (pthread_mutexattr_gettype != NULL || c11_threads_in_use ())
      81  
      82  # else
      83  #  define pthread_in_use() 1
      84  # endif
      85  
      86  static int
      87  mbtowc_with_lock (wchar_t *pwc, const char *p, size_t m)
      88  {
      89    if (pthread_in_use())
      90      {
      91        pthread_mutex_t *lock = gl_get_mbtowc_lock ();
      92        int ret;
      93  
      94        if (pthread_mutex_lock (lock))
      95          abort ();
      96        ret = mbtowc_unlocked (pwc, p, m);
      97        if (pthread_mutex_unlock (lock))
      98          abort ();
      99  
     100        return ret;
     101      }
     102    else
     103      return mbtowc_unlocked (pwc, p, m);
     104  }
     105  
     106  #elif HAVE_THREADS_H
     107  
     108  extern mtx_t *gl_get_mbtowc_lock (void);
     109  
     110  static int
     111  mbtowc_with_lock (wchar_t *pwc, const char *p, size_t m)
     112  {
     113    mtx_t *lock = gl_get_mbtowc_lock ();
     114    int ret;
     115  
     116    if (mtx_lock (lock) != thrd_success)
     117      abort ();
     118    ret = mbtowc_unlocked (pwc, p, m);
     119    if (mtx_unlock (lock) != thrd_success)
     120      abort ();
     121  
     122    return ret;
     123  }
     124  
     125  #endif