1
/* Copyright 2000-2005 The Apache Software Foundation or its licensors, as
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
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.
19
#include "apr_errno.h"
20
#include "apr_general.h"
22
#include "apr_strings.h"
23
#include "apr_thread_proc.h"
32
#if APR_HAS_SHARED_MEMORY
34
static int msgwait(int sleep_sec, int first_box, int last_box)
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)) {
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.
48
memset(boxes[i].msg, 0, 1024);
51
apr_sleep(apr_time_make(0, 10000)); /* 10ms */
56
static void msgput(int boxnum, char *msg)
58
apr_cpystrn(boxes[boxnum].msg, msg, strlen(msg) + 1);
59
boxes[boxnum].msgavail = 1;
62
static void test_anon_create(abts_case *tc, void *data)
65
apr_shm_t *shm = NULL;
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);
71
rv = apr_shm_destroy(shm);
72
APR_ASSERT_SUCCESS(tc, "Error destroying shared memory block", rv);
75
static void test_check_size(abts_case *tc, void *data)
78
apr_shm_t *shm = NULL;
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);
85
retsize = apr_shm_size_get(shm);
86
ABTS_INT_EQUAL(tc, SHARED_SIZE, retsize);
88
rv = apr_shm_destroy(shm);
89
APR_ASSERT_SUCCESS(tc, "Error destroying shared memory block", rv);
92
static void test_shm_allocate(abts_case *tc, void *data)
95
apr_shm_t *shm = NULL;
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);
101
boxes = apr_shm_baseaddr_get(shm);
102
ABTS_PTR_NOTNULL(tc, boxes);
104
rv = apr_shm_destroy(shm);
105
APR_ASSERT_SUCCESS(tc, "Error destroying shared memory block", rv);
109
static void test_anon(abts_case *tc, void *data)
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);
122
retsize = apr_shm_size_get(shm);
123
ABTS_INT_EQUAL(tc, SHARED_SIZE, retsize);
125
boxes = apr_shm_baseaddr_get(shm);
126
ABTS_PTR_NOTNULL(tc, boxes);
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.
136
else if (rv == APR_INPARENT) { /* parent */
139
while (cnt++ < N_MESSAGES) {
141
i += N_BOXES; /* start over at the top */
144
apr_sleep(apr_time_make(0, 10000));
148
ABTS_FAIL(tc, "apr_proc_fork failed");
150
/* wait for the child */
151
rv = apr_proc_wait(&proc, &recvd, NULL, APR_WAIT);
152
ABTS_INT_EQUAL(tc, N_MESSAGES, recvd);
154
rv = apr_shm_destroy(shm);
155
APR_ASSERT_SUCCESS(tc, "Error destroying shared memory block", rv);
159
static void test_named(abts_case *tc, void *data)
162
apr_shm_t *shm = NULL;
164
apr_proc_t pidproducer, pidconsumer;
165
apr_procattr_t *attr1 = NULL, *attr2 = NULL;
170
apr_shm_remove(SHARED_FILENAME, p);
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) {
177
ABTS_PTR_NOTNULL(tc, shm);
179
retsize = apr_shm_size_get(shm);
180
ABTS_INT_EQUAL(tc, SHARED_SIZE, retsize);
182
boxes = apr_shm_baseaddr_get(shm);
183
ABTS_PTR_NOTNULL(tc, boxes);
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);
190
rv = apr_proc_create(&pidproducer, "./testshmproducer" EXTENSION, args,
192
APR_ASSERT_SUCCESS(tc, "Couldn't launch producer", rv);
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,
200
APR_ASSERT_SUCCESS(tc, "Couldn't launch consumer", rv);
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);
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);
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.
214
APR_ASSERT_SUCCESS(tc, "Error destroying shared memory",
215
apr_shm_destroy(shm));
217
ABTS_INT_EQUAL(tc, sent, received);
221
static void test_named_remove(abts_case *tc, void *data)
226
apr_shm_remove(SHARED_FILENAME, p);
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) {
233
ABTS_PTR_NOTNULL(tc, shm);
235
rv = apr_shm_remove(SHARED_FILENAME, p);
236
APR_ASSERT_SUCCESS(tc, "Error removing shared memory block", rv);
237
if (rv != APR_SUCCESS) {
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) {
246
ABTS_PTR_NOTNULL(tc, shm);
248
rv = apr_shm_destroy(shm);
249
APR_ASSERT_SUCCESS(tc, "Error destroying shared memory block", rv);
254
abts_suite *testshm(abts_suite *suite)
256
suite = ADD_SUITE(suite)
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);
263
abts_run_test(suite, test_anon, NULL);
265
abts_run_test(suite, test_named, NULL);
266
abts_run_test(suite, test_named_remove, NULL);