diff options
author | ylavic <ylavic@13f79535-47bb-0310-9956-ffa450edef68> | 2023-03-02 22:56:04 +0000 |
---|---|---|
committer | ylavic <ylavic@13f79535-47bb-0310-9956-ffa450edef68> | 2023-03-02 22:56:04 +0000 |
commit | 643cf16cb35567bb19f8685477f605c12a78560c (patch) | |
tree | 0d08acf687ad272f2922574efc70474a1343ca83 /test/testshm.h | |
parent | 404fe93feed16e9a1b1b78428cf3b86f84d7e6c3 (diff) | |
download | libapr-643cf16cb35567bb19f8685477f605c12a78560c.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.
Merges r1902267 from trunk.
Merges r1908004 from 1.8.x.
Submitted by: ylavic
git-svn-id: https://svn.apache.org/repos/asf/apr/apr/branches/1.7.x@1908005 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'test/testshm.h')
-rw-r--r-- | test/testshm.h | 56 |
1 files changed, 53 insertions, 3 deletions
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 |