summaryrefslogtreecommitdiff
path: root/test/testshm.h
blob: d8cb50be811e0fe87f257ccaafb96d946c552a2c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef TESTSHM_H
#define TESTSHM_H

#include "apr.h"
#include "apr_time.h"
#include "apr_atomic.h"
#include "apr_strings.h"

#include <assert.h>

typedef struct mbox {
    char msg[1024];
    apr_uint32_t msgavail;
} mbox;
mbox *boxes;

#define N_BOXES 10
#define N_MESSAGES 100
#define SHARED_SIZE (apr_size_t)(N_BOXES * sizeof(mbox))
#define SHARED_FILENAME "data/apr.testshm.shm"
#define MSG "Sending a message"

#if APR_HAS_SHARED_MEMORY

static APR_INLINE
int msgwait(const char *msg, int count, int duration, int sleep_ms)
{
    int recvd = 0, i;
    apr_time_t start = apr_time_now();
    apr_interval_time_t sleep_duration = apr_time_from_sec(duration);
    apr_interval_time_t sleep_delay = apr_time_from_msec(sleep_ms);
    while (apr_time_now() - start < sleep_duration) {
        for (i = 0; i < N_BOXES; i++) {
            if (apr_atomic_cas32(&boxes[i].msgavail, 0, 1) == 1) {
                if (msg) {
                    assert(strcmp(boxes[i].msg, msg) == 0);
                }
                *boxes[i].msg = '\0';
                if (++recvd == count) {
                    return recvd;
                }
            }
        }
        apr_sleep(sleep_delay);
    }
    return recvd;
}

static APR_INLINE
int msgput(const char *msg, int boxnum)
{
    if (apr_atomic_cas32(&boxes[boxnum].msgavail, -1, 0) != 0) {
        return 0;
    }
    if (msg) {
        apr_cpystrn(boxes[boxnum].msg, msg, sizeof(boxes[boxnum].msg));
    }
    else {
        *boxes[boxnum].msg = '\0';
    }
    apr_atomic_set32(&boxes[boxnum].msgavail, 1);
    return 1;
}

#endif /* APR_HAS_SHARED_MEMORY */

#endif