]> CyberLeo.Net >> Repos - FreeBSD/releng/10.2.git/blob - contrib/apr/locks/unix/global_mutex.c
- Copy stable/10@285827 to releng/10.2 in preparation for 10.2-RC1
[FreeBSD/releng/10.2.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 #include "apr_strings.h"
19 #include "apr_arch_global_mutex.h"
20 #include "apr_proc_mutex.h"
21 #include "apr_thread_mutex.h"
22 #include "apr_portable.h"
23
24 static apr_status_t global_mutex_cleanup(void *data)
25 {
26     apr_global_mutex_t *m = (apr_global_mutex_t *)data;
27     apr_status_t rv;
28
29     rv = apr_proc_mutex_destroy(m->proc_mutex);
30
31 #if APR_HAS_THREADS
32     if (m->thread_mutex) {
33         if (rv != APR_SUCCESS) {
34             (void)apr_thread_mutex_destroy(m->thread_mutex);
35         }
36         else {
37             rv = apr_thread_mutex_destroy(m->thread_mutex);
38         }
39     }
40 #endif /* APR_HAS_THREADS */
41
42     return rv;
43 }
44
45 APR_DECLARE(apr_status_t) apr_global_mutex_create(apr_global_mutex_t **mutex,
46                                                   const char *fname,
47                                                   apr_lockmech_e mech,
48                                                   apr_pool_t *pool)
49 {
50     apr_status_t rv;
51     apr_global_mutex_t *m;
52
53     m = (apr_global_mutex_t *)apr_palloc(pool, sizeof(*m));
54     m->pool = pool;
55
56     rv = apr_proc_mutex_create(&m->proc_mutex, fname, mech, m->pool);
57     if (rv != APR_SUCCESS) {
58         return rv;
59     }
60
61 #if APR_HAS_THREADS
62     if (m->proc_mutex->inter_meth->flags & APR_PROCESS_LOCK_MECH_IS_GLOBAL) {
63         m->thread_mutex = NULL; /* We don't need a thread lock. */
64     }
65     else {
66         rv = apr_thread_mutex_create(&m->thread_mutex,
67                                      APR_THREAD_MUTEX_DEFAULT, m->pool);
68         if (rv != APR_SUCCESS) {
69             rv = apr_proc_mutex_destroy(m->proc_mutex);
70             return rv;
71         }
72     }
73 #endif /* APR_HAS_THREADS */
74
75     apr_pool_cleanup_register(m->pool, (void *)m,
76                               global_mutex_cleanup, apr_pool_cleanup_null);
77     *mutex = m;
78     return APR_SUCCESS;
79 }
80
81 APR_DECLARE(apr_status_t) apr_global_mutex_child_init(
82                               apr_global_mutex_t **mutex,
83                               const char *fname,
84                               apr_pool_t *pool)
85 {
86     apr_status_t rv;
87
88     rv = apr_proc_mutex_child_init(&((*mutex)->proc_mutex), fname, pool);
89     return rv;
90 }
91
92 APR_DECLARE(apr_status_t) apr_global_mutex_lock(apr_global_mutex_t *mutex)
93 {
94     apr_status_t rv;
95
96 #if APR_HAS_THREADS
97     if (mutex->thread_mutex) {
98         rv = apr_thread_mutex_lock(mutex->thread_mutex);
99         if (rv != APR_SUCCESS) {
100             return rv;
101         }
102     }
103 #endif /* APR_HAS_THREADS */
104
105     rv = apr_proc_mutex_lock(mutex->proc_mutex);
106
107 #if APR_HAS_THREADS
108     if (rv != APR_SUCCESS) {
109         if (mutex->thread_mutex) {
110             (void)apr_thread_mutex_unlock(mutex->thread_mutex);
111         }
112     }
113 #endif /* APR_HAS_THREADS */
114
115     return rv;
116 }
117
118 APR_DECLARE(apr_status_t) apr_global_mutex_trylock(apr_global_mutex_t *mutex)
119 {
120     apr_status_t rv;
121
122 #if APR_HAS_THREADS
123     if (mutex->thread_mutex) {
124         rv = apr_thread_mutex_trylock(mutex->thread_mutex);
125         if (rv != APR_SUCCESS) {
126             return rv;
127         }
128     }
129 #endif /* APR_HAS_THREADS */
130
131     rv = apr_proc_mutex_trylock(mutex->proc_mutex);
132
133 #if APR_HAS_THREADS
134     if (rv != APR_SUCCESS) {
135         if (mutex->thread_mutex) {
136             (void)apr_thread_mutex_unlock(mutex->thread_mutex);
137         }
138     }
139 #endif /* APR_HAS_THREADS */
140
141     return rv;
142 }
143
144 APR_DECLARE(apr_status_t) apr_global_mutex_unlock(apr_global_mutex_t *mutex)
145 {
146     apr_status_t rv;
147
148     rv = apr_proc_mutex_unlock(mutex->proc_mutex);
149 #if APR_HAS_THREADS
150     if (mutex->thread_mutex) {
151         if (rv != APR_SUCCESS) {
152             (void)apr_thread_mutex_unlock(mutex->thread_mutex);
153         }
154         else {
155             rv = apr_thread_mutex_unlock(mutex->thread_mutex);
156         }
157     }
158 #endif /* APR_HAS_THREADS */
159     return rv;
160 }
161
162 APR_DECLARE(apr_status_t) apr_os_global_mutex_get(apr_os_global_mutex_t *ospmutex,
163                                                 apr_global_mutex_t *pmutex)
164 {
165     ospmutex->pool = pmutex->pool;
166     ospmutex->proc_mutex = pmutex->proc_mutex;
167 #if APR_HAS_THREADS
168     ospmutex->thread_mutex = pmutex->thread_mutex;
169 #endif
170     return APR_SUCCESS;
171 }
172
173 APR_DECLARE(apr_status_t) apr_global_mutex_destroy(apr_global_mutex_t *mutex)
174 {
175     return apr_pool_cleanup_run(mutex->pool, mutex, global_mutex_cleanup);
176 }
177
178 APR_DECLARE(const char *) apr_global_mutex_lockfile(apr_global_mutex_t *mutex)
179 {
180     return apr_proc_mutex_lockfile(mutex->proc_mutex);
181 }
182
183 APR_DECLARE(const char *) apr_global_mutex_name(apr_global_mutex_t *mutex)
184 {
185     return apr_proc_mutex_name(mutex->proc_mutex);
186 }
187
188 APR_POOL_IMPLEMENT_ACCESSOR(global_mutex)