]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/apr/locks/unix/global_mutex.c
Update apr to 1.7.0. See contrib/apr/CHANGES for a summary of changes.
[FreeBSD/FreeBSD.git] / contrib / apr / locks / unix / global_mutex.c
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.h"
18
19 #include "apr_strings.h"
20 #include "apr_arch_global_mutex.h"
21 #include "apr_proc_mutex.h"
22 #include "apr_thread_mutex.h"
23 #include "apr_portable.h"
24
25 static apr_status_t global_mutex_cleanup(void *data)
26 {
27     apr_global_mutex_t *m = (apr_global_mutex_t *)data;
28     apr_status_t rv;
29
30     rv = apr_proc_mutex_destroy(m->proc_mutex);
31
32 #if APR_HAS_THREADS
33     if (m->thread_mutex) {
34         if (rv != APR_SUCCESS) {
35             (void)apr_thread_mutex_destroy(m->thread_mutex);
36         }
37         else {
38             rv = apr_thread_mutex_destroy(m->thread_mutex);
39         }
40     }
41 #endif /* APR_HAS_THREADS */
42
43     return rv;
44 }
45
46 APR_DECLARE(apr_status_t) apr_global_mutex_create(apr_global_mutex_t **mutex,
47                                                   const char *fname,
48                                                   apr_lockmech_e mech,
49                                                   apr_pool_t *pool)
50 {
51     apr_status_t rv;
52     apr_global_mutex_t *m;
53
54     m = (apr_global_mutex_t *)apr_palloc(pool, sizeof(*m));
55     m->pool = pool;
56
57     rv = apr_proc_mutex_create(&m->proc_mutex, fname, mech, m->pool);
58     if (rv != APR_SUCCESS) {
59         return rv;
60     }
61
62 #if APR_HAS_THREADS
63     if (m->proc_mutex->meth->flags & APR_PROCESS_LOCK_MECH_IS_GLOBAL) {
64         m->thread_mutex = NULL; /* We don't need a thread lock. */
65     }
66     else {
67         rv = apr_thread_mutex_create(&m->thread_mutex,
68                                      APR_THREAD_MUTEX_DEFAULT, m->pool);
69         if (rv != APR_SUCCESS) {
70             rv = apr_proc_mutex_destroy(m->proc_mutex);
71             return rv;
72         }
73     }
74 #endif /* APR_HAS_THREADS */
75
76     apr_pool_cleanup_register(m->pool, (void *)m,
77                               global_mutex_cleanup, apr_pool_cleanup_null);
78     *mutex = m;
79     return APR_SUCCESS;
80 }
81
82 APR_DECLARE(apr_status_t) apr_global_mutex_child_init(
83                               apr_global_mutex_t **mutex,
84                               const char *fname,
85                               apr_pool_t *pool)
86 {
87     apr_status_t rv;
88
89     rv = apr_proc_mutex_child_init(&((*mutex)->proc_mutex), fname, pool);
90     return rv;
91 }
92
93 APR_DECLARE(apr_status_t) apr_global_mutex_lock(apr_global_mutex_t *mutex)
94 {
95     apr_status_t rv;
96
97 #if APR_HAS_THREADS
98     if (mutex->thread_mutex) {
99         rv = apr_thread_mutex_lock(mutex->thread_mutex);
100         if (rv != APR_SUCCESS) {
101             return rv;
102         }
103     }
104 #endif /* APR_HAS_THREADS */
105
106     rv = apr_proc_mutex_lock(mutex->proc_mutex);
107
108 #if APR_HAS_THREADS
109     if (rv != APR_SUCCESS) {
110         if (mutex->thread_mutex) {
111             (void)apr_thread_mutex_unlock(mutex->thread_mutex);
112         }
113     }
114 #endif /* APR_HAS_THREADS */
115
116     return rv;
117 }
118
119 APR_DECLARE(apr_status_t) apr_global_mutex_trylock(apr_global_mutex_t *mutex)
120 {
121     apr_status_t rv;
122
123 #if APR_HAS_THREADS
124     if (mutex->thread_mutex) {
125         rv = apr_thread_mutex_trylock(mutex->thread_mutex);
126         if (rv != APR_SUCCESS) {
127             return rv;
128         }
129     }
130 #endif /* APR_HAS_THREADS */
131
132     rv = apr_proc_mutex_trylock(mutex->proc_mutex);
133
134 #if APR_HAS_THREADS
135     if (rv != APR_SUCCESS) {
136         if (mutex->thread_mutex) {
137             (void)apr_thread_mutex_unlock(mutex->thread_mutex);
138         }
139     }
140 #endif /* APR_HAS_THREADS */
141
142     return rv;
143 }
144
145 APR_DECLARE(apr_status_t) apr_global_mutex_timedlock(apr_global_mutex_t *mutex,
146                                                  apr_interval_time_t timeout)
147 {
148 #if APR_HAS_TIMEDLOCKS
149     apr_status_t rv;
150
151 #if APR_HAS_THREADS
152     if (mutex->thread_mutex) {
153         apr_time_t expiry = 0;
154         if (timeout > 0) {
155             expiry = apr_time_now() + timeout;
156         }
157         rv = apr_thread_mutex_timedlock(mutex->thread_mutex, timeout);
158         if (rv != APR_SUCCESS) {
159             return rv;
160         }
161         if (expiry) {
162             timeout = expiry - apr_time_now();
163             if (timeout < 0) {
164                 timeout = 0;
165             }
166         }
167     }
168 #endif /* APR_HAS_THREADS */
169
170     rv = apr_proc_mutex_timedlock(mutex->proc_mutex, timeout);
171
172 #if APR_HAS_THREADS
173     if (rv != APR_SUCCESS) {
174         if (mutex->thread_mutex) {
175             (void)apr_thread_mutex_unlock(mutex->thread_mutex);
176         }
177     }
178 #endif /* APR_HAS_THREADS */
179
180     return rv;
181 #else  /* APR_HAS_TIMEDLOCKS */
182     return APR_ENOTIMPL;
183 #endif
184 }
185
186 APR_DECLARE(apr_status_t) apr_global_mutex_unlock(apr_global_mutex_t *mutex)
187 {
188     apr_status_t rv;
189
190     rv = apr_proc_mutex_unlock(mutex->proc_mutex);
191 #if APR_HAS_THREADS
192     if (mutex->thread_mutex) {
193         if (rv != APR_SUCCESS) {
194             (void)apr_thread_mutex_unlock(mutex->thread_mutex);
195         }
196         else {
197             rv = apr_thread_mutex_unlock(mutex->thread_mutex);
198         }
199     }
200 #endif /* APR_HAS_THREADS */
201     return rv;
202 }
203
204 APR_DECLARE(apr_status_t) apr_os_global_mutex_get(apr_os_global_mutex_t *ospmutex,
205                                                 apr_global_mutex_t *pmutex)
206 {
207     ospmutex->pool = pmutex->pool;
208     ospmutex->proc_mutex = pmutex->proc_mutex;
209 #if APR_HAS_THREADS
210     ospmutex->thread_mutex = pmutex->thread_mutex;
211 #endif
212     return APR_SUCCESS;
213 }
214
215 APR_DECLARE(apr_status_t) apr_global_mutex_destroy(apr_global_mutex_t *mutex)
216 {
217     return apr_pool_cleanup_run(mutex->pool, mutex, global_mutex_cleanup);
218 }
219
220 APR_DECLARE(const char *) apr_global_mutex_lockfile(apr_global_mutex_t *mutex)
221 {
222     return apr_proc_mutex_lockfile(mutex->proc_mutex);
223 }
224
225 APR_DECLARE(apr_lockmech_e) apr_global_mutex_mech(apr_global_mutex_t *mutex)
226 {
227     return apr_proc_mutex_mech(mutex->proc_mutex);
228 }
229
230 APR_DECLARE(const char *) apr_global_mutex_name(apr_global_mutex_t *mutex)
231 {
232     return apr_proc_mutex_name(mutex->proc_mutex);
233 }
234
235 APR_PERMS_SET_IMPLEMENT(global_mutex)
236 {
237     apr_status_t rv;
238     apr_global_mutex_t *mutex = (apr_global_mutex_t *)theglobal_mutex;
239
240     rv = APR_PERMS_SET_FN(proc_mutex)(mutex->proc_mutex, perms, uid, gid);
241     return rv;
242 }
243
244 APR_POOL_IMPLEMENT_ACCESSOR(global_mutex)
245