1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/nsprpub/pr/tests/tpd.c Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,298 @@ 1.4 +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +/* 1.10 +** File: tpd.c 1.11 +** Description: Exercising the thread private data bailywick. 1.12 +*/ 1.13 + 1.14 +#include "prmem.h" 1.15 +#include "prinit.h" 1.16 +#include "prlog.h" 1.17 +#include "prprf.h" 1.18 +#include "prthread.h" 1.19 +#include "prtypes.h" 1.20 + 1.21 +#include "private/pprio.h" 1.22 + 1.23 +#include "plgetopt.h" 1.24 + 1.25 +static PRUintn key[128]; 1.26 +static PRIntn debug = 0; 1.27 +static PRBool failed = PR_FALSE; 1.28 +static PRBool should = PR_TRUE; 1.29 +static PRBool did = PR_TRUE; 1.30 +static PRFileDesc *fout = NULL; 1.31 + 1.32 +static void PrintProgress(PRIntn line) 1.33 +{ 1.34 + failed = failed || (should && !did); 1.35 + failed = failed || (!should && did); 1.36 + if (debug > 0) 1.37 + { 1.38 +#if defined(WIN16) 1.39 + printf( 1.40 + "@ line %d destructor should%s have been called and was%s\n", 1.41 + line, ((should) ? "" : " NOT"), ((did) ? "" : " NOT")); 1.42 +#else 1.43 + PR_fprintf( 1.44 + fout, "@ line %d destructor should%s have been called and was%s\n", 1.45 + line, ((should) ? "" : " NOT"), ((did) ? "" : " NOT")); 1.46 +#endif 1.47 + } 1.48 +} /* PrintProgress */ 1.49 + 1.50 +static void MyAssert(const char *expr, const char *file, PRIntn line) 1.51 +{ 1.52 + if (debug > 0) 1.53 + (void)PR_fprintf(fout, "'%s' in file: %s: %d\n", expr, file, line); 1.54 +} /* MyAssert */ 1.55 + 1.56 +#define MY_ASSERT(_expr) \ 1.57 + ((_expr)?((void)0):MyAssert(# _expr,__FILE__,__LINE__)) 1.58 + 1.59 + 1.60 +static void PR_CALLBACK Destructor(void *data) 1.61 +{ 1.62 + MY_ASSERT(NULL != data); 1.63 + if (should) did = PR_TRUE; 1.64 + else failed = PR_TRUE; 1.65 + /* 1.66 + * We don't actually free the storage since it's actually allocated 1.67 + * on the stack. Normally, this would not be the case and this is 1.68 + * the opportunity to free whatever. 1.69 + PR_Free(data); 1.70 + */ 1.71 +} /* Destructor */ 1.72 + 1.73 +static void PR_CALLBACK Thread(void *null) 1.74 +{ 1.75 + void *pd; 1.76 + PRStatus rv; 1.77 + PRUintn keys; 1.78 + char *key_string[] = { 1.79 + "Key #0", "Key #1", "Key #2", "Key #3", 1.80 + "Bogus #5", "Bogus #6", "Bogus #7", "Bogus #8"}; 1.81 + 1.82 + did = should = PR_FALSE; 1.83 + for (keys = 0; keys < 8; ++keys) 1.84 + { 1.85 + pd = PR_GetThreadPrivate(key[keys]); 1.86 + MY_ASSERT(NULL == pd); 1.87 + } 1.88 + PrintProgress(__LINE__); 1.89 + 1.90 + did = should = PR_FALSE; 1.91 + for (keys = 0; keys < 4; ++keys) 1.92 + { 1.93 + rv = PR_SetThreadPrivate(key[keys], key_string[keys]); 1.94 + MY_ASSERT(PR_SUCCESS == rv); 1.95 + } 1.96 + PrintProgress(__LINE__); 1.97 + 1.98 + did = should = PR_FALSE; 1.99 + for (keys = 4; keys < 8; ++keys) 1.100 + { 1.101 + rv = PR_SetThreadPrivate(key[keys], key_string[keys]); 1.102 + MY_ASSERT(PR_FAILURE == rv); 1.103 + } 1.104 + PrintProgress(__LINE__); 1.105 + 1.106 + did = PR_FALSE; should = PR_TRUE; 1.107 + for (keys = 0; keys < 4; ++keys) 1.108 + { 1.109 + rv = PR_SetThreadPrivate(key[keys], key_string[keys]); 1.110 + MY_ASSERT(PR_SUCCESS == rv); 1.111 + } 1.112 + PrintProgress(__LINE__); 1.113 + 1.114 + did = PR_FALSE; should = PR_TRUE; 1.115 + for (keys = 0; keys < 4; ++keys) 1.116 + { 1.117 + rv = PR_SetThreadPrivate(key[keys], NULL); 1.118 + MY_ASSERT(PR_SUCCESS == rv); 1.119 + } 1.120 + PrintProgress(__LINE__); 1.121 + 1.122 + did = should = PR_FALSE; 1.123 + for (keys = 0; keys < 4; ++keys) 1.124 + { 1.125 + rv = PR_SetThreadPrivate(key[keys], NULL); 1.126 + MY_ASSERT(PR_SUCCESS == rv); 1.127 + } 1.128 + PrintProgress(__LINE__); 1.129 + 1.130 + did = should = PR_FALSE; 1.131 + for (keys = 8; keys < 127; ++keys) 1.132 + { 1.133 + rv = PR_SetThreadPrivate(key[keys], "EXTENSION"); 1.134 + MY_ASSERT(PR_SUCCESS == rv); 1.135 + } 1.136 + PrintProgress(__LINE__); 1.137 + 1.138 + did = PR_FALSE; should = PR_TRUE; 1.139 + for (keys = 8; keys < 127; ++keys) 1.140 + { 1.141 + rv = PR_SetThreadPrivate(key[keys], NULL); 1.142 + MY_ASSERT(PR_SUCCESS == rv); 1.143 + } 1.144 + PrintProgress(__LINE__); 1.145 + 1.146 + did = should = PR_FALSE; 1.147 + for (keys = 8; keys < 127; ++keys) 1.148 + { 1.149 + rv = PR_SetThreadPrivate(key[keys], NULL); 1.150 + MY_ASSERT(PR_SUCCESS == rv); 1.151 + } 1.152 + 1.153 + /* put in keys and leave them there for thread exit */ 1.154 + did = should = PR_FALSE; 1.155 + for (keys = 0; keys < 4; ++keys) 1.156 + { 1.157 + rv = PR_SetThreadPrivate(key[keys], key_string[keys]); 1.158 + MY_ASSERT(PR_SUCCESS == rv); 1.159 + } 1.160 + PrintProgress(__LINE__); 1.161 + did = PR_FALSE; should = PR_TRUE; 1.162 + 1.163 +} /* Thread */ 1.164 + 1.165 +static PRIntn PR_CALLBACK Tpd(PRIntn argc, char **argv) 1.166 +{ 1.167 + void *pd; 1.168 + PRStatus rv; 1.169 + PRUintn keys; 1.170 + PRThread *thread; 1.171 + char *key_string[] = { 1.172 + "Key #0", "Key #1", "Key #2", "Key #3", 1.173 + "Bogus #5", "Bogus #6", "Bogus #7", "Bogus #8"}; 1.174 + 1.175 + fout = PR_STDOUT; 1.176 + 1.177 + did = should = PR_FALSE; 1.178 + for (keys = 0; keys < 4; ++keys) 1.179 + { 1.180 + rv = PR_NewThreadPrivateIndex(&key[keys], Destructor); 1.181 + MY_ASSERT(PR_SUCCESS == rv); 1.182 + } 1.183 + PrintProgress(__LINE__); 1.184 + 1.185 + did = should = PR_FALSE; 1.186 + for (keys = 0; keys < 8; ++keys) 1.187 + { 1.188 + pd = PR_GetThreadPrivate(key[keys]); 1.189 + MY_ASSERT(NULL == pd); 1.190 + } 1.191 + PrintProgress(__LINE__); 1.192 + 1.193 + did = should = PR_FALSE; 1.194 + for (keys = 0; keys < 4; ++keys) 1.195 + { 1.196 + rv = PR_SetThreadPrivate(key[keys], key_string[keys]); 1.197 + MY_ASSERT(PR_SUCCESS == rv); 1.198 + } 1.199 + PrintProgress(__LINE__); 1.200 + 1.201 + for (keys = 4; keys < 8; ++keys) 1.202 + key[keys] = 4096; /* set to invalid value */ 1.203 + did = should = PR_FALSE; 1.204 + for (keys = 4; keys < 8; ++keys) 1.205 + { 1.206 + rv = PR_SetThreadPrivate(key[keys], key_string[keys]); 1.207 + MY_ASSERT(PR_FAILURE == rv); 1.208 + } 1.209 + PrintProgress(__LINE__); 1.210 + 1.211 + did = PR_FALSE; should = PR_TRUE; 1.212 + for (keys = 0; keys < 4; ++keys) 1.213 + { 1.214 + rv = PR_SetThreadPrivate(key[keys], key_string[keys]); 1.215 + MY_ASSERT(PR_SUCCESS == rv); 1.216 + } 1.217 + PrintProgress(__LINE__); 1.218 + 1.219 + did = PR_FALSE; should = PR_TRUE; 1.220 + for (keys = 0; keys < 4; ++keys) 1.221 + { 1.222 + rv = PR_SetThreadPrivate(key[keys], NULL); 1.223 + MY_ASSERT(PR_SUCCESS == rv); 1.224 + } 1.225 + PrintProgress(__LINE__); 1.226 + 1.227 + did = should = PR_FALSE; 1.228 + for (keys = 0; keys < 4; ++keys) 1.229 + { 1.230 + rv = PR_SetThreadPrivate(key[keys], NULL); 1.231 + MY_ASSERT(PR_SUCCESS == rv); 1.232 + } 1.233 + PrintProgress(__LINE__); 1.234 + 1.235 + did = should = PR_FALSE; 1.236 + for (keys = 8; keys < 127; ++keys) 1.237 + { 1.238 + rv = PR_NewThreadPrivateIndex(&key[keys], Destructor); 1.239 + MY_ASSERT(PR_SUCCESS == rv); 1.240 + rv = PR_SetThreadPrivate(key[keys], "EXTENSION"); 1.241 + MY_ASSERT(PR_SUCCESS == rv); 1.242 + } 1.243 + PrintProgress(__LINE__); 1.244 + 1.245 + did = PR_FALSE; should = PR_TRUE; 1.246 + for (keys = 8; keys < 127; ++keys) 1.247 + { 1.248 + rv = PR_SetThreadPrivate(key[keys], NULL); 1.249 + MY_ASSERT(PR_SUCCESS == rv); 1.250 + } 1.251 + PrintProgress(__LINE__); 1.252 + 1.253 + did = should = PR_FALSE; 1.254 + for (keys = 8; keys < 127; ++keys) 1.255 + { 1.256 + rv = PR_SetThreadPrivate(key[keys], NULL); 1.257 + MY_ASSERT(PR_SUCCESS == rv); 1.258 + } 1.259 + 1.260 + thread = PR_CreateThread( 1.261 + PR_USER_THREAD, Thread, NULL, PR_PRIORITY_NORMAL, 1.262 + PR_LOCAL_THREAD, PR_JOINABLE_THREAD, 0); 1.263 + 1.264 + (void)PR_JoinThread(thread); 1.265 + 1.266 + PrintProgress(__LINE__); 1.267 + 1.268 +#if defined(WIN16) 1.269 + printf( 1.270 + "%s\n",((PR_TRUE == failed) ? "FAILED" : "PASSED")); 1.271 +#else 1.272 + (void)PR_fprintf( 1.273 + fout, "%s\n",((PR_TRUE == failed) ? "FAILED" : "PASSED")); 1.274 +#endif 1.275 + 1.276 + return 0; 1.277 + 1.278 +} /* Tpd */ 1.279 + 1.280 +int main(int argc, char **argv) 1.281 +{ 1.282 + PLOptStatus os; 1.283 + PLOptState *opt = PL_CreateOptState(argc, argv, "dl:r:"); 1.284 + while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) 1.285 + { 1.286 + if (PL_OPT_BAD == os) continue; 1.287 + switch (opt->option) 1.288 + { 1.289 + case 'd': /* debug mode */ 1.290 + debug = PR_TRUE; 1.291 + break; 1.292 + default: 1.293 + break; 1.294 + } 1.295 + } 1.296 + PL_DestroyOptState(opt); 1.297 + PR_STDIO_INIT(); 1.298 + return PR_Initialize(Tpd, argc, argv, 0); 1.299 +} /* main */ 1.300 + 1.301 +/* tpd.c */