"Fossies" - the Fresh Open Source Software Archive 
Member "apr-1.7.0/locks/unix/thread_mutex.c" (21 Mar 2019, 7859 Bytes) of package /linux/www/apr-1.7.0.tar.bz2:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
For more information about "thread_mutex.c" see the
Fossies "Dox" file reference documentation and the latest
Fossies "Diffs" side-by-side code changes report:
1.6.5_vs_1.7.0.
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
23 static apr_status_t thread_mutex_cleanup(void *data)
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
37 APR_DECLARE(apr_status_t) apr_thread_mutex_create(apr_thread_mutex_t **mutex,
38 unsigned int flags,
39 apr_pool_t *pool)
40 {
41 apr_thread_mutex_t *new_mutex;
42 apr_status_t rv;
43
44 #ifndef HAVE_PTHREAD_MUTEX_RECURSIVE
45 if (flags & APR_THREAD_MUTEX_NESTED) {
46 return APR_ENOTIMPL;
47 }
48 #endif
49
50 new_mutex = apr_pcalloc(pool, sizeof(apr_thread_mutex_t));
51 new_mutex->pool = pool;
52
53 #ifdef HAVE_PTHREAD_MUTEX_RECURSIVE
54 if (flags & APR_THREAD_MUTEX_NESTED) {
55 pthread_mutexattr_t mattr;
56
57 rv = pthread_mutexattr_init(&mattr);
58 if (rv) return rv;
59
60 rv = pthread_mutexattr_settype(&mattr, PTHREAD_MUTEX_RECURSIVE);
61 if (rv) {
62 pthread_mutexattr_destroy(&mattr);
63 return rv;
64 }
65
66 rv = pthread_mutex_init(&new_mutex->mutex, &mattr);
67
68 pthread_mutexattr_destroy(&mattr);
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
81 if (flags & APR_THREAD_MUTEX_TIMED) {
82 rv = apr_thread_cond_create(&new_mutex->cond, pool);
83 if (rv) {
84 #ifdef HAVE_ZOS_PTHREADS
85 rv = errno;
86 #endif
87 pthread_mutex_destroy(&new_mutex->mutex);
88 return rv;
89 }
90 }
91 #endif
92
93 apr_pool_cleanup_register(new_mutex->pool,
94 new_mutex, thread_mutex_cleanup,
95 apr_pool_cleanup_null);
96
97 *mutex = new_mutex;
98 return APR_SUCCESS;
99 }
100
101 APR_DECLARE(apr_status_t) apr_thread_mutex_lock(apr_thread_mutex_t *mutex)
102 {
103 apr_status_t rv;
104
105 if (mutex->cond) {
106 apr_status_t rv2;
107
108 rv = pthread_mutex_lock(&mutex->mutex);
109 if (rv) {
110 #ifdef HAVE_ZOS_PTHREADS
111 rv = errno;
112 #endif
113 return rv;
114 }
115
116 if (mutex->locked) {
117 mutex->num_waiters++;
118 rv = apr_thread_cond_wait(mutex->cond, mutex);
119 mutex->num_waiters--;
120 }
121 else {
122 mutex->locked = 1;
123 }
124
125 rv2 = pthread_mutex_unlock(&mutex->mutex);
126 if (rv2 && !rv) {
127 #ifdef HAVE_ZOS_PTHREADS
128 rv = errno;
129 #else
130 rv = rv2;
131 #endif
132 }
133
134 return rv;
135 }
136
137 rv = pthread_mutex_lock(&mutex->mutex);
138 #ifdef HAVE_ZOS_PTHREADS
139 if (rv) {
140 rv = errno;
141 }
142 #endif
143
144 return rv;
145 }
146
147 APR_DECLARE(apr_status_t) apr_thread_mutex_trylock(apr_thread_mutex_t *mutex)
148 {
149 apr_status_t rv;
150
151 if (mutex->cond) {
152 apr_status_t rv2;
153
154 rv = pthread_mutex_lock(&mutex->mutex);
155 if (rv) {
156 #ifdef HAVE_ZOS_PTHREADS
157 rv = errno;
158 #endif
159 return rv;
160 }
161
162 if (mutex->locked) {
163 rv = APR_EBUSY;
164 }
165 else {
166 mutex->locked = 1;
167 }
168
169 rv2 = pthread_mutex_unlock(&mutex->mutex);
170 if (rv2) {
171 #ifdef HAVE_ZOS_PTHREADS
172 rv = errno;
173 #else
174 rv = rv2;
175 #endif
176 }
177
178 return rv;
179 }
180
181 rv = pthread_mutex_trylock(&mutex->mutex);
182 if (rv) {
183 #ifdef HAVE_ZOS_PTHREADS
184 rv = errno;
185 #endif
186 return (rv == EBUSY) ? APR_EBUSY : rv;
187 }
188
189 return APR_SUCCESS;
190 }
191
192 APR_DECLARE(apr_status_t) apr_thread_mutex_timedlock(apr_thread_mutex_t *mutex,
193 apr_interval_time_t timeout)
194 {
195 apr_status_t rv = APR_ENOTIMPL;
196 #if APR_HAS_TIMEDLOCKS
197
198 #ifdef HAVE_PTHREAD_MUTEX_TIMEDLOCK
199 if (timeout <= 0) {
200 rv = pthread_mutex_trylock(&mutex->mutex);
201 if (rv) {
202 #ifdef HAVE_ZOS_PTHREADS
203 rv = errno;
204 #endif
205 if (rv == EBUSY) {
206 rv = APR_TIMEUP;
207 }
208 }
209 }
210 else {
211 struct timespec abstime;
212
213 timeout += apr_time_now();
214 abstime.tv_sec = apr_time_sec(timeout);
215 abstime.tv_nsec = apr_time_usec(timeout) * 1000; /* nanoseconds */
216
217 rv = pthread_mutex_timedlock(&mutex->mutex, &abstime);
218 if (rv) {
219 #ifdef HAVE_ZOS_PTHREADS
220 rv = errno;
221 #endif
222 if (rv == ETIMEDOUT) {
223 rv = APR_TIMEUP;
224 }
225 }
226 }
227
228 #else /* HAVE_PTHREAD_MUTEX_TIMEDLOCK */
229
230 if (mutex->cond) {
231 rv = pthread_mutex_lock(&mutex->mutex);
232 if (rv) {
233 #ifdef HAVE_ZOS_PTHREADS
234 rv = errno;
235 #endif
236 return rv;
237 }
238
239 if (mutex->locked) {
240 if (timeout <= 0) {
241 rv = APR_TIMEUP;
242 }
243 else {
244 mutex->num_waiters++;
245 do {
246 rv = apr_thread_cond_timedwait(mutex->cond, mutex,
247 timeout);
248 if (rv) {
249 #ifdef HAVE_ZOS_PTHREADS
250 rv = errno;
251 #endif
252 break;
253 }
254 } while (mutex->locked);
255 mutex->num_waiters--;
256 }
257 if (rv) {
258 pthread_mutex_unlock(&mutex->mutex);
259 return rv;
260 }
261 }
262
263 mutex->locked = 1;
264
265 rv = pthread_mutex_unlock(&mutex->mutex);
266 if (rv) {
267 #ifdef HAVE_ZOS_PTHREADS
268 rv = errno;
269 #endif
270 return rv;
271 }
272 }
273
274 #endif /* HAVE_PTHREAD_MUTEX_TIMEDLOCK */
275
276 #endif /* APR_HAS_TIMEDLOCKS */
277 return rv;
278 }
279
280 APR_DECLARE(apr_status_t) apr_thread_mutex_unlock(apr_thread_mutex_t *mutex)
281 {
282 apr_status_t status;
283
284 if (mutex->cond) {
285 status = pthread_mutex_lock(&mutex->mutex);
286 if (status) {
287 #ifdef HAVE_ZOS_PTHREADS
288 status = errno;
289 #endif
290 return status;
291 }
292
293 if (!mutex->locked) {
294 status = APR_EINVAL;
295 }
296 else if (mutex->num_waiters) {
297 status = apr_thread_cond_signal(mutex->cond);
298 }
299 if (status) {
300 pthread_mutex_unlock(&mutex->mutex);
301 return status;
302 }
303
304 mutex->locked = 0;
305 }
306
307 status = pthread_mutex_unlock(&mutex->mutex);
308 #ifdef HAVE_ZOS_PTHREADS
309 if (status) {
310 status = errno;
311 }
312 #endif
313
314 return status;
315 }
316
317 APR_DECLARE(apr_status_t) apr_thread_mutex_destroy(apr_thread_mutex_t *mutex)
318 {
319 apr_status_t rv, rv2 = APR_SUCCESS;
320
321 if (mutex->cond) {
322 rv2 = apr_thread_cond_destroy(mutex->cond);
323 }
324 rv = apr_pool_cleanup_run(mutex->pool, mutex, thread_mutex_cleanup);
325 if (rv == APR_SUCCESS) {
326 rv = rv2;
327 }
328
329 return rv;
330 }
331
332 APR_POOL_IMPLEMENT_ACCESSOR(thread_mutex)
333
334 #endif /* APR_HAS_THREADS */