intprops: Avoid bogus "warning: division by zero is undefined" on clang.
[gnulib.git] / lib / pthread-mutex.c
blob45b3e78cf3369cb6fb78285dc17414389691e5b5
1 /* POSIX mutexes (locks).
2 Copyright (C) 2010-2020 Free Software Foundation, Inc.
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 2, or (at your option)
7 any later version.
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.
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/>. */
17 /* Written by Paul Eggert, 2010, and Bruno Haible <bruno@clisp.org>, 2019. */
19 #include <config.h>
21 /* Specification. */
22 #include <pthread.h>
24 #if (defined _WIN32 && ! defined __CYGWIN__) && USE_WINDOWS_THREADS
25 # include "windows-timedmutex.h"
26 # include "windows-timedrecmutex.h"
27 #else
28 # include <stdlib.h>
29 #endif
31 #if ((defined _WIN32 && ! defined __CYGWIN__) && USE_WINDOWS_THREADS) || !HAVE_PTHREAD_H
33 int
34 pthread_mutexattr_init (pthread_mutexattr_t *attr)
36 *attr = (PTHREAD_MUTEX_STALLED << 2) | PTHREAD_MUTEX_DEFAULT;
37 return 0;
40 int
41 pthread_mutexattr_gettype (const pthread_mutexattr_t *attr, int *typep)
43 *typep = *attr & (PTHREAD_MUTEX_DEFAULT | PTHREAD_MUTEX_NORMAL
44 | PTHREAD_MUTEX_ERRORCHECK | PTHREAD_MUTEX_RECURSIVE);
45 return 0;
48 int
49 pthread_mutexattr_settype (pthread_mutexattr_t *attr, int type)
51 if (!(type == PTHREAD_MUTEX_DEFAULT
52 || type == PTHREAD_MUTEX_NORMAL
53 || type == PTHREAD_MUTEX_ERRORCHECK
54 || type == PTHREAD_MUTEX_RECURSIVE))
55 return EINVAL;
56 *attr ^= (*attr ^ type)
57 & (PTHREAD_MUTEX_DEFAULT | PTHREAD_MUTEX_NORMAL
58 | PTHREAD_MUTEX_ERRORCHECK | PTHREAD_MUTEX_RECURSIVE);
59 return 0;
62 int
63 pthread_mutexattr_getrobust (const pthread_mutexattr_t *attr, int *robustp)
65 *robustp = (*attr >> 2) & (PTHREAD_MUTEX_STALLED | PTHREAD_MUTEX_ROBUST);
66 return 0;
69 int
70 pthread_mutexattr_setrobust (pthread_mutexattr_t *attr, int robust)
72 if (!(robust == PTHREAD_MUTEX_STALLED || robust == PTHREAD_MUTEX_ROBUST))
73 return EINVAL;
74 *attr ^= (*attr ^ (robust << 2))
75 & ((PTHREAD_MUTEX_STALLED | PTHREAD_MUTEX_ROBUST) << 2);
76 return 0;
79 int
80 pthread_mutexattr_destroy (pthread_mutexattr_t *attr _GL_UNUSED)
82 return 0;
85 #elif PTHREAD_MUTEXATTR_ROBUST_UNIMPLEMENTED
87 int
88 pthread_mutexattr_getrobust (const pthread_mutexattr_t *attr, int *robustp)
90 *robustp = PTHREAD_MUTEX_STALLED;
91 return 0;
94 int
95 pthread_mutexattr_setrobust (pthread_mutexattr_t *attr, int robust)
97 if (!(robust == PTHREAD_MUTEX_STALLED || robust == PTHREAD_MUTEX_ROBUST))
98 return EINVAL;
99 if (!(robust == PTHREAD_MUTEX_STALLED))
100 return ENOTSUP;
101 return 0;
104 #endif
106 #if (defined _WIN32 && ! defined __CYGWIN__) && USE_WINDOWS_THREADS
107 /* Use Windows threads. */
110 pthread_mutex_init (pthread_mutex_t *mutex, const pthread_mutexattr_t *attr)
112 /* This implementation does not support PTHREAD_MUTEX_ERRORCHECK
113 and ignores the 'robust' attribute. */
114 if (attr != NULL
115 && (*attr & (PTHREAD_MUTEX_DEFAULT | PTHREAD_MUTEX_NORMAL
116 | PTHREAD_MUTEX_ERRORCHECK | PTHREAD_MUTEX_RECURSIVE))
117 == PTHREAD_MUTEX_RECURSIVE)
119 mutex->type = 2;
120 return glwthread_timedrecmutex_init (&mutex->u.u_timedrecmutex);
122 else
124 mutex->type = 1;
125 return glwthread_timedmutex_init (&mutex->u.u_timedmutex);
130 pthread_mutex_lock (pthread_mutex_t *mutex)
132 switch (mutex->type)
134 case 1:
135 return glwthread_timedmutex_lock (&mutex->u.u_timedmutex);
136 case 2:
137 return glwthread_timedrecmutex_lock (&mutex->u.u_timedrecmutex);
138 default:
139 abort ();
144 pthread_mutex_trylock (pthread_mutex_t *mutex)
146 switch (mutex->type)
148 case 1:
149 return glwthread_timedmutex_trylock (&mutex->u.u_timedmutex);
150 case 2:
151 return glwthread_timedrecmutex_trylock (&mutex->u.u_timedrecmutex);
152 default:
153 abort ();
158 pthread_mutex_timedlock (pthread_mutex_t *mutex, const struct timespec *abstime)
160 switch (mutex->type)
162 case 1:
163 return glwthread_timedmutex_timedlock (&mutex->u.u_timedmutex, abstime);
164 case 2:
165 return glwthread_timedrecmutex_timedlock (&mutex->u.u_timedrecmutex,
166 abstime);
167 default:
168 abort ();
173 pthread_mutex_unlock (pthread_mutex_t *mutex)
175 switch (mutex->type)
177 case 1:
178 return glwthread_timedmutex_unlock (&mutex->u.u_timedmutex);
179 case 2:
180 return glwthread_timedrecmutex_unlock (&mutex->u.u_timedrecmutex);
181 default:
182 abort ();
187 pthread_mutex_destroy (pthread_mutex_t *mutex)
189 switch (mutex->type)
191 case 1:
192 return glwthread_timedmutex_destroy (&mutex->u.u_timedmutex);
193 case 2:
194 return glwthread_timedrecmutex_destroy (&mutex->u.u_timedrecmutex);
195 default:
196 abort ();
200 #elif HAVE_PTHREAD_H
201 /* Provide workarounds for POSIX threads. */
203 /* pthread_mutex_timedlock is defined by the 'pthread_mutex_timedlock'
204 module. */
206 #else
207 /* Provide a dummy implementation for single-threaded applications. */
210 pthread_mutex_init (pthread_mutex_t *mutex _GL_UNUSED,
211 const pthread_mutexattr_t *attr _GL_UNUSED)
213 /* MUTEX is never seriously used. */
214 return 0;
218 pthread_mutex_lock (pthread_mutex_t *mutex _GL_UNUSED)
220 /* There is only one thread, so it always gets the lock. This
221 implementation does not support PTHREAD_MUTEX_ERRORCHECK. */
222 return 0;
226 pthread_mutex_trylock (pthread_mutex_t *mutex _GL_UNUSED)
228 /* There is only one thread, so it always gets the lock. This
229 implementation does not support PTHREAD_MUTEX_ERRORCHECK. */
230 return 0;
234 pthread_mutex_timedlock (pthread_mutex_t *mutex _GL_UNUSED,
235 const struct timespec *abstime _GL_UNUSED)
237 /* There is only one thread, so it always gets the lock. This
238 implementation does not support PTHREAD_MUTEX_ERRORCHECK. */
239 return 0;
243 pthread_mutex_unlock (pthread_mutex_t *mutex _GL_UNUSED)
245 /* There is only one thread, so it always unlocks successfully.
246 This implementation does not support robust mutexes or
247 PTHREAD_MUTEX_ERRORCHECK. */
248 return 0;
252 pthread_mutex_destroy (pthread_mutex_t *mutex _GL_UNUSED)
254 /* MUTEX is never seriously used. */
255 return 0;
258 #endif