upload http
[bottlenecks.git] / rubbos / app / httpd-2.0.64 / srclib / apr / test / testmutexscope.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 <assert.h>
18 #include <errno.h>
19 #include <stdio.h>
20 #include <stdlib.h>
21
22 #include "apr.h"
23 #include "apr_general.h"
24 #include "apr_proc_mutex.h"
25 #include "apr_global_mutex.h"
26 #include "apr_thread_proc.h"
27
28 #if !APR_HAS_THREADS
29 int main(void)
30 {
31     printf("This test requires APR thread support.\n");
32     return 0;
33 }
34
35 #else /* APR_HAS_THREADS */
36
37 static apr_thread_mutex_t *thread_mutex;
38 static apr_proc_mutex_t *proc_mutex;
39 static apr_global_mutex_t *global_mutex;
40 static apr_pool_t *p;
41 static volatile int counter;
42 typedef enum {TEST_GLOBAL, TEST_PROC} test_mode_e;
43
44 static void lock_init(apr_lockmech_e mech, test_mode_e test_mode)
45 {
46     if (test_mode == TEST_PROC) {
47         assert(apr_proc_mutex_create(&proc_mutex,
48                                      NULL,
49                                      mech,
50                                      p) == APR_SUCCESS);
51     }
52     else {
53         assert(apr_global_mutex_create(&global_mutex,
54                                        NULL,
55                                        mech,
56                                        p) == APR_SUCCESS);
57     }
58 }
59
60 static void lock_destroy(test_mode_e test_mode)
61 {
62     if (test_mode == TEST_PROC) {
63         assert(apr_proc_mutex_destroy(proc_mutex) == APR_SUCCESS);
64     }
65     else {
66         assert(apr_global_mutex_destroy(global_mutex) == APR_SUCCESS);
67     }
68 }
69
70 static void lock_grab(test_mode_e test_mode)
71 {
72     if (test_mode == TEST_PROC) {
73         assert(apr_proc_mutex_lock(proc_mutex) == APR_SUCCESS);
74     }
75     else {
76         assert(apr_global_mutex_lock(global_mutex) == APR_SUCCESS);
77     }
78 }
79
80 static void lock_release(test_mode_e test_mode)
81 {
82     if (test_mode == TEST_PROC) {
83         assert(apr_proc_mutex_unlock(proc_mutex) == APR_SUCCESS);
84     }
85     else {
86         assert(apr_global_mutex_unlock(global_mutex) == APR_SUCCESS);
87     }
88 }
89
90 static void * APR_THREAD_FUNC eachThread(apr_thread_t *id, void *p)
91 {
92     test_mode_e test_mode = (test_mode_e)p;
93
94     lock_grab(test_mode);
95     ++counter;
96     assert(apr_thread_mutex_lock(thread_mutex) == APR_SUCCESS);
97     assert(apr_thread_mutex_unlock(thread_mutex) == APR_SUCCESS);
98     lock_release(test_mode);
99     return NULL;
100 }
101
102 static void test_mech_mode(apr_lockmech_e mech, const char *mech_name,
103                            test_mode_e test_mode)
104 {
105   apr_thread_t *threads[20];
106   int numThreads = 5;
107   int i;
108   apr_status_t rv;
109
110   printf("Trying %s mutexes with mechanism `%s'...\n",
111          test_mode == TEST_GLOBAL ? "global" : "proc", mech_name);
112
113   assert(numThreads <= sizeof(threads) / sizeof(threads[0]));
114
115   assert(apr_pool_create(&p, NULL) == APR_SUCCESS);
116
117   assert(apr_thread_mutex_create(&thread_mutex, 0, p) == APR_SUCCESS);
118   assert(apr_thread_mutex_lock(thread_mutex) == APR_SUCCESS);
119   
120   lock_init(mech, test_mode);
121
122   counter = 0;
123
124   i = 0;
125   while (i < numThreads)
126   {
127     rv = apr_thread_create(&threads[i],
128                            NULL,
129                            eachThread,
130                            (void *)test_mode,
131                            p);
132     if (rv != APR_SUCCESS) {
133       fprintf(stderr, "apr_thread_create->%d\n", rv);
134       exit(1);
135     }
136     ++i;
137   }
138
139   apr_sleep(apr_time_from_sec(5));
140
141   if (test_mode == TEST_PROC) {
142       printf("  Mutex mechanism `%s' is %sglobal in scope on this platform.\n",
143              mech_name, counter == 1 ? "" : "not ");
144   }
145   else {
146       if (counter != 1) {
147           fprintf(stderr, "\n!!!apr_global_mutex operations are broken on this "
148                   "platform for mutex mechanism `%s'!\n"
149                   "They don't block out threads within the same process.\n",
150                   mech_name);
151           fprintf(stderr, "counter value: %d\n", counter);
152           exit(1);
153       }
154       else {
155           printf("  no problems encountered...\n");
156       }
157   }
158   
159   assert(apr_thread_mutex_unlock(thread_mutex) == APR_SUCCESS);
160
161   i = 0;
162   while (i < numThreads)
163   {
164     apr_status_t ignored;
165
166     rv = apr_thread_join(&ignored,
167                          threads[i]);
168     assert(rv == APR_SUCCESS);
169     ++i;
170   }
171
172   lock_destroy(test_mode);
173   apr_thread_mutex_destroy(thread_mutex);
174   apr_pool_destroy(p);
175 }
176
177 static void test_mech(apr_lockmech_e mech, const char *mech_name)
178 {
179     test_mech_mode(mech, mech_name, TEST_PROC);
180     test_mech_mode(mech, mech_name, TEST_GLOBAL);
181 }
182
183 int main(void)
184 {
185     struct {
186         apr_lockmech_e mech;
187         const char *mech_name;
188     } lockmechs[] = {
189         {APR_LOCK_DEFAULT, "default"}
190 #if APR_HAS_FLOCK_SERIALIZE
191         ,{APR_LOCK_FLOCK, "flock"}
192 #endif
193 #if APR_HAS_SYSVSEM_SERIALIZE
194         ,{APR_LOCK_SYSVSEM, "sysvsem"}
195 #endif
196 #if APR_HAS_POSIXSEM_SERIALIZE
197         ,{APR_LOCK_POSIXSEM, "posix"}
198 #endif
199 #if APR_HAS_FCNTL_SERIALIZE
200         ,{APR_LOCK_FCNTL, "fcntl"}
201 #endif
202 #if APR_HAS_PROC_PTHREAD_SERIALIZE
203         ,{APR_LOCK_PROC_PTHREAD, "proc_pthread"}
204 #endif
205     };
206     int i;
207         
208     assert(apr_initialize() == APR_SUCCESS);
209
210     for (i = 0; i < sizeof(lockmechs) / sizeof(lockmechs[0]); i++) {
211         test_mech(lockmechs[i].mech, lockmechs[i].mech_name);
212     }
213     
214     apr_terminate();
215     return 0;
216 }
217
218 #endif /* APR_HAS_THREADS */