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