testmutexscope.c 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  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 <assert.h>
  17. #include <errno.h>
  18. #include <stdio.h>
  19. #include <stdlib.h>
  20. #include "fspr.h"
  21. #include "fspr_general.h"
  22. #include "fspr_proc_mutex.h"
  23. #include "fspr_global_mutex.h"
  24. #include "fspr_thread_proc.h"
  25. #if !APR_HAS_THREADS
  26. int main(void)
  27. {
  28. printf("This test requires APR thread support.\n");
  29. return 0;
  30. }
  31. #else /* APR_HAS_THREADS */
  32. static fspr_thread_mutex_t *thread_mutex;
  33. static fspr_proc_mutex_t *proc_mutex;
  34. static fspr_global_mutex_t *global_mutex;
  35. static fspr_pool_t *p;
  36. static volatile int counter;
  37. typedef enum {TEST_GLOBAL, TEST_PROC} test_mode_e;
  38. static void lock_init(fspr_lockmech_e mech, test_mode_e test_mode)
  39. {
  40. if (test_mode == TEST_PROC) {
  41. assert(fspr_proc_mutex_create(&proc_mutex,
  42. NULL,
  43. mech,
  44. p) == APR_SUCCESS);
  45. }
  46. else {
  47. assert(fspr_global_mutex_create(&global_mutex,
  48. NULL,
  49. mech,
  50. p) == APR_SUCCESS);
  51. }
  52. }
  53. static void lock_destroy(test_mode_e test_mode)
  54. {
  55. if (test_mode == TEST_PROC) {
  56. assert(fspr_proc_mutex_destroy(proc_mutex) == APR_SUCCESS);
  57. }
  58. else {
  59. assert(fspr_global_mutex_destroy(global_mutex) == APR_SUCCESS);
  60. }
  61. }
  62. static void lock_grab(test_mode_e test_mode)
  63. {
  64. if (test_mode == TEST_PROC) {
  65. assert(fspr_proc_mutex_lock(proc_mutex) == APR_SUCCESS);
  66. }
  67. else {
  68. assert(fspr_global_mutex_lock(global_mutex) == APR_SUCCESS);
  69. }
  70. }
  71. static void lock_release(test_mode_e test_mode)
  72. {
  73. if (test_mode == TEST_PROC) {
  74. assert(fspr_proc_mutex_unlock(proc_mutex) == APR_SUCCESS);
  75. }
  76. else {
  77. assert(fspr_global_mutex_unlock(global_mutex) == APR_SUCCESS);
  78. }
  79. }
  80. static void * APR_THREAD_FUNC eachThread(fspr_thread_t *id, void *p)
  81. {
  82. test_mode_e test_mode = (test_mode_e)p;
  83. lock_grab(test_mode);
  84. ++counter;
  85. assert(fspr_thread_mutex_lock(thread_mutex) == APR_SUCCESS);
  86. assert(fspr_thread_mutex_unlock(thread_mutex) == APR_SUCCESS);
  87. lock_release(test_mode);
  88. return NULL;
  89. }
  90. static void test_mech_mode(fspr_lockmech_e mech, const char *mech_name,
  91. test_mode_e test_mode)
  92. {
  93. fspr_thread_t *threads[20];
  94. int numThreads = 5;
  95. int i;
  96. fspr_status_t rv;
  97. printf("Trying %s mutexes with mechanism `%s'...\n",
  98. test_mode == TEST_GLOBAL ? "global" : "proc", mech_name);
  99. assert(numThreads <= sizeof(threads) / sizeof(threads[0]));
  100. assert(fspr_pool_create(&p, NULL) == APR_SUCCESS);
  101. assert(fspr_thread_mutex_create(&thread_mutex, 0, p) == APR_SUCCESS);
  102. assert(fspr_thread_mutex_lock(thread_mutex) == APR_SUCCESS);
  103. lock_init(mech, test_mode);
  104. counter = 0;
  105. i = 0;
  106. while (i < numThreads)
  107. {
  108. rv = fspr_thread_create(&threads[i],
  109. NULL,
  110. eachThread,
  111. (void *)test_mode,
  112. p);
  113. if (rv != APR_SUCCESS) {
  114. fprintf(stderr, "fspr_thread_create->%d\n", rv);
  115. exit(1);
  116. }
  117. ++i;
  118. }
  119. fspr_sleep(fspr_time_from_sec(5));
  120. if (test_mode == TEST_PROC) {
  121. printf(" Mutex mechanism `%s' is %sglobal in scope on this platform.\n",
  122. mech_name, counter == 1 ? "" : "not ");
  123. }
  124. else {
  125. if (counter != 1) {
  126. fprintf(stderr, "\n!!!fspr_global_mutex operations are broken on this "
  127. "platform for mutex mechanism `%s'!\n"
  128. "They don't block out threads within the same process.\n",
  129. mech_name);
  130. fprintf(stderr, "counter value: %d\n", counter);
  131. exit(1);
  132. }
  133. else {
  134. printf(" no problems encountered...\n");
  135. }
  136. }
  137. assert(fspr_thread_mutex_unlock(thread_mutex) == APR_SUCCESS);
  138. i = 0;
  139. while (i < numThreads)
  140. {
  141. fspr_status_t ignored;
  142. rv = fspr_thread_join(&ignored,
  143. threads[i]);
  144. assert(rv == APR_SUCCESS);
  145. ++i;
  146. }
  147. lock_destroy(test_mode);
  148. fspr_thread_mutex_destroy(thread_mutex);
  149. fspr_pool_destroy(p);
  150. }
  151. static void test_mech(fspr_lockmech_e mech, const char *mech_name)
  152. {
  153. test_mech_mode(mech, mech_name, TEST_PROC);
  154. test_mech_mode(mech, mech_name, TEST_GLOBAL);
  155. }
  156. int main(void)
  157. {
  158. struct {
  159. fspr_lockmech_e mech;
  160. const char *mech_name;
  161. } lockmechs[] = {
  162. {APR_LOCK_DEFAULT, "default"}
  163. #if APR_HAS_FLOCK_SERIALIZE
  164. ,{APR_LOCK_FLOCK, "flock"}
  165. #endif
  166. #if APR_HAS_SYSVSEM_SERIALIZE
  167. ,{APR_LOCK_SYSVSEM, "sysvsem"}
  168. #endif
  169. #if APR_HAS_POSIXSEM_SERIALIZE
  170. ,{APR_LOCK_POSIXSEM, "posix"}
  171. #endif
  172. #if APR_HAS_FCNTL_SERIALIZE
  173. ,{APR_LOCK_FCNTL, "fcntl"}
  174. #endif
  175. #if APR_HAS_PROC_PTHREAD_SERIALIZE
  176. ,{APR_LOCK_PROC_PTHREAD, "proc_pthread"}
  177. #endif
  178. };
  179. int i;
  180. assert(fspr_initialize() == APR_SUCCESS);
  181. for (i = 0; i < sizeof(lockmechs) / sizeof(lockmechs[0]); i++) {
  182. test_mech(lockmechs[i].mech, lockmechs[i].mech_name);
  183. }
  184. fspr_terminate();
  185. return 0;
  186. }
  187. #endif /* APR_HAS_THREADS */