tpd.c 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309
  1. /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
  2. /* This Source Code Form is subject to the terms of the Mozilla Public
  3. * License, v. 2.0. If a copy of the MPL was not distributed with this
  4. * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  5. /*
  6. ** File: tpd.c
  7. ** Description: Exercising the thread private data bailywick.
  8. */
  9. #include "prmem.h"
  10. #include "prinit.h"
  11. #include "prlog.h"
  12. #include "prprf.h"
  13. #include "prthread.h"
  14. #include "prtypes.h"
  15. #include "private/pprio.h"
  16. #include "plgetopt.h"
  17. static PRUintn key[128];
  18. static PRIntn debug = 0;
  19. static PRBool failed = PR_FALSE;
  20. static PRBool should = PR_TRUE;
  21. static PRBool did = PR_TRUE;
  22. static PRFileDesc *fout = NULL;
  23. static void PrintProgress(PRIntn line)
  24. {
  25. failed = failed || (should && !did);
  26. failed = failed || (!should && did);
  27. if (debug > 0)
  28. {
  29. #if defined(WIN16)
  30. printf(
  31. "@ line %d destructor should%s have been called and was%s\n",
  32. line, ((should) ? "" : " NOT"), ((did) ? "" : " NOT"));
  33. #else
  34. PR_fprintf(
  35. fout, "@ line %d destructor should%s have been called and was%s\n",
  36. line, ((should) ? "" : " NOT"), ((did) ? "" : " NOT"));
  37. #endif
  38. }
  39. } /* PrintProgress */
  40. static void MyAssert(const char *expr, const char *file, PRIntn line)
  41. {
  42. if (debug > 0) {
  43. (void)PR_fprintf(fout, "'%s' in file: %s: %d\n", expr, file, line);
  44. }
  45. } /* MyAssert */
  46. #define MY_ASSERT(_expr) \
  47. ((_expr)?((void)0):MyAssert(# _expr,__FILE__,__LINE__))
  48. static void PR_CALLBACK Destructor(void *data)
  49. {
  50. MY_ASSERT(NULL != data);
  51. if (should) {
  52. did = PR_TRUE;
  53. }
  54. else {
  55. failed = PR_TRUE;
  56. }
  57. /*
  58. * We don't actually free the storage since it's actually allocated
  59. * on the stack. Normally, this would not be the case and this is
  60. * the opportunity to free whatever.
  61. PR_Free(data);
  62. */
  63. } /* Destructor */
  64. static void PR_CALLBACK Thread(void *null)
  65. {
  66. void *pd;
  67. PRStatus rv;
  68. PRUintn keys;
  69. char *key_string[] = {
  70. "Key #0", "Key #1", "Key #2", "Key #3",
  71. "Bogus #5", "Bogus #6", "Bogus #7", "Bogus #8"
  72. };
  73. did = should = PR_FALSE;
  74. for (keys = 0; keys < 8; ++keys)
  75. {
  76. pd = PR_GetThreadPrivate(key[keys]);
  77. MY_ASSERT(NULL == pd);
  78. }
  79. PrintProgress(__LINE__);
  80. did = should = PR_FALSE;
  81. for (keys = 0; keys < 4; ++keys)
  82. {
  83. rv = PR_SetThreadPrivate(key[keys], key_string[keys]);
  84. MY_ASSERT(PR_SUCCESS == rv);
  85. }
  86. PrintProgress(__LINE__);
  87. did = should = PR_FALSE;
  88. for (keys = 4; keys < 8; ++keys)
  89. {
  90. rv = PR_SetThreadPrivate(key[keys], key_string[keys]);
  91. MY_ASSERT(PR_FAILURE == rv);
  92. }
  93. PrintProgress(__LINE__);
  94. did = PR_FALSE; should = PR_TRUE;
  95. for (keys = 0; keys < 4; ++keys)
  96. {
  97. rv = PR_SetThreadPrivate(key[keys], key_string[keys]);
  98. MY_ASSERT(PR_SUCCESS == rv);
  99. }
  100. PrintProgress(__LINE__);
  101. did = PR_FALSE; should = PR_TRUE;
  102. for (keys = 0; keys < 4; ++keys)
  103. {
  104. rv = PR_SetThreadPrivate(key[keys], NULL);
  105. MY_ASSERT(PR_SUCCESS == rv);
  106. }
  107. PrintProgress(__LINE__);
  108. did = should = PR_FALSE;
  109. for (keys = 0; keys < 4; ++keys)
  110. {
  111. rv = PR_SetThreadPrivate(key[keys], NULL);
  112. MY_ASSERT(PR_SUCCESS == rv);
  113. }
  114. PrintProgress(__LINE__);
  115. did = should = PR_FALSE;
  116. for (keys = 8; keys < 127; ++keys)
  117. {
  118. rv = PR_SetThreadPrivate(key[keys], "EXTENSION");
  119. MY_ASSERT(PR_SUCCESS == rv);
  120. }
  121. PrintProgress(__LINE__);
  122. did = PR_FALSE; should = PR_TRUE;
  123. for (keys = 8; keys < 127; ++keys)
  124. {
  125. rv = PR_SetThreadPrivate(key[keys], NULL);
  126. MY_ASSERT(PR_SUCCESS == rv);
  127. }
  128. PrintProgress(__LINE__);
  129. did = should = PR_FALSE;
  130. for (keys = 8; keys < 127; ++keys)
  131. {
  132. rv = PR_SetThreadPrivate(key[keys], NULL);
  133. MY_ASSERT(PR_SUCCESS == rv);
  134. }
  135. /* put in keys and leave them there for thread exit */
  136. did = should = PR_FALSE;
  137. for (keys = 0; keys < 4; ++keys)
  138. {
  139. rv = PR_SetThreadPrivate(key[keys], key_string[keys]);
  140. MY_ASSERT(PR_SUCCESS == rv);
  141. }
  142. PrintProgress(__LINE__);
  143. did = PR_FALSE; should = PR_TRUE;
  144. } /* Thread */
  145. static PRIntn PR_CALLBACK Tpd(PRIntn argc, char **argv)
  146. {
  147. void *pd;
  148. PRStatus rv;
  149. PRUintn keys;
  150. PRThread *thread;
  151. char *key_string[] = {
  152. "Key #0", "Key #1", "Key #2", "Key #3",
  153. "Bogus #5", "Bogus #6", "Bogus #7", "Bogus #8"
  154. };
  155. fout = PR_STDOUT;
  156. did = should = PR_FALSE;
  157. for (keys = 0; keys < 4; ++keys)
  158. {
  159. rv = PR_NewThreadPrivateIndex(&key[keys], Destructor);
  160. MY_ASSERT(PR_SUCCESS == rv);
  161. }
  162. PrintProgress(__LINE__);
  163. did = should = PR_FALSE;
  164. for (keys = 0; keys < 8; ++keys)
  165. {
  166. pd = PR_GetThreadPrivate(key[keys]);
  167. MY_ASSERT(NULL == pd);
  168. }
  169. PrintProgress(__LINE__);
  170. did = should = PR_FALSE;
  171. for (keys = 0; keys < 4; ++keys)
  172. {
  173. rv = PR_SetThreadPrivate(key[keys], key_string[keys]);
  174. MY_ASSERT(PR_SUCCESS == rv);
  175. }
  176. PrintProgress(__LINE__);
  177. for (keys = 4; keys < 8; ++keys) {
  178. key[keys] = 4096; /* set to invalid value */
  179. }
  180. did = should = PR_FALSE;
  181. for (keys = 4; keys < 8; ++keys)
  182. {
  183. rv = PR_SetThreadPrivate(key[keys], key_string[keys]);
  184. MY_ASSERT(PR_FAILURE == rv);
  185. }
  186. PrintProgress(__LINE__);
  187. did = PR_FALSE; should = PR_TRUE;
  188. for (keys = 0; keys < 4; ++keys)
  189. {
  190. rv = PR_SetThreadPrivate(key[keys], key_string[keys]);
  191. MY_ASSERT(PR_SUCCESS == rv);
  192. }
  193. PrintProgress(__LINE__);
  194. did = PR_FALSE; should = PR_TRUE;
  195. for (keys = 0; keys < 4; ++keys)
  196. {
  197. rv = PR_SetThreadPrivate(key[keys], NULL);
  198. MY_ASSERT(PR_SUCCESS == rv);
  199. }
  200. PrintProgress(__LINE__);
  201. did = should = PR_FALSE;
  202. for (keys = 0; keys < 4; ++keys)
  203. {
  204. rv = PR_SetThreadPrivate(key[keys], NULL);
  205. MY_ASSERT(PR_SUCCESS == rv);
  206. }
  207. PrintProgress(__LINE__);
  208. did = should = PR_FALSE;
  209. for (keys = 8; keys < 127; ++keys)
  210. {
  211. rv = PR_NewThreadPrivateIndex(&key[keys], Destructor);
  212. MY_ASSERT(PR_SUCCESS == rv);
  213. rv = PR_SetThreadPrivate(key[keys], "EXTENSION");
  214. MY_ASSERT(PR_SUCCESS == rv);
  215. }
  216. PrintProgress(__LINE__);
  217. did = PR_FALSE; should = PR_TRUE;
  218. for (keys = 8; keys < 127; ++keys)
  219. {
  220. rv = PR_SetThreadPrivate(key[keys], NULL);
  221. MY_ASSERT(PR_SUCCESS == rv);
  222. }
  223. PrintProgress(__LINE__);
  224. did = should = PR_FALSE;
  225. for (keys = 8; keys < 127; ++keys)
  226. {
  227. rv = PR_SetThreadPrivate(key[keys], NULL);
  228. MY_ASSERT(PR_SUCCESS == rv);
  229. }
  230. thread = PR_CreateThread(
  231. PR_USER_THREAD, Thread, NULL, PR_PRIORITY_NORMAL,
  232. PR_LOCAL_THREAD, PR_JOINABLE_THREAD, 0);
  233. (void)PR_JoinThread(thread);
  234. PrintProgress(__LINE__);
  235. #if defined(WIN16)
  236. printf(
  237. "%s\n",((PR_TRUE == failed) ? "FAILED" : "PASSED"));
  238. #else
  239. (void)PR_fprintf(
  240. fout, "%s\n",((PR_TRUE == failed) ? "FAILED" : "PASSED"));
  241. #endif
  242. return 0;
  243. } /* Tpd */
  244. int main(int argc, char **argv)
  245. {
  246. PLOptStatus os;
  247. PLOptState *opt = PL_CreateOptState(argc, argv, "dl:r:");
  248. while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
  249. {
  250. if (PL_OPT_BAD == os) {
  251. continue;
  252. }
  253. switch (opt->option)
  254. {
  255. case 'd': /* debug mode */
  256. debug = PR_TRUE;
  257. break;
  258. default:
  259. break;
  260. }
  261. }
  262. PL_DestroyOptState(opt);
  263. PR_STDIO_INIT();
  264. return PR_Initialize(Tpd, argc, argv, 0);
  265. } /* main */
  266. /* tpd.c */