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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
18 #include "apr_private.h"
19 #include "apr_general.h"
20 #include "apr_strings.h"
21 #include "apr_portable.h"
22 #include "apr_arch_file_io.h"
23 #include "apr_arch_proc_mutex.h"
24 #include "apr_arch_misc.h"
26 static apr_status_t proc_mutex_cleanup(void *mutex_)
28 apr_proc_mutex_t *mutex = mutex_;
31 if (CloseHandle(mutex->handle) == 0) {
32 return apr_get_os_error();
38 APR_DECLARE(apr_status_t) apr_proc_mutex_create(apr_proc_mutex_t **mutex,
46 /* res_name_from_filename turns fname into a pseduo-name
47 * without slashes or backslashes, and prepends the \global
48 * prefix on Win2K and later
51 mutexkey = res_name_from_filename(fname, 1, pool);
57 #if APR_HAS_UNICODE_FS
60 hMutex = CreateMutexW(NULL, FALSE, mutexkey);
66 hMutex = CreateMutexA(NULL, FALSE, mutexkey);
71 return apr_get_os_error();
74 *mutex = (apr_proc_mutex_t *)apr_palloc(pool, sizeof(apr_proc_mutex_t));
75 (*mutex)->pool = pool;
76 (*mutex)->handle = hMutex;
77 (*mutex)->fname = fname;
78 apr_pool_cleanup_register((*mutex)->pool, *mutex,
79 proc_mutex_cleanup, apr_pool_cleanup_null);
83 APR_DECLARE(apr_status_t) apr_proc_mutex_child_init(apr_proc_mutex_t **mutex,
91 /* Reinitializing unnamed mutexes is a noop in the Unix code. */
95 /* res_name_from_filename turns file into a pseudo-name
96 * without slashes or backslashes, and prepends the \global
97 * prefix on Win2K and later
99 mutexkey = res_name_from_filename(fname, 1, pool);
101 #if defined(_WIN32_WCE)
102 hMutex = CreateMutex(NULL, FALSE, mutexkey);
103 if (hMutex && ERROR_ALREADY_EXISTS != GetLastError()) {
106 SetLastError(ERROR_FILE_NOT_FOUND);
109 #if APR_HAS_UNICODE_FS
112 hMutex = OpenMutexW(MUTEX_ALL_ACCESS, FALSE, mutexkey);
118 hMutex = OpenMutexA(MUTEX_ALL_ACCESS, FALSE, mutexkey);
124 return apr_get_os_error();
127 *mutex = (apr_proc_mutex_t *)apr_palloc(pool, sizeof(apr_proc_mutex_t));
128 (*mutex)->pool = pool;
129 (*mutex)->handle = hMutex;
130 (*mutex)->fname = fname;
131 apr_pool_cleanup_register((*mutex)->pool, *mutex,
132 proc_mutex_cleanup, apr_pool_cleanup_null);
136 APR_DECLARE(apr_status_t) apr_proc_mutex_lock(apr_proc_mutex_t *mutex)
140 rv = WaitForSingleObject(mutex->handle, INFINITE);
142 if (rv == WAIT_OBJECT_0 || rv == WAIT_ABANDONED) {
145 return apr_get_os_error();
148 APR_DECLARE(apr_status_t) apr_proc_mutex_trylock(apr_proc_mutex_t *mutex)
152 rv = WaitForSingleObject(mutex->handle, 0);
154 if (rv == WAIT_OBJECT_0 || rv == WAIT_ABANDONED) {
157 else if (rv == WAIT_TIMEOUT) {
160 return apr_get_os_error();
163 APR_DECLARE(apr_status_t) apr_proc_mutex_unlock(apr_proc_mutex_t *mutex)
165 if (ReleaseMutex(mutex->handle) == 0) {
166 return apr_get_os_error();
171 APR_DECLARE(apr_status_t) apr_proc_mutex_destroy(apr_proc_mutex_t *mutex)
175 stat = proc_mutex_cleanup(mutex);
176 if (stat == APR_SUCCESS) {
177 apr_pool_cleanup_kill(mutex->pool, mutex, proc_mutex_cleanup);
182 APR_DECLARE(const char *) apr_proc_mutex_lockfile(apr_proc_mutex_t *mutex)
187 APR_DECLARE(const char *) apr_proc_mutex_name(apr_proc_mutex_t *mutex)
192 APR_DECLARE(const char *) apr_proc_mutex_defname(void)
197 APR_POOL_IMPLEMENT_ACCESSOR(proc_mutex)
199 /* Implement OS-specific accessors defined in apr_portable.h */
201 APR_DECLARE(apr_status_t) apr_os_proc_mutex_get(apr_os_proc_mutex_t *ospmutex,
202 apr_proc_mutex_t *mutex)
204 *ospmutex = mutex->handle;
208 APR_DECLARE(apr_status_t) apr_os_proc_mutex_put(apr_proc_mutex_t **pmutex,
209 apr_os_proc_mutex_t *ospmutex,
215 if ((*pmutex) == NULL) {
216 (*pmutex) = (apr_proc_mutex_t *)apr_palloc(pool,
217 sizeof(apr_proc_mutex_t));
218 (*pmutex)->pool = pool;
220 (*pmutex)->handle = *ospmutex;