xref: /aosp_15_r20/external/cronet/third_party/apache-portable-runtime/src/locks/unix/global_mutex.c (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
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 
global_mutex_cleanup(void * data)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 
apr_global_mutex_create(apr_global_mutex_t ** mutex,const char * fname,apr_lockmech_e mech,apr_pool_t * pool)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 
apr_global_mutex_child_init(apr_global_mutex_t ** mutex,const char * fname,apr_pool_t * pool)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 
apr_global_mutex_lock(apr_global_mutex_t * mutex)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 
apr_global_mutex_trylock(apr_global_mutex_t * mutex)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 
apr_global_mutex_unlock(apr_global_mutex_t * mutex)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 
apr_os_global_mutex_get(apr_os_global_mutex_t * ospmutex,apr_global_mutex_t * pmutex)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 
apr_global_mutex_destroy(apr_global_mutex_t * mutex)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 
apr_global_mutex_lockfile(apr_global_mutex_t * mutex)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 
apr_global_mutex_name(apr_global_mutex_t * mutex)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)
189