upload http
[bottlenecks.git] / rubbos / app / httpd-2.0.64 / srclib / apr-util / test / testreslist.c
1 /* Copyright 2000-2005 The Apache Software Foundation or its licensors, as
2  * applicable.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * 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 <stdio.h>
18 #include <stdlib.h>
19 #include "apr_reslist.h"
20 #include "apr_thread_proc.h"
21
22 #if !APR_HAS_THREADS
23
24 int main(void)
25 {
26     fprintf(stderr, "this program requires APR thread support\n");
27     return 0;
28 }
29
30 #else
31
32 #define RESLIST_MIN   3
33 #define RESLIST_SMAX 10
34 #define RESLIST_HMAX 20
35 #define RESLIST_TTL  APR_TIME_C(350000) /* 35 ms */
36 #define CONSUMER_THREADS 25
37 #define CONSUMER_ITERATIONS 250
38 #define CONSTRUCT_SLEEP_TIME  APR_TIME_C(250000) /* 25 ms */
39 #define DESTRUCT_SLEEP_TIME   APR_TIME_C(100000) /* 10 ms */
40 #define WORK_DELAY_SLEEP_TIME APR_TIME_C(150000) /* 15 ms */
41
42 typedef struct {
43     apr_interval_time_t sleep_upon_construct;
44     apr_interval_time_t sleep_upon_destruct;
45     int c_count;
46     int d_count;
47 } my_parameters_t;
48
49 typedef struct {
50     int id;
51 } my_resource_t;
52
53 static apr_status_t my_constructor(void **resource, void *params,
54                                    apr_pool_t *pool)
55 {
56     my_resource_t *res;
57     my_parameters_t *my_params = params;
58
59     /* Create some resource */
60     res = apr_palloc(pool, sizeof(*res));
61     res->id = my_params->c_count++;
62
63     printf("++ constructing new resource [id:%d]\n", res->id);
64
65     /* Sleep for awhile, to simulate construction overhead. */
66     apr_sleep(my_params->sleep_upon_construct);
67
68     /* Set the resource so it can be managed by the reslist */
69     *resource = res;
70     return APR_SUCCESS;
71 }
72
73 static apr_status_t my_destructor(void *resource, void *params,
74                                   apr_pool_t *pool)
75 {
76     my_resource_t *res = resource;
77     my_parameters_t *my_params = params;
78
79     printf("-- destructing old resource [id:%d, #%d]\n", res->id,
80            my_params->d_count++);
81
82     apr_sleep(my_params->sleep_upon_destruct);
83
84     return APR_SUCCESS;
85 }
86
87 typedef struct {
88     int tid;
89     apr_reslist_t *reslist;
90     apr_interval_time_t work_delay_sleep;
91 } my_thread_info_t;
92
93 static void * APR_THREAD_FUNC resource_consuming_thread(apr_thread_t *thd,
94                                                         void *data)
95 {
96     apr_status_t rv;
97     my_thread_info_t *thread_info = data;
98     apr_reslist_t *rl = thread_info->reslist;
99     int i;
100
101     for (i = 0; i < CONSUMER_ITERATIONS; i++) {
102         my_resource_t *res;
103         rv = apr_reslist_acquire(rl, (void**)&res);
104         if (rv != APR_SUCCESS) {
105             fprintf(stderr, "Failed to retrieve resource from reslist\n");
106             apr_thread_exit(thd, rv);
107             return NULL;
108         }
109         printf("  [tid:%d,iter:%d] using resource id:%d\n", thread_info->tid,
110                i, res->id);
111         apr_sleep(thread_info->work_delay_sleep);
112         rv = apr_reslist_release(rl, res);
113         if (rv != APR_SUCCESS) {
114             fprintf(stderr, "Failed to return resource to reslist\n");
115             apr_thread_exit(thd, rv);
116             return NULL;
117         }
118     }
119
120     return APR_SUCCESS;
121 }
122
123 static apr_status_t test_reslist(apr_pool_t *parpool)
124 {
125     apr_status_t rv;
126     apr_pool_t *pool;
127     apr_reslist_t *rl;
128     my_parameters_t *params;
129     int i;
130     apr_thread_t *my_threads[CONSUMER_THREADS];
131     my_thread_info_t my_thread_info[CONSUMER_THREADS];
132
133     printf("Creating child pool.......................");
134     rv = apr_pool_create(&pool, parpool);
135     if (rv != APR_SUCCESS) {
136         fprintf(stderr, "Error creating child pool\n");
137         return rv;
138     }
139     printf("OK\n");
140
141     /* Create some parameters that will be passed into each
142      * constructor and destructor call. */
143     params = apr_pcalloc(pool, sizeof(*params));
144     params->sleep_upon_construct = CONSTRUCT_SLEEP_TIME;
145     params->sleep_upon_destruct = DESTRUCT_SLEEP_TIME;
146
147     /* We're going to want 10 blocks of data from our target rmm. */
148     printf("Creating resource list:\n"
149            " min/smax/hmax: %d/%d/%d\n"
150            " ttl: %" APR_TIME_T_FMT "\n", RESLIST_MIN, RESLIST_SMAX,
151            RESLIST_HMAX, RESLIST_TTL);
152     rv = apr_reslist_create(&rl, RESLIST_MIN, RESLIST_SMAX, RESLIST_HMAX,
153                             RESLIST_TTL, my_constructor, my_destructor,
154                             params, pool);
155     if (rv != APR_SUCCESS) { 
156         fprintf(stderr, "Error allocating shared memory block\n");
157         return rv;
158     }
159     fprintf(stdout, "OK\n");
160
161     printf("Creating %d threads", CONSUMER_THREADS);
162     for (i = 0; i < CONSUMER_THREADS; i++) {
163         putchar('.');
164         my_thread_info[i].tid = i;
165         my_thread_info[i].reslist = rl;
166         my_thread_info[i].work_delay_sleep = WORK_DELAY_SLEEP_TIME;
167         rv = apr_thread_create(&my_threads[i], NULL,
168                                resource_consuming_thread, &my_thread_info[i],
169                                pool);
170         if (rv != APR_SUCCESS) {
171             fprintf(stderr, "Failed to create thread %d\n", i);
172             return rv;
173         }
174     }
175     printf("\nDone!\n");
176
177     printf("Waiting for threads to finish");
178     for (i = 0; i < CONSUMER_THREADS; i++) {
179         apr_status_t thread_rv;
180         putchar('.');
181         apr_thread_join(&thread_rv, my_threads[i]);
182         if (rv != APR_SUCCESS) {
183             fprintf(stderr, "Failed to join thread %d\n", i);
184             return rv;
185         }
186     }
187     printf("\nDone!\n");
188
189     printf("Destroying resource list.................");
190     rv = apr_reslist_destroy(rl);
191     if (rv != APR_SUCCESS) {
192         printf("FAILED\n");
193         return rv;
194     }
195     printf("OK\n");
196
197     apr_pool_destroy(pool);
198
199     return APR_SUCCESS;
200 }
201
202
203 int main(void)
204 {
205     apr_status_t rv;
206     apr_pool_t *pool;
207     char errmsg[200];
208
209     apr_initialize();
210     
211     printf("APR Resource List Test\n");
212     printf("======================\n\n");
213
214     printf("Initializing the pool............................"); 
215     if (apr_pool_create(&pool, NULL) != APR_SUCCESS) {
216         printf("could not initialize pool\n");
217         exit(-1);
218     }
219     printf("OK\n");
220
221     rv = test_reslist(pool);
222     if (rv != APR_SUCCESS) {
223         printf("Resource list test FAILED: [%d] %s\n",
224                rv, apr_strerror(rv, errmsg, sizeof(errmsg)));
225         exit(-2);
226     }
227     printf("Resource list test passed!\n");
228
229     return 0;
230 }
231
232 #endif /* APR_HAS_THREADS */