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)
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. */
24 #if (defined _WIN32 && ! defined __CYGWIN__) && USE_WINDOWS_THREADS
25 # include "windows-timedmutex.h"
26 # include "windows-timedrecmutex.h"
31 #if ((defined _WIN32 && ! defined __CYGWIN__) && USE_WINDOWS_THREADS) || !HAVE_PTHREAD_H
34 pthread_mutexattr_init (pthread_mutexattr_t
*attr
)
36 *attr
= (PTHREAD_MUTEX_STALLED
<< 2) | PTHREAD_MUTEX_DEFAULT
;
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
);
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
))
56 *attr
^= (*attr
^ type
)
57 & (PTHREAD_MUTEX_DEFAULT
| PTHREAD_MUTEX_NORMAL
58 | PTHREAD_MUTEX_ERRORCHECK
| PTHREAD_MUTEX_RECURSIVE
);
63 pthread_mutexattr_getrobust (const pthread_mutexattr_t
*attr
, int *robustp
)
65 *robustp
= (*attr
>> 2) & (PTHREAD_MUTEX_STALLED
| PTHREAD_MUTEX_ROBUST
);
70 pthread_mutexattr_setrobust (pthread_mutexattr_t
*attr
, int robust
)
72 if (!(robust
== PTHREAD_MUTEX_STALLED
|| robust
== PTHREAD_MUTEX_ROBUST
))
74 *attr
^= (*attr
^ (robust
<< 2))
75 & ((PTHREAD_MUTEX_STALLED
| PTHREAD_MUTEX_ROBUST
) << 2);
80 pthread_mutexattr_destroy (pthread_mutexattr_t
*attr _GL_UNUSED
)
85 #elif PTHREAD_MUTEXATTR_ROBUST_UNIMPLEMENTED
88 pthread_mutexattr_getrobust (const pthread_mutexattr_t
*attr
, int *robustp
)
90 *robustp
= PTHREAD_MUTEX_STALLED
;
95 pthread_mutexattr_setrobust (pthread_mutexattr_t
*attr
, int robust
)
97 if (!(robust
== PTHREAD_MUTEX_STALLED
|| robust
== PTHREAD_MUTEX_ROBUST
))
99 if (!(robust
== PTHREAD_MUTEX_STALLED
))
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. */
115 && (*attr
& (PTHREAD_MUTEX_DEFAULT
| PTHREAD_MUTEX_NORMAL
116 | PTHREAD_MUTEX_ERRORCHECK
| PTHREAD_MUTEX_RECURSIVE
))
117 == PTHREAD_MUTEX_RECURSIVE
)
120 return glwthread_timedrecmutex_init (&mutex
->u
.u_timedrecmutex
);
125 return glwthread_timedmutex_init (&mutex
->u
.u_timedmutex
);
130 pthread_mutex_lock (pthread_mutex_t
*mutex
)
135 return glwthread_timedmutex_lock (&mutex
->u
.u_timedmutex
);
137 return glwthread_timedrecmutex_lock (&mutex
->u
.u_timedrecmutex
);
144 pthread_mutex_trylock (pthread_mutex_t
*mutex
)
149 return glwthread_timedmutex_trylock (&mutex
->u
.u_timedmutex
);
151 return glwthread_timedrecmutex_trylock (&mutex
->u
.u_timedrecmutex
);
158 pthread_mutex_timedlock (pthread_mutex_t
*mutex
, const struct timespec
*abstime
)
163 return glwthread_timedmutex_timedlock (&mutex
->u
.u_timedmutex
, abstime
);
165 return glwthread_timedrecmutex_timedlock (&mutex
->u
.u_timedrecmutex
,
173 pthread_mutex_unlock (pthread_mutex_t
*mutex
)
178 return glwthread_timedmutex_unlock (&mutex
->u
.u_timedmutex
);
180 return glwthread_timedrecmutex_unlock (&mutex
->u
.u_timedrecmutex
);
187 pthread_mutex_destroy (pthread_mutex_t
*mutex
)
192 return glwthread_timedmutex_destroy (&mutex
->u
.u_timedmutex
);
194 return glwthread_timedrecmutex_destroy (&mutex
->u
.u_timedrecmutex
);
201 /* Provide workarounds for POSIX threads. */
203 /* pthread_mutex_timedlock is defined by the 'pthread_mutex_timedlock'
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. */
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. */
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. */
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. */
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. */
252 pthread_mutex_destroy (pthread_mutex_t
*mutex _GL_UNUSED
)
254 /* MUTEX is never seriously used. */