~ubuntu-branches/ubuntu/feisty/apache2/feisty

« back to all changes in this revision

Viewing changes to srclib/apr/test/testshm.c

  • Committer: Bazaar Package Importer
  • Author(s): Andreas Barth
  • Date: 2006-12-09 21:05:45 UTC
  • mfrom: (0.6.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20061209210545-h70s0xaqc2v8vqr2
Tags: 2.2.3-3.2
* Non-maintainer upload.
* 043_ajp_connection_reuse: Patch from upstream Bugzilla, fixing a critical
  issue with regard to connection reuse in mod_proxy_ajp.
  Closes: #396265

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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 "testutil.h"
 
18
#include "apr_shm.h"
 
19
#include "apr_errno.h"
 
20
#include "apr_general.h"
 
21
#include "apr_lib.h"
 
22
#include "apr_strings.h"
 
23
#include "apr_thread_proc.h"
 
24
#include "apr_time.h"
 
25
#include "testshm.h"
 
26
#include "apr.h"
 
27
 
 
28
#if APR_HAVE_STDLIB_H
 
29
#include <stdlib.h>
 
30
#endif
 
31
 
 
32
#if APR_HAS_SHARED_MEMORY
 
33
 
 
34
static int msgwait(int sleep_sec, int first_box, int last_box)
 
35
{
 
36
    int i;
 
37
    int recvd = 0;
 
38
    apr_time_t start = apr_time_now();
 
39
    apr_interval_time_t sleep_duration = apr_time_from_sec(sleep_sec);
 
40
    while (apr_time_now() - start < sleep_duration) {
 
41
        for (i = first_box; i < last_box; i++) {
 
42
            if (boxes[i].msgavail && !strcmp(boxes[i].msg, MSG)) {
 
43
                recvd++;
 
44
                boxes[i].msgavail = 0; /* reset back to 0 */
 
45
                /* reset the msg field.  1024 is a magic number and it should
 
46
                 * be a macro, but I am being lazy.
 
47
                 */
 
48
                memset(boxes[i].msg, 0, 1024);
 
49
            }
 
50
        }
 
51
        apr_sleep(apr_time_make(0, 10000)); /* 10ms */
 
52
    }
 
53
    return recvd;
 
54
}
 
55
 
 
56
static void msgput(int boxnum, char *msg)
 
57
{
 
58
    apr_cpystrn(boxes[boxnum].msg, msg, strlen(msg) + 1);
 
59
    boxes[boxnum].msgavail = 1;
 
60
}
 
61
 
 
62
static void test_anon_create(abts_case *tc, void *data)
 
63
{
 
64
    apr_status_t rv;
 
65
    apr_shm_t *shm = NULL;
 
66
 
 
67
    rv = apr_shm_create(&shm, SHARED_SIZE, NULL, p);
 
68
    APR_ASSERT_SUCCESS(tc, "Error allocating shared memory block", rv);
 
69
    ABTS_PTR_NOTNULL(tc, shm);
 
70
 
 
71
    rv = apr_shm_destroy(shm);
 
72
    APR_ASSERT_SUCCESS(tc, "Error destroying shared memory block", rv);
 
73
}
 
74
 
 
75
static void test_check_size(abts_case *tc, void *data)
 
76
{
 
77
    apr_status_t rv;
 
78
    apr_shm_t *shm = NULL;
 
79
    apr_size_t retsize;
 
80
 
 
81
    rv = apr_shm_create(&shm, SHARED_SIZE, NULL, p);
 
82
    APR_ASSERT_SUCCESS(tc, "Error allocating shared memory block", rv);
 
83
    ABTS_PTR_NOTNULL(tc, shm);
 
84
 
 
85
    retsize = apr_shm_size_get(shm);
 
86
    ABTS_INT_EQUAL(tc, SHARED_SIZE, retsize);
 
87
 
 
88
    rv = apr_shm_destroy(shm);
 
89
    APR_ASSERT_SUCCESS(tc, "Error destroying shared memory block", rv);
 
90
}
 
91
 
 
92
static void test_shm_allocate(abts_case *tc, void *data)
 
93
{
 
94
    apr_status_t rv;
 
95
    apr_shm_t *shm = NULL;
 
96
 
 
97
    rv = apr_shm_create(&shm, SHARED_SIZE, NULL, p);
 
98
    APR_ASSERT_SUCCESS(tc, "Error allocating shared memory block", rv);
 
99
    ABTS_PTR_NOTNULL(tc, shm);
 
100
 
 
101
    boxes = apr_shm_baseaddr_get(shm);
 
102
    ABTS_PTR_NOTNULL(tc, boxes);
 
103
 
 
104
    rv = apr_shm_destroy(shm);
 
105
    APR_ASSERT_SUCCESS(tc, "Error destroying shared memory block", rv);
 
106
}
 
107
 
 
108
#if APR_HAS_FORK
 
109
static void test_anon(abts_case *tc, void *data)
 
110
{
 
111
    apr_proc_t proc;
 
112
    apr_status_t rv;
 
113
    apr_shm_t *shm;
 
114
    apr_size_t retsize;
 
115
    int cnt, i;
 
116
    int recvd;
 
117
 
 
118
    rv = apr_shm_create(&shm, SHARED_SIZE, NULL, p);
 
119
    APR_ASSERT_SUCCESS(tc, "Error allocating shared memory block", rv);
 
120
    ABTS_PTR_NOTNULL(tc, shm);
 
121
 
 
122
    retsize = apr_shm_size_get(shm);
 
123
    ABTS_INT_EQUAL(tc, SHARED_SIZE, retsize);
 
124
 
 
125
    boxes = apr_shm_baseaddr_get(shm);
 
126
    ABTS_PTR_NOTNULL(tc, boxes);
 
127
 
 
128
    rv = apr_proc_fork(&proc, p);
 
129
    if (rv == APR_INCHILD) { /* child */
 
130
        int num = msgwait(5, 0, N_BOXES);
 
131
        /* exit with the number of messages received so that the parent
 
132
         * can check that all messages were received.
 
133
         */
 
134
        exit(num);
 
135
    }
 
136
    else if (rv == APR_INPARENT) { /* parent */
 
137
        i = N_BOXES;
 
138
        cnt = 0;
 
139
        while (cnt++ < N_MESSAGES) {
 
140
            if ((i-=3) < 0) {
 
141
                i += N_BOXES; /* start over at the top */
 
142
            }
 
143
            msgput(i, MSG);
 
144
            apr_sleep(apr_time_make(0, 10000));
 
145
        }
 
146
    }
 
147
    else {
 
148
        ABTS_FAIL(tc, "apr_proc_fork failed");
 
149
    }
 
150
    /* wait for the child */
 
151
    rv = apr_proc_wait(&proc, &recvd, NULL, APR_WAIT);
 
152
    ABTS_INT_EQUAL(tc, N_MESSAGES, recvd);
 
153
 
 
154
    rv = apr_shm_destroy(shm);
 
155
    APR_ASSERT_SUCCESS(tc, "Error destroying shared memory block", rv);
 
156
}
 
157
#endif
 
158
 
 
159
static void test_named(abts_case *tc, void *data)
 
160
{
 
161
    apr_status_t rv;
 
162
    apr_shm_t *shm = NULL;
 
163
    apr_size_t retsize;
 
164
    apr_proc_t pidproducer, pidconsumer;
 
165
    apr_procattr_t *attr1 = NULL, *attr2 = NULL;
 
166
    int sent, received;
 
167
    apr_exit_why_e why;
 
168
    const char *args[4];
 
169
 
 
170
    apr_shm_remove(SHARED_FILENAME, p);
 
171
 
 
172
    rv = apr_shm_create(&shm, SHARED_SIZE, SHARED_FILENAME, p);
 
173
    APR_ASSERT_SUCCESS(tc, "Error allocating shared memory block", rv);
 
174
    if (rv != APR_SUCCESS) {
 
175
        return;
 
176
    }
 
177
    ABTS_PTR_NOTNULL(tc, shm);
 
178
 
 
179
    retsize = apr_shm_size_get(shm);
 
180
    ABTS_INT_EQUAL(tc, SHARED_SIZE, retsize);
 
181
 
 
182
    boxes = apr_shm_baseaddr_get(shm);
 
183
    ABTS_PTR_NOTNULL(tc, boxes);
 
184
 
 
185
    rv = apr_procattr_create(&attr1, p);
 
186
    ABTS_PTR_NOTNULL(tc, attr1);
 
187
    APR_ASSERT_SUCCESS(tc, "Couldn't create attr1", rv);
 
188
    args[0] = apr_pstrdup(p, "testshmproducer" EXTENSION);
 
189
    args[1] = NULL;
 
190
    rv = apr_proc_create(&pidproducer, "./testshmproducer" EXTENSION, args,
 
191
                         NULL, attr1, p);
 
192
    APR_ASSERT_SUCCESS(tc, "Couldn't launch producer", rv);
 
193
 
 
194
    rv = apr_procattr_create(&attr2, p);
 
195
    ABTS_PTR_NOTNULL(tc, attr2);
 
196
    APR_ASSERT_SUCCESS(tc, "Couldn't create attr2", rv);
 
197
    args[0] = apr_pstrdup(p, "testshmconsumer" EXTENSION);
 
198
    rv = apr_proc_create(&pidconsumer, "./testshmconsumer" EXTENSION, args, 
 
199
                         NULL, attr2, p);
 
200
    APR_ASSERT_SUCCESS(tc, "Couldn't launch consumer", rv);
 
201
 
 
202
    rv = apr_proc_wait(&pidconsumer, &received, &why, APR_WAIT);
 
203
    ABTS_INT_EQUAL(tc, APR_CHILD_DONE, rv);
 
204
    ABTS_INT_EQUAL(tc, APR_PROC_EXIT, why);
 
205
 
 
206
    rv = apr_proc_wait(&pidproducer, &sent, &why, APR_WAIT);
 
207
    ABTS_INT_EQUAL(tc, APR_CHILD_DONE, rv);
 
208
    ABTS_INT_EQUAL(tc, APR_PROC_EXIT, why);
 
209
 
 
210
    /* Cleanup before testing that producer and consumer worked correctly.
 
211
     * This way, if they didn't succeed, we can just run this test again
 
212
     * without having to cleanup manually.
 
213
     */
 
214
    APR_ASSERT_SUCCESS(tc, "Error destroying shared memory", 
 
215
                       apr_shm_destroy(shm));
 
216
    
 
217
    ABTS_INT_EQUAL(tc, sent, received);
 
218
 
 
219
}
 
220
 
 
221
static void test_named_remove(abts_case *tc, void *data)
 
222
{
 
223
    apr_status_t rv;
 
224
    apr_shm_t *shm;
 
225
 
 
226
    apr_shm_remove(SHARED_FILENAME, p);
 
227
 
 
228
    rv = apr_shm_create(&shm, SHARED_SIZE, SHARED_FILENAME, p);
 
229
    APR_ASSERT_SUCCESS(tc, "Error allocating shared memory block", rv);
 
230
    if (rv != APR_SUCCESS) {
 
231
        return;
 
232
    }
 
233
    ABTS_PTR_NOTNULL(tc, shm);
 
234
 
 
235
    rv = apr_shm_remove(SHARED_FILENAME, p);
 
236
    APR_ASSERT_SUCCESS(tc, "Error removing shared memory block", rv);
 
237
    if (rv != APR_SUCCESS) {
 
238
        return ;
 
239
    }
 
240
 
 
241
    rv = apr_shm_create(&shm, SHARED_SIZE, SHARED_FILENAME, p);
 
242
    APR_ASSERT_SUCCESS(tc, "Error allocating shared memory block", rv);
 
243
    if (rv != APR_SUCCESS) {
 
244
        return;
 
245
    }
 
246
    ABTS_PTR_NOTNULL(tc, shm);
 
247
 
 
248
    rv = apr_shm_destroy(shm);
 
249
    APR_ASSERT_SUCCESS(tc, "Error destroying shared memory block", rv);
 
250
}
 
251
 
 
252
#endif
 
253
 
 
254
abts_suite *testshm(abts_suite *suite)
 
255
{
 
256
    suite = ADD_SUITE(suite)
 
257
 
 
258
#if APR_HAS_SHARED_MEMORY
 
259
    abts_run_test(suite, test_anon_create, NULL);
 
260
    abts_run_test(suite, test_check_size, NULL);
 
261
    abts_run_test(suite, test_shm_allocate, NULL);
 
262
#if APR_HAS_FORK
 
263
    abts_run_test(suite, test_anon, NULL);
 
264
#endif
 
265
    abts_run_test(suite, test_named, NULL); 
 
266
    abts_run_test(suite, test_named_remove, NULL); 
 
267
#endif
 
268
 
 
269
    return suite;
 
270
}
 
271
 
 
272