summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorYann Ylavic <ylavic@apache.org>2022-06-26 23:30:37 +0000
committerYann Ylavic <ylavic@apache.org>2022-06-26 23:30:37 +0000
commit6ed911f09d0a144f865cc12ce5267c9c507d4cb1 (patch)
tree0a91f6b5aa438caea10a851bf06316d02054fe3c /test
parent849781e74f9b6c2d6403ca834227167735480020 (diff)
downloadapr-6ed911f09d0a144f865cc12ce5267c9c507d4cb1.tar.gz
test/testshm: Fix synchronization of msgput/msgwait IPC functions.
* test/testshm.h(): Move (APR_INLINE) common msgput/msgwait() functions there. * test/testshm.h(msgput, msgwait): Use atomics (cas) to prevent producer and consumer from writing to the same box. * testshm.c, testshmconsumer.c, testshmproducer.c: Use common helpers. git-svn-id: https://svn.apache.org/repos/asf/apr/apr/trunk@1902267 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'test')
-rw-r--r--test/testshm.c43
-rw-r--r--test/testshm.h56
-rw-r--r--test/testshmconsumer.c21
-rw-r--r--test/testshmproducer.c7
4 files changed, 65 insertions, 62 deletions
diff --git a/test/testshm.c b/test/testshm.c
index 738706906..12b6f3542 100644
--- a/test/testshm.c
+++ b/test/testshm.c
@@ -31,36 +31,6 @@
#if APR_HAS_SHARED_MEMORY
-#if APR_HAS_FORK
-static int msgwait(int sleep_sec, int first_box, int last_box)
-{
- int i;
- int recvd = 0;
- apr_time_t start = apr_time_now();
- apr_interval_time_t sleep_duration = apr_time_from_sec(sleep_sec);
- while (apr_time_now() - start < sleep_duration) {
- for (i = first_box; i < last_box; i++) {
- if (boxes[i].msgavail && !strcmp(boxes[i].msg, MSG)) {
- recvd++;
- boxes[i].msgavail = 0; /* reset back to 0 */
- /* reset the msg field. 1024 is a magic number and it should
- * be a macro, but I am being lazy.
- */
- memset(boxes[i].msg, 0, 1024);
- }
- }
- apr_sleep(apr_time_make(0, 10000)); /* 10ms */
- }
- return recvd;
-}
-
-static void msgput(int boxnum, char *msg)
-{
- apr_cpystrn(boxes[boxnum].msg, msg, strlen(msg) + 1);
- boxes[boxnum].msgavail = 1;
-}
-#endif /* APR_HAS_FORK */
-
static void test_anon_create(abts_case *tc, void *data)
{
apr_status_t rv;
@@ -102,6 +72,7 @@ static void test_shm_allocate(abts_case *tc, void *data)
boxes = apr_shm_baseaddr_get(shm);
ABTS_PTR_NOTNULL(tc, boxes);
+ memset(boxes, 0, SHARED_SIZE);
rv = apr_shm_destroy(shm);
APR_ASSERT_SUCCESS(tc, "Error destroying shared memory block", rv);
@@ -126,10 +97,13 @@ static void test_anon(abts_case *tc, void *data)
boxes = apr_shm_baseaddr_get(shm);
ABTS_PTR_NOTNULL(tc, boxes);
+ memset(boxes, 0, SHARED_SIZE);
rv = apr_proc_fork(&proc, p);
if (rv == APR_INCHILD) { /* child */
- int num = msgwait(5, 0, N_BOXES);
+ int num = msgwait("anon_test", N_MESSAGES,
+ 5, /* wait for 5s */
+ 10 /* with 10ms spin delay */);
/* exit with the number of messages received so that the parent
* can check that all messages were received.
*/
@@ -142,8 +116,10 @@ static void test_anon(abts_case *tc, void *data)
if ((i-=3) < 0) {
i += N_BOXES; /* start over at the top */
}
- msgput(i, MSG);
- apr_sleep(apr_time_make(0, 10000));
+ if (!msgput("anon_test", i)) {
+ cnt--;
+ }
+ apr_sleep(apr_time_from_msec(10));
}
}
else {
@@ -183,6 +159,7 @@ static void test_named(abts_case *tc, void *data)
boxes = apr_shm_baseaddr_get(shm);
ABTS_PTR_NOTNULL(tc, boxes);
+ memset(boxes, 0, SHARED_SIZE);
rv = apr_procattr_create(&attr1, p);
ABTS_PTR_NOTNULL(tc, attr1);
diff --git a/test/testshm.h b/test/testshm.h
index 5b24a9d42..4d4f0c5db 100644
--- a/test/testshm.h
+++ b/test/testshm.h
@@ -17,17 +17,67 @@
#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];
- int msgavail;
+ 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 N_MESSAGES 100
#define MSG "Sending a message"
-#endif
+#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
diff --git a/test/testshmconsumer.c b/test/testshmconsumer.c
index 6a2a3c30d..bf70e728c 100644
--- a/test/testshmconsumer.c
+++ b/test/testshmconsumer.c
@@ -30,25 +30,6 @@
#if APR_HAS_SHARED_MEMORY
-static int msgwait(int sleep_sec, int first_box, int last_box)
-{
- int i;
- int recvd = 0;
- apr_time_t start = apr_time_now();
- apr_interval_time_t sleep_duration = apr_time_from_sec(sleep_sec);
- while (apr_time_now() - start < sleep_duration) {
- for (i = first_box; i < last_box; i++) {
- if (boxes[i].msgavail && !strcmp(boxes[i].msg, MSG)) {
- recvd++;
- boxes[i].msgavail = 0; /* reset back to 0 */
- memset(boxes[i].msg, 0, 1024);
- }
- }
- apr_sleep(apr_time_from_sec(1));
- }
- return recvd;
-}
-
int main(void)
{
apr_status_t rv;
@@ -70,7 +51,7 @@ int main(void)
boxes = apr_shm_baseaddr_get(shm);
/* consume messages on all of the boxes */
- recvd = msgwait(30, 0, N_BOXES); /* wait for 30 seconds for messages */
+ recvd = msgwait(MSG, N_MESSAGES, 30, 1);
rv = apr_shm_detach(shm);
if (rv != APR_SUCCESS) {
diff --git a/test/testshmproducer.c b/test/testshmproducer.c
index 58eb94fcd..eb61e76b9 100644
--- a/test/testshmproducer.c
+++ b/test/testshmproducer.c
@@ -29,11 +29,6 @@
#if APR_HAS_SHARED_MEMORY
-static void msgput(int boxnum, char *msg)
-{
- apr_cpystrn(boxes[boxnum].msg, msg, strlen(msg) + 1);
- boxes[boxnum].msgavail = 1;
-}
int main(void)
{
@@ -63,7 +58,7 @@ int main(void)
* are returning the right number.
*/
for (i = N_BOXES - 1, sent = 0; i >= 0; i--, sent++) {
- msgput(i, MSG);
+ msgput(MSG, i);
apr_sleep(apr_time_from_sec(1));
}