upload http
[bottlenecks.git] / rubbos / app / httpd-2.0.64 / srclib / apr / locks / win32 / proc_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_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"
25
26 static apr_status_t proc_mutex_cleanup(void *mutex_)
27 {
28     apr_proc_mutex_t *mutex = mutex_;
29
30     if (mutex->handle) {
31         if (CloseHandle(mutex->handle) == 0) {
32             return apr_get_os_error();
33         }
34     }
35     return APR_SUCCESS;
36 }
37
38 APR_DECLARE(apr_status_t) apr_proc_mutex_create(apr_proc_mutex_t **mutex,
39                                                 const char *fname,
40                                                 apr_lockmech_e mech,
41                                                 apr_pool_t *pool)
42 {
43     HANDLE hMutex;
44     void *mutexkey;
45
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
49      */
50     if (fname) {
51         mutexkey = res_name_from_filename(fname, 1, pool);
52     }
53     else {
54         mutexkey = NULL;
55     }
56
57 #if APR_HAS_UNICODE_FS
58     IF_WIN_OS_IS_UNICODE
59     {
60         hMutex = CreateMutexW(NULL, FALSE, mutexkey);
61     }
62 #endif
63 #if APR_HAS_ANSI_FS
64     ELSE_WIN_OS_IS_ANSI
65     {
66         hMutex = CreateMutexA(NULL, FALSE, mutexkey);
67     }
68 #endif
69
70     if (!hMutex) {
71         return apr_get_os_error();
72     }
73
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);
80     return APR_SUCCESS;
81 }
82
83 APR_DECLARE(apr_status_t) apr_proc_mutex_child_init(apr_proc_mutex_t **mutex,
84                                                     const char *fname,
85                                                     apr_pool_t *pool)
86 {
87     HANDLE hMutex;
88     void *mutexkey;
89
90     if (!fname) {
91         /* Reinitializing unnamed mutexes is a noop in the Unix code. */
92         return APR_SUCCESS;
93     }
94
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
98      */
99     mutexkey = res_name_from_filename(fname, 1, pool);
100
101 #if defined(_WIN32_WCE)
102     hMutex = CreateMutex(NULL, FALSE, mutexkey);
103     if (hMutex && ERROR_ALREADY_EXISTS != GetLastError()) {
104         CloseHandle(hMutex);
105         hMutex = NULL;
106         SetLastError(ERROR_FILE_NOT_FOUND);
107     }
108 #else
109 #if APR_HAS_UNICODE_FS
110     IF_WIN_OS_IS_UNICODE
111     {
112         hMutex = OpenMutexW(MUTEX_ALL_ACCESS, FALSE, mutexkey);
113     }
114 #endif
115 #if APR_HAS_ANSI_FS
116     ELSE_WIN_OS_IS_ANSI
117     {
118         hMutex = OpenMutexA(MUTEX_ALL_ACCESS, FALSE, mutexkey);
119     }
120 #endif
121 #endif
122
123     if (!hMutex) {
124         return apr_get_os_error();
125     }
126
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);
133     return APR_SUCCESS;
134 }
135     
136 APR_DECLARE(apr_status_t) apr_proc_mutex_lock(apr_proc_mutex_t *mutex)
137 {
138     DWORD rv;
139
140     rv = WaitForSingleObject(mutex->handle, INFINITE);
141
142     if (rv == WAIT_OBJECT_0 || rv == WAIT_ABANDONED) {
143         return APR_SUCCESS;
144     }
145     return apr_get_os_error();
146 }
147
148 APR_DECLARE(apr_status_t) apr_proc_mutex_trylock(apr_proc_mutex_t *mutex)
149 {
150     DWORD rv;
151
152     rv = WaitForSingleObject(mutex->handle, 0);
153
154     if (rv == WAIT_OBJECT_0 || rv == WAIT_ABANDONED) {
155         return APR_SUCCESS;
156     } 
157     else if (rv == WAIT_TIMEOUT) {
158         return APR_EBUSY;
159     }
160     return apr_get_os_error();
161 }
162
163 APR_DECLARE(apr_status_t) apr_proc_mutex_unlock(apr_proc_mutex_t *mutex)
164 {
165     if (ReleaseMutex(mutex->handle) == 0) {
166         return apr_get_os_error();
167     }
168     return APR_SUCCESS;
169 }
170
171 APR_DECLARE(apr_status_t) apr_proc_mutex_destroy(apr_proc_mutex_t *mutex)
172 {
173     apr_status_t stat;
174
175     stat = proc_mutex_cleanup(mutex);
176     if (stat == APR_SUCCESS) {
177         apr_pool_cleanup_kill(mutex->pool, mutex, proc_mutex_cleanup);
178     }
179     return stat;
180 }
181
182 APR_DECLARE(const char *) apr_proc_mutex_lockfile(apr_proc_mutex_t *mutex)
183 {
184     return NULL;
185 }
186
187 APR_DECLARE(const char *) apr_proc_mutex_name(apr_proc_mutex_t *mutex)
188 {
189     return mutex->fname;
190 }
191
192 APR_DECLARE(const char *) apr_proc_mutex_defname(void)
193 {
194     return "win32mutex";
195 }
196
197 APR_POOL_IMPLEMENT_ACCESSOR(proc_mutex)
198
199 /* Implement OS-specific accessors defined in apr_portable.h */
200
201 APR_DECLARE(apr_status_t) apr_os_proc_mutex_get(apr_os_proc_mutex_t *ospmutex,
202                                                 apr_proc_mutex_t *mutex)
203 {
204     *ospmutex = mutex->handle;
205     return APR_SUCCESS;
206 }
207
208 APR_DECLARE(apr_status_t) apr_os_proc_mutex_put(apr_proc_mutex_t **pmutex,
209                                                 apr_os_proc_mutex_t *ospmutex,
210                                                 apr_pool_t *pool)
211 {
212     if (pool == NULL) {
213         return APR_ENOPOOL;
214     }
215     if ((*pmutex) == NULL) {
216         (*pmutex) = (apr_proc_mutex_t *)apr_palloc(pool,
217                                                    sizeof(apr_proc_mutex_t));
218         (*pmutex)->pool = pool;
219     }
220     (*pmutex)->handle = *ospmutex;
221     return APR_SUCCESS;
222 }
223