From 6ed911f09d0a144f865cc12ce5267c9c507d4cb1 Mon Sep 17 00:00:00 2001 From: Yann Ylavic Date: Sun, 26 Jun 2022 23:30:37 +0000 Subject: 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 --- test/testshm.c | 43 +++++++++----------------------------- test/testshm.h | 56 +++++++++++++++++++++++++++++++++++++++++++++++--- test/testshmconsumer.c | 21 +------------------ test/testshmproducer.c | 7 +------ 4 files changed, 65 insertions(+), 62 deletions(-) (limited to 'test') 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 + 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)); } -- cgit v1.2.1