testshm.c 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272
  1. /* Licensed to the Apache Software Foundation (ASF) under one or more
  2. * contributor license agreements. See the NOTICE file distributed with
  3. * this work for additional information regarding copyright ownership.
  4. * The ASF licenses this file to You under the Apache License, Version 2.0
  5. * (the "License"); you may not use this file except in compliance with
  6. * the License. You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  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.
  15. */
  16. #include "testutil.h"
  17. #include "fspr_shm.h"
  18. #include "fspr_errno.h"
  19. #include "fspr_general.h"
  20. #include "fspr_lib.h"
  21. #include "fspr_strings.h"
  22. #include "fspr_thread_proc.h"
  23. #include "fspr_time.h"
  24. #include "testshm.h"
  25. #include "fspr.h"
  26. #if APR_HAVE_STDLIB_H
  27. #include <stdlib.h>
  28. #endif
  29. #if APR_HAS_SHARED_MEMORY
  30. static int msgwait(int sleep_sec, int first_box, int last_box)
  31. {
  32. int i;
  33. int recvd = 0;
  34. fspr_time_t start = fspr_time_now();
  35. fspr_interval_time_t sleep_duration = fspr_time_from_sec(sleep_sec);
  36. while (fspr_time_now() - start < sleep_duration) {
  37. for (i = first_box; i < last_box; i++) {
  38. if (boxes[i].msgavail && !strcmp(boxes[i].msg, MSG)) {
  39. recvd++;
  40. boxes[i].msgavail = 0; /* reset back to 0 */
  41. /* reset the msg field. 1024 is a magic number and it should
  42. * be a macro, but I am being lazy.
  43. */
  44. memset(boxes[i].msg, 0, 1024);
  45. }
  46. }
  47. fspr_sleep(fspr_time_make(0, 10000)); /* 10ms */
  48. }
  49. return recvd;
  50. }
  51. static void msgput(int boxnum, char *msg)
  52. {
  53. fspr_cpystrn(boxes[boxnum].msg, msg, strlen(msg) + 1);
  54. boxes[boxnum].msgavail = 1;
  55. }
  56. static void test_anon_create(abts_case *tc, void *data)
  57. {
  58. fspr_status_t rv;
  59. fspr_shm_t *shm = NULL;
  60. rv = fspr_shm_create(&shm, SHARED_SIZE, NULL, p);
  61. APR_ASSERT_SUCCESS(tc, "Error allocating shared memory block", rv);
  62. ABTS_PTR_NOTNULL(tc, shm);
  63. rv = fspr_shm_destroy(shm);
  64. APR_ASSERT_SUCCESS(tc, "Error destroying shared memory block", rv);
  65. }
  66. static void test_check_size(abts_case *tc, void *data)
  67. {
  68. fspr_status_t rv;
  69. fspr_shm_t *shm = NULL;
  70. fspr_size_t retsize;
  71. rv = fspr_shm_create(&shm, SHARED_SIZE, NULL, p);
  72. APR_ASSERT_SUCCESS(tc, "Error allocating shared memory block", rv);
  73. ABTS_PTR_NOTNULL(tc, shm);
  74. retsize = fspr_shm_size_get(shm);
  75. ABTS_INT_EQUAL(tc, SHARED_SIZE, retsize);
  76. rv = fspr_shm_destroy(shm);
  77. APR_ASSERT_SUCCESS(tc, "Error destroying shared memory block", rv);
  78. }
  79. static void test_shm_allocate(abts_case *tc, void *data)
  80. {
  81. fspr_status_t rv;
  82. fspr_shm_t *shm = NULL;
  83. rv = fspr_shm_create(&shm, SHARED_SIZE, NULL, p);
  84. APR_ASSERT_SUCCESS(tc, "Error allocating shared memory block", rv);
  85. ABTS_PTR_NOTNULL(tc, shm);
  86. boxes = fspr_shm_baseaddr_get(shm);
  87. ABTS_PTR_NOTNULL(tc, boxes);
  88. rv = fspr_shm_destroy(shm);
  89. APR_ASSERT_SUCCESS(tc, "Error destroying shared memory block", rv);
  90. }
  91. #if APR_HAS_FORK
  92. static void test_anon(abts_case *tc, void *data)
  93. {
  94. fspr_proc_t proc;
  95. fspr_status_t rv;
  96. fspr_shm_t *shm;
  97. fspr_size_t retsize;
  98. int cnt, i;
  99. int recvd;
  100. rv = fspr_shm_create(&shm, SHARED_SIZE, NULL, p);
  101. APR_ASSERT_SUCCESS(tc, "Error allocating shared memory block", rv);
  102. ABTS_PTR_NOTNULL(tc, shm);
  103. retsize = fspr_shm_size_get(shm);
  104. ABTS_INT_EQUAL(tc, SHARED_SIZE, retsize);
  105. boxes = fspr_shm_baseaddr_get(shm);
  106. ABTS_PTR_NOTNULL(tc, boxes);
  107. rv = fspr_proc_fork(&proc, p);
  108. if (rv == APR_INCHILD) { /* child */
  109. int num = msgwait(5, 0, N_BOXES);
  110. /* exit with the number of messages received so that the parent
  111. * can check that all messages were received.
  112. */
  113. exit(num);
  114. }
  115. else if (rv == APR_INPARENT) { /* parent */
  116. i = N_BOXES;
  117. cnt = 0;
  118. while (cnt++ < N_MESSAGES) {
  119. if ((i-=3) < 0) {
  120. i += N_BOXES; /* start over at the top */
  121. }
  122. msgput(i, MSG);
  123. fspr_sleep(fspr_time_make(0, 10000));
  124. }
  125. }
  126. else {
  127. ABTS_FAIL(tc, "fspr_proc_fork failed");
  128. }
  129. /* wait for the child */
  130. rv = fspr_proc_wait(&proc, &recvd, NULL, APR_WAIT);
  131. ABTS_INT_EQUAL(tc, N_MESSAGES, recvd);
  132. rv = fspr_shm_destroy(shm);
  133. APR_ASSERT_SUCCESS(tc, "Error destroying shared memory block", rv);
  134. }
  135. #endif
  136. static void test_named(abts_case *tc, void *data)
  137. {
  138. fspr_status_t rv;
  139. fspr_shm_t *shm = NULL;
  140. fspr_size_t retsize;
  141. fspr_proc_t pidproducer, pidconsumer;
  142. fspr_procattr_t *attr1 = NULL, *attr2 = NULL;
  143. int sent, received;
  144. fspr_exit_why_e why;
  145. const char *args[4];
  146. fspr_shm_remove(SHARED_FILENAME, p);
  147. rv = fspr_shm_create(&shm, SHARED_SIZE, SHARED_FILENAME, p);
  148. APR_ASSERT_SUCCESS(tc, "Error allocating shared memory block", rv);
  149. if (rv != APR_SUCCESS) {
  150. return;
  151. }
  152. ABTS_PTR_NOTNULL(tc, shm);
  153. retsize = fspr_shm_size_get(shm);
  154. ABTS_INT_EQUAL(tc, SHARED_SIZE, retsize);
  155. boxes = fspr_shm_baseaddr_get(shm);
  156. ABTS_PTR_NOTNULL(tc, boxes);
  157. rv = fspr_procattr_create(&attr1, p);
  158. ABTS_PTR_NOTNULL(tc, attr1);
  159. APR_ASSERT_SUCCESS(tc, "Couldn't create attr1", rv);
  160. args[0] = fspr_pstrdup(p, "testshmproducer" EXTENSION);
  161. args[1] = NULL;
  162. rv = fspr_proc_create(&pidproducer, "./testshmproducer" EXTENSION, args,
  163. NULL, attr1, p);
  164. APR_ASSERT_SUCCESS(tc, "Couldn't launch producer", rv);
  165. rv = fspr_procattr_create(&attr2, p);
  166. ABTS_PTR_NOTNULL(tc, attr2);
  167. APR_ASSERT_SUCCESS(tc, "Couldn't create attr2", rv);
  168. args[0] = fspr_pstrdup(p, "testshmconsumer" EXTENSION);
  169. rv = fspr_proc_create(&pidconsumer, "./testshmconsumer" EXTENSION, args,
  170. NULL, attr2, p);
  171. APR_ASSERT_SUCCESS(tc, "Couldn't launch consumer", rv);
  172. rv = fspr_proc_wait(&pidconsumer, &received, &why, APR_WAIT);
  173. ABTS_INT_EQUAL(tc, APR_CHILD_DONE, rv);
  174. ABTS_INT_EQUAL(tc, APR_PROC_EXIT, why);
  175. rv = fspr_proc_wait(&pidproducer, &sent, &why, APR_WAIT);
  176. ABTS_INT_EQUAL(tc, APR_CHILD_DONE, rv);
  177. ABTS_INT_EQUAL(tc, APR_PROC_EXIT, why);
  178. /* Cleanup before testing that producer and consumer worked correctly.
  179. * This way, if they didn't succeed, we can just run this test again
  180. * without having to cleanup manually.
  181. */
  182. APR_ASSERT_SUCCESS(tc, "Error destroying shared memory",
  183. fspr_shm_destroy(shm));
  184. ABTS_INT_EQUAL(tc, sent, received);
  185. }
  186. static void test_named_remove(abts_case *tc, void *data)
  187. {
  188. fspr_status_t rv;
  189. fspr_shm_t *shm;
  190. fspr_shm_remove(SHARED_FILENAME, p);
  191. rv = fspr_shm_create(&shm, SHARED_SIZE, SHARED_FILENAME, p);
  192. APR_ASSERT_SUCCESS(tc, "Error allocating shared memory block", rv);
  193. if (rv != APR_SUCCESS) {
  194. return;
  195. }
  196. ABTS_PTR_NOTNULL(tc, shm);
  197. rv = fspr_shm_remove(SHARED_FILENAME, p);
  198. APR_ASSERT_SUCCESS(tc, "Error removing shared memory block", rv);
  199. if (rv != APR_SUCCESS) {
  200. return ;
  201. }
  202. rv = fspr_shm_create(&shm, SHARED_SIZE, SHARED_FILENAME, p);
  203. APR_ASSERT_SUCCESS(tc, "Error allocating shared memory block", rv);
  204. if (rv != APR_SUCCESS) {
  205. return;
  206. }
  207. ABTS_PTR_NOTNULL(tc, shm);
  208. rv = fspr_shm_destroy(shm);
  209. APR_ASSERT_SUCCESS(tc, "Error destroying shared memory block", rv);
  210. }
  211. #endif
  212. abts_suite *testshm(abts_suite *suite)
  213. {
  214. suite = ADD_SUITE(suite)
  215. #if APR_HAS_SHARED_MEMORY
  216. abts_run_test(suite, test_anon_create, NULL);
  217. abts_run_test(suite, test_check_size, NULL);
  218. abts_run_test(suite, test_shm_allocate, NULL);
  219. #if APR_HAS_FORK
  220. abts_run_test(suite, test_anon, NULL);
  221. #endif
  222. abts_run_test(suite, test_named, NULL);
  223. abts_run_test(suite, test_named_remove, NULL);
  224. #endif
  225. return suite;
  226. }