Apache HTTPD
thread_mutex.c
Go to the documentation of this file.
1/* Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache License, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "apr_arch_thread_mutex.h"
18#define APR_WANT_MEMFUNC
19#include "apr_want.h"
20
21#if APR_HAS_THREADS
22
24{
25 apr_thread_mutex_t *mutex = data;
26 apr_status_t rv;
27
28 rv = pthread_mutex_destroy(&mutex->mutex);
29#ifdef HAVE_ZOS_PTHREADS
30 if (rv) {
31 rv = errno;
32 }
33#endif
34 return rv;
35}
36
38 unsigned int flags,
40{
42 apr_status_t rv;
43
44#ifndef HAVE_PTHREAD_MUTEX_RECURSIVE
46 return APR_ENOTIMPL;
47 }
48#endif
49
51 new_mutex->pool = pool;
52
53#ifdef HAVE_PTHREAD_MUTEX_RECURSIVE
56
58 if (rv) return rv;
59
61 if (rv) {
63 return rv;
64 }
65
66 rv = pthread_mutex_init(&new_mutex->mutex, &mattr);
67
69 } else
70#endif
71 rv = pthread_mutex_init(&new_mutex->mutex, NULL);
72
73 if (rv) {
74#ifdef HAVE_ZOS_PTHREADS
75 rv = errno;
76#endif
77 return rv;
78 }
79
80#ifndef HAVE_PTHREAD_MUTEX_TIMEDLOCK
83 if (rv) {
84#ifdef HAVE_ZOS_PTHREADS
85 rv = errno;
86#endif
88 return rv;
89 }
90 }
91#endif
92
96
97 *mutex = new_mutex;
98 return APR_SUCCESS;
99}
100
102{
103 apr_status_t rv;
104
105#ifndef HAVE_PTHREAD_MUTEX_TIMEDLOCK
106 if (mutex->cond) {
108
109 rv = pthread_mutex_lock(&mutex->mutex);
110 if (rv) {
111#ifdef HAVE_ZOS_PTHREADS
112 rv = errno;
113#endif
114 return rv;
115 }
116
117 if (mutex->locked) {
118 mutex->num_waiters++;
119 rv = apr_thread_cond_wait(mutex->cond, mutex);
120 mutex->num_waiters--;
121 }
122 else {
123 mutex->locked = 1;
124 }
125
126 rv2 = pthread_mutex_unlock(&mutex->mutex);
127 if (rv2 && !rv) {
128#ifdef HAVE_ZOS_PTHREADS
129 rv = errno;
130#else
131 rv = rv2;
132#endif
133 }
134
135 return rv;
136 }
137#endif
138
139 rv = pthread_mutex_lock(&mutex->mutex);
140#ifdef HAVE_ZOS_PTHREADS
141 if (rv) {
142 rv = errno;
143 }
144#endif
145
146 return rv;
147}
148
150{
151 apr_status_t rv;
152
153#ifndef HAVE_PTHREAD_MUTEX_TIMEDLOCK
154 if (mutex->cond) {
156
157 rv = pthread_mutex_lock(&mutex->mutex);
158 if (rv) {
159#ifdef HAVE_ZOS_PTHREADS
160 rv = errno;
161#endif
162 return rv;
163 }
164
165 if (mutex->locked) {
166 rv = APR_EBUSY;
167 }
168 else {
169 mutex->locked = 1;
170 }
171
172 rv2 = pthread_mutex_unlock(&mutex->mutex);
173 if (rv2) {
174#ifdef HAVE_ZOS_PTHREADS
175 rv = errno;
176#else
177 rv = rv2;
178#endif
179 }
180
181 return rv;
182 }
183#endif
184
185 rv = pthread_mutex_trylock(&mutex->mutex);
186 if (rv) {
187#ifdef HAVE_ZOS_PTHREADS
188 rv = errno;
189#endif
190 return (rv == EBUSY) ? APR_EBUSY : rv;
191 }
192
193 return APR_SUCCESS;
194}
195
198{
200#if APR_HAS_TIMEDLOCKS
201
202#ifdef HAVE_PTHREAD_MUTEX_TIMEDLOCK
203 if (timeout <= 0) {
204 rv = pthread_mutex_trylock(&mutex->mutex);
205 if (rv) {
206#ifdef HAVE_ZOS_PTHREADS
207 rv = errno;
208#endif
209 if (rv == EBUSY) {
210 rv = APR_TIMEUP;
211 }
212 }
213 }
214 else {
215 struct timespec abstime;
216
218 abstime.tv_sec = apr_time_sec(timeout);
219 abstime.tv_nsec = apr_time_usec(timeout) * 1000; /* nanoseconds */
220
221 rv = pthread_mutex_timedlock(&mutex->mutex, &abstime);
222 if (rv) {
223#ifdef HAVE_ZOS_PTHREADS
224 rv = errno;
225#endif
226 if (rv == ETIMEDOUT) {
227 rv = APR_TIMEUP;
228 }
229 }
230 }
231
232#else /* HAVE_PTHREAD_MUTEX_TIMEDLOCK */
233
234 if (mutex->cond) {
235 rv = pthread_mutex_lock(&mutex->mutex);
236 if (rv) {
237#ifdef HAVE_ZOS_PTHREADS
238 rv = errno;
239#endif
240 return rv;
241 }
242
243 if (mutex->locked) {
244 if (timeout <= 0) {
245 rv = APR_TIMEUP;
246 }
247 else {
248 mutex->num_waiters++;
249 do {
250 rv = apr_thread_cond_timedwait(mutex->cond, mutex,
251 timeout);
252 if (rv) {
253#ifdef HAVE_ZOS_PTHREADS
254 rv = errno;
255#endif
256 break;
257 }
258 } while (mutex->locked);
259 mutex->num_waiters--;
260 }
261 if (rv) {
263 return rv;
264 }
265 }
266
267 mutex->locked = 1;
268
269 rv = pthread_mutex_unlock(&mutex->mutex);
270 if (rv) {
271#ifdef HAVE_ZOS_PTHREADS
272 rv = errno;
273#endif
274 return rv;
275 }
276 }
277
278#endif /* HAVE_PTHREAD_MUTEX_TIMEDLOCK */
279
280#endif /* APR_HAS_TIMEDLOCKS */
281 return rv;
282}
283
285{
287
288#ifndef HAVE_PTHREAD_MUTEX_TIMEDLOCK
289 if (mutex->cond) {
291 if (status) {
292#ifdef HAVE_ZOS_PTHREADS
293 status = errno;
294#endif
295 return status;
296 }
297
298 if (!mutex->locked) {
300 }
301 else if (mutex->num_waiters) {
303 }
304 if (status) {
306 return status;
307 }
308
309 mutex->locked = 0;
310 }
311#endif
312
314#ifdef HAVE_ZOS_PTHREADS
315 if (status) {
316 status = errno;
317 }
318#endif
319
320 return status;
321}
322
324{
326
327#ifndef HAVE_PTHREAD_MUTEX_TIMEDLOCK
328 if (mutex->cond) {
330 }
331#endif
332
334 if (rv == APR_SUCCESS) {
335 rv = rv2;
336 }
337
338 return rv;
339}
340
342
343#endif /* APR_HAS_THREADS */
APR Standard Headers Support.
#define APR_ENOTIMPL
Definition apr_errno.h:476
#define APR_TIMEUP
Definition apr_errno.h:450
#define APR_EBUSY
Definition apr_errno.h:480
#define APR_EINVAL
Definition apr_errno.h:711
const char apr_ssize_t int flags
Definition apr_encode.h:168
const void apr_status_t(*) apr_status_t(* APR_DECLARE)(void) apr_pool_pre_cleanup_register(apr_pool_t *p
Definition apr_pools.h:646
apr_size_t size
const char int apr_pool_t * pool
Definition apr_cstr.h:84
#define APR_SUCCESS
Definition apr_errno.h:225
int apr_status_t
Definition apr_errno.h:44
void * data
#define APR_POOL_IMPLEMENT_ACCESSOR(type)
Definition apr_pools.h:91
#define apr_pcalloc(p, size)
Definition apr_pools.h:465
int int status
apr_int64_t apr_interval_time_t
Definition apr_time.h:55
#define apr_time_sec(time)
Definition apr_time.h:63
#define apr_time_usec(time)
Definition apr_time.h:66
return NULL
Definition mod_so.c:359
static apr_status_t thread_mutex_cleanup(void *data)
apr_thread_cond_t * cond
IN ULONG IN INT timeout