This source file includes following definitions.
- mtx_init
- mtx_lock
- mtx_trylock
- mtx_timedlock
- mtx_unlock
- mtx_destroy
- call_once
- mtx_init
- mtx_lock
- mtx_trylock
- mtx_timedlock
- mtx_unlock
- mtx_destroy
- call_once
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 #include <config.h>
21
22 #include <threads.h>
23
24 #include <errno.h>
25
26 #if defined _WIN32 && ! defined __CYGWIN__
27
28
29 # define WIN32_LEAN_AND_MEAN
30 # include <windows.h>
31
32 # include <stdlib.h>
33
34 #else
35
36
37 # include <pthread.h>
38
39 #endif
40
41 #if defined _WIN32 && ! defined __CYGWIN__
42
43
44 int
45 mtx_init (mtx_t *mutex, int type)
46 {
47 switch (type)
48 {
49 case mtx_plain:
50 glwthread_mutex_init (&mutex->u.u_mutex);
51 break;
52 case mtx_plain | mtx_recursive:
53 glwthread_recmutex_init (&mutex->u.u_recmutex);
54 break;
55 case mtx_timed:
56 if (glwthread_timedmutex_init (&mutex->u.u_timedmutex) != 0)
57 return thrd_error;
58 break;
59 case mtx_timed | mtx_recursive:
60 if (glwthread_timedrecmutex_init (&mutex->u.u_timedrecmutex) != 0)
61 return thrd_error;
62 break;
63 default:
64 return thrd_error;
65 }
66 mutex->type = type;
67 return thrd_success;
68 }
69
70 int
71 mtx_lock (mtx_t *mutex)
72 {
73 int err;
74
75 switch (mutex->type)
76 {
77 case mtx_plain:
78 err = glwthread_mutex_lock (&mutex->u.u_mutex);
79 break;
80 case mtx_plain | mtx_recursive:
81 err = glwthread_recmutex_lock (&mutex->u.u_recmutex);
82 break;
83 case mtx_timed:
84 err = glwthread_timedmutex_lock (&mutex->u.u_timedmutex);
85 break;
86 case mtx_timed | mtx_recursive:
87 err = glwthread_timedrecmutex_lock (&mutex->u.u_timedrecmutex);
88 break;
89 default:
90 abort ();
91 }
92 return (err == 0 ? thrd_success : thrd_error);
93 }
94
95 int
96 mtx_trylock (mtx_t *mutex)
97 {
98 int err;
99
100 switch (mutex->type)
101 {
102 case mtx_plain:
103 err = glwthread_mutex_trylock (&mutex->u.u_mutex);
104 break;
105 case mtx_plain | mtx_recursive:
106 err = glwthread_recmutex_trylock (&mutex->u.u_recmutex);
107 break;
108 case mtx_timed:
109 err = glwthread_timedmutex_trylock (&mutex->u.u_timedmutex);
110 break;
111 case mtx_timed | mtx_recursive:
112 err = glwthread_timedrecmutex_trylock (&mutex->u.u_timedrecmutex);
113 break;
114 default:
115 abort ();
116 }
117 return (err == 0 ? thrd_success : err == EBUSY ? thrd_busy : thrd_error);
118 }
119
120 int
121 mtx_timedlock (mtx_t *mutex, const struct timespec *abstime)
122 {
123 int err;
124
125 switch (mutex->type)
126 {
127 case mtx_plain:
128 case mtx_plain | mtx_recursive:
129 return thrd_error;
130 case mtx_timed:
131 err = glwthread_timedmutex_timedlock (&mutex->u.u_timedmutex, abstime);
132 break;
133 case mtx_timed | mtx_recursive:
134 err =
135 glwthread_timedrecmutex_timedlock (&mutex->u.u_timedrecmutex, abstime);
136 break;
137 default:
138 abort ();
139 }
140 return (err == 0 ? thrd_success : err == EBUSY ? thrd_busy : thrd_error);
141 }
142
143 int
144 mtx_unlock (mtx_t *mutex)
145 {
146 int err;
147
148 switch (mutex->type)
149 {
150 case mtx_plain:
151 err = glwthread_mutex_unlock (&mutex->u.u_mutex);
152 break;
153 case mtx_plain | mtx_recursive:
154 err = glwthread_recmutex_unlock (&mutex->u.u_recmutex);
155 break;
156 case mtx_timed:
157 err = glwthread_timedmutex_unlock (&mutex->u.u_timedmutex);
158 break;
159 case mtx_timed | mtx_recursive:
160 err = glwthread_timedrecmutex_unlock (&mutex->u.u_timedrecmutex);
161 break;
162 default:
163 abort ();
164 }
165 return (err == 0 ? thrd_success : thrd_error);
166 }
167
168 void
169 mtx_destroy (mtx_t *mutex)
170 {
171 switch (mutex->type)
172 {
173 case mtx_plain:
174 glwthread_mutex_destroy (&mutex->u.u_mutex);
175 break;
176 case mtx_plain | mtx_recursive:
177 glwthread_recmutex_destroy (&mutex->u.u_recmutex);
178 break;
179 case mtx_timed:
180 glwthread_timedmutex_destroy (&mutex->u.u_timedmutex);
181 break;
182 case mtx_timed | mtx_recursive:
183 glwthread_timedrecmutex_destroy (&mutex->u.u_timedrecmutex);
184 break;
185 default:
186 abort ();
187 }
188 }
189
190 void
191 call_once (once_flag *flagp, void (*func) (void))
192 {
193 glwthread_once (flagp, func);
194 }
195
196 #else
197
198
199 int
200 mtx_init (mtx_t *mutex, int type)
201 {
202 switch (type)
203 {
204 case mtx_plain:
205 case mtx_timed:
206 case mtx_plain | mtx_recursive:
207 case mtx_timed | mtx_recursive:
208 break;
209 default:
210 return thrd_error;
211 }
212
213 if ((type & mtx_recursive) != 0)
214 {
215 pthread_mutexattr_t attributes;
216 int err;
217
218 err = pthread_mutexattr_init (&attributes);
219 if (err != 0)
220 return thrd_error;
221 err = pthread_mutexattr_settype (&attributes, PTHREAD_MUTEX_RECURSIVE);
222 if (err != 0)
223 {
224 pthread_mutexattr_destroy (&attributes);
225 return thrd_error;
226 }
227 err = pthread_mutex_init (mutex, &attributes);
228 if (err != 0)
229 {
230 pthread_mutexattr_destroy (&attributes);
231 return thrd_error;
232 }
233 err = pthread_mutexattr_destroy (&attributes);
234 if (err != 0)
235 return thrd_error;
236 }
237 else
238 {
239 int err = pthread_mutex_init (mutex, NULL);
240 if (err != 0)
241 return thrd_error;
242 }
243 return thrd_success;
244 }
245
246 int
247 mtx_lock (mtx_t *mutex)
248 {
249 int err = pthread_mutex_lock (mutex);
250 return (err == 0 ? thrd_success : thrd_error);
251 }
252
253 int
254 mtx_trylock (mtx_t *mutex)
255 {
256 int err = pthread_mutex_trylock (mutex);
257 return (err == 0 ? thrd_success : err == EBUSY ? thrd_busy : thrd_error);
258 }
259
260 int
261 mtx_timedlock (mtx_t *mutex, const struct timespec *abstime)
262 {
263 int err = pthread_mutex_timedlock (mutex, abstime);
264 return (err == 0 ? thrd_success :
265 err == ETIMEDOUT ? thrd_timedout :
266 thrd_error);
267 }
268
269 int
270 mtx_unlock (mtx_t *mutex)
271 {
272 int err = pthread_mutex_unlock (mutex);
273 return (err == 0 ? thrd_success : thrd_error);
274 }
275
276 void
277 mtx_destroy (mtx_t *mutex)
278 {
279 pthread_mutex_destroy (mutex);
280 }
281
282 void
283 call_once (once_flag *flagp, void (*func) (void))
284 {
285 pthread_once (flagp, func);
286 }
287
288 #endif