gnulib: update to 776af40e0
[deliverable/binutils-gdb.git] / gnulib / import / mbtowc-lock.h
CommitLineData
5df4cba6 1/* Use the internal lock used by mbrtowc and mbrtoc32.
9c9d63b1 2 Copyright (C) 2019-2021 Free Software Foundation, Inc.
5df4cba6
SM
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-2020. */
18
19/* Use a lock, so that no two threads can invoke mbtowc at the same time. */
20
21static inline int
22mbtowc_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 defined _WIN32 && !defined __CYGWIN__
36
37extern __declspec(dllimport) CRITICAL_SECTION *gl_get_mbtowc_lock (void);
38
39static int
40mbtowc_with_lock (wchar_t *pwc, const char *p, size_t m)
41{
42 CRITICAL_SECTION *lock = gl_get_mbtowc_lock ();
43 int ret;
44
45 EnterCriticalSection (lock);
46 ret = mbtowc_unlocked (pwc, p, m);
47 LeaveCriticalSection (lock);
48
49 return ret;
50}
51
52#elif HAVE_PTHREAD_API /* AIX, IRIX, Cygwin */
53
54extern
55# if defined _WIN32 || defined __CYGWIN__
56 __declspec(dllimport)
57# endif
58 pthread_mutex_t *gl_get_mbtowc_lock (void);
59
60# if HAVE_WEAK_SYMBOLS /* IRIX */
61
62 /* Avoid the need to link with '-lpthread'. */
63# pragma weak pthread_mutex_lock
64# pragma weak pthread_mutex_unlock
65
66 /* Determine whether libpthread is in use. */
67# pragma weak pthread_mutexattr_gettype
68 /* See the comments in lock.h. */
69# define pthread_in_use() \
70 (pthread_mutexattr_gettype != NULL || c11_threads_in_use ())
71
72# else
73# define pthread_in_use() 1
74# endif
75
76static int
77mbtowc_with_lock (wchar_t *pwc, const char *p, size_t m)
78{
79 if (pthread_in_use())
80 {
81 pthread_mutex_t *lock = gl_get_mbtowc_lock ();
82 int ret;
83
84 if (pthread_mutex_lock (lock))
85 abort ();
86 ret = mbtowc_unlocked (pwc, p, m);
87 if (pthread_mutex_unlock (lock))
88 abort ();
89
90 return ret;
91 }
92 else
93 return mbtowc_unlocked (pwc, p, m);
94}
95
96#elif HAVE_THREADS_H
97
98extern mtx_t *gl_get_mbtowc_lock (void);
99
100static int
101mbtowc_with_lock (wchar_t *pwc, const char *p, size_t m)
102{
103 mtx_t *lock = gl_get_mbtowc_lock ();
104 int ret;
105
106 if (mtx_lock (lock) != thrd_success)
107 abort ();
108 ret = mbtowc_unlocked (pwc, p, m);
109 if (mtx_unlock (lock) != thrd_success)
110 abort ();
111
112 return ret;
113}
114
115#endif
This page took 0.072121 seconds and 4 git commands to generate.