diff options
Diffstat (limited to 'nsprpub/pr/tests/tpd.c')
-rw-r--r-- | nsprpub/pr/tests/tpd.c | 308 |
1 files changed, 308 insertions, 0 deletions
diff --git a/nsprpub/pr/tests/tpd.c b/nsprpub/pr/tests/tpd.c new file mode 100644 index 0000000000..cac8c59aaa --- /dev/null +++ b/nsprpub/pr/tests/tpd.c @@ -0,0 +1,308 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* +** File: tpd.c +** Description: Exercising the thread private data bailywick. +*/ + +#include "prmem.h" +#include "prinit.h" +#include "prlog.h" +#include "prprf.h" +#include "prthread.h" +#include "prtypes.h" + +#include "private/pprio.h" + +#include "plgetopt.h" + +static PRUintn key[128]; +static PRIntn debug = 0; +static PRBool failed = PR_FALSE; +static PRBool should = PR_TRUE; +static PRBool did = PR_TRUE; +static PRFileDesc *fout = NULL; + +static void PrintProgress(PRIntn line) +{ + failed = failed || (should && !did); + failed = failed || (!should && did); + if (debug > 0) + { +#if defined(WIN16) + printf( + "@ line %d destructor should%s have been called and was%s\n", + line, ((should) ? "" : " NOT"), ((did) ? "" : " NOT")); +#else + PR_fprintf( + fout, "@ line %d destructor should%s have been called and was%s\n", + line, ((should) ? "" : " NOT"), ((did) ? "" : " NOT")); +#endif + } +} /* PrintProgress */ + +static void MyAssert(const char *expr, const char *file, PRIntn line) +{ + if (debug > 0) { + (void)PR_fprintf(fout, "'%s' in file: %s: %d\n", expr, file, line); + } +} /* MyAssert */ + +#define MY_ASSERT(_expr) \ + ((_expr)?((void)0):MyAssert(# _expr,__FILE__,__LINE__)) + + +static void PR_CALLBACK Destructor(void *data) +{ + MY_ASSERT(NULL != data); + if (should) { + did = PR_TRUE; + } + else { + failed = PR_TRUE; + } + /* + * We don't actually free the storage since it's actually allocated + * on the stack. Normally, this would not be the case and this is + * the opportunity to free whatever. + PR_Free(data); + */ +} /* Destructor */ + +static void PR_CALLBACK Thread(void *null) +{ + void *pd; + PRStatus rv; + PRUintn keys; + char *key_string[] = { + "Key #0", "Key #1", "Key #2", "Key #3", + "Bogus #5", "Bogus #6", "Bogus #7", "Bogus #8" + }; + + did = should = PR_FALSE; + for (keys = 0; keys < 8; ++keys) + { + pd = PR_GetThreadPrivate(key[keys]); + MY_ASSERT(NULL == pd); + } + PrintProgress(__LINE__); + + did = should = PR_FALSE; + for (keys = 0; keys < 4; ++keys) + { + rv = PR_SetThreadPrivate(key[keys], key_string[keys]); + MY_ASSERT(PR_SUCCESS == rv); + } + PrintProgress(__LINE__); + + did = should = PR_FALSE; + for (keys = 4; keys < 8; ++keys) + { + rv = PR_SetThreadPrivate(key[keys], key_string[keys]); + MY_ASSERT(PR_FAILURE == rv); + } + PrintProgress(__LINE__); + + did = PR_FALSE; should = PR_TRUE; + for (keys = 0; keys < 4; ++keys) + { + rv = PR_SetThreadPrivate(key[keys], key_string[keys]); + MY_ASSERT(PR_SUCCESS == rv); + } + PrintProgress(__LINE__); + + did = PR_FALSE; should = PR_TRUE; + for (keys = 0; keys < 4; ++keys) + { + rv = PR_SetThreadPrivate(key[keys], NULL); + MY_ASSERT(PR_SUCCESS == rv); + } + PrintProgress(__LINE__); + + did = should = PR_FALSE; + for (keys = 0; keys < 4; ++keys) + { + rv = PR_SetThreadPrivate(key[keys], NULL); + MY_ASSERT(PR_SUCCESS == rv); + } + PrintProgress(__LINE__); + + did = should = PR_FALSE; + for (keys = 8; keys < 127; ++keys) + { + rv = PR_SetThreadPrivate(key[keys], "EXTENSION"); + MY_ASSERT(PR_SUCCESS == rv); + } + PrintProgress(__LINE__); + + did = PR_FALSE; should = PR_TRUE; + for (keys = 8; keys < 127; ++keys) + { + rv = PR_SetThreadPrivate(key[keys], NULL); + MY_ASSERT(PR_SUCCESS == rv); + } + PrintProgress(__LINE__); + + did = should = PR_FALSE; + for (keys = 8; keys < 127; ++keys) + { + rv = PR_SetThreadPrivate(key[keys], NULL); + MY_ASSERT(PR_SUCCESS == rv); + } + + /* put in keys and leave them there for thread exit */ + did = should = PR_FALSE; + for (keys = 0; keys < 4; ++keys) + { + rv = PR_SetThreadPrivate(key[keys], key_string[keys]); + MY_ASSERT(PR_SUCCESS == rv); + } + PrintProgress(__LINE__); + did = PR_FALSE; should = PR_TRUE; + +} /* Thread */ + +static PRIntn PR_CALLBACK Tpd(PRIntn argc, char **argv) +{ + void *pd; + PRStatus rv; + PRUintn keys; + PRThread *thread; + char *key_string[] = { + "Key #0", "Key #1", "Key #2", "Key #3", + "Bogus #5", "Bogus #6", "Bogus #7", "Bogus #8" + }; + + fout = PR_STDOUT; + + did = should = PR_FALSE; + for (keys = 0; keys < 4; ++keys) + { + rv = PR_NewThreadPrivateIndex(&key[keys], Destructor); + MY_ASSERT(PR_SUCCESS == rv); + } + PrintProgress(__LINE__); + + did = should = PR_FALSE; + for (keys = 0; keys < 8; ++keys) + { + pd = PR_GetThreadPrivate(key[keys]); + MY_ASSERT(NULL == pd); + } + PrintProgress(__LINE__); + + did = should = PR_FALSE; + for (keys = 0; keys < 4; ++keys) + { + rv = PR_SetThreadPrivate(key[keys], key_string[keys]); + MY_ASSERT(PR_SUCCESS == rv); + } + PrintProgress(__LINE__); + + for (keys = 4; keys < 8; ++keys) { + key[keys] = 4096; /* set to invalid value */ + } + did = should = PR_FALSE; + for (keys = 4; keys < 8; ++keys) + { + rv = PR_SetThreadPrivate(key[keys], key_string[keys]); + MY_ASSERT(PR_FAILURE == rv); + } + PrintProgress(__LINE__); + + did = PR_FALSE; should = PR_TRUE; + for (keys = 0; keys < 4; ++keys) + { + rv = PR_SetThreadPrivate(key[keys], key_string[keys]); + MY_ASSERT(PR_SUCCESS == rv); + } + PrintProgress(__LINE__); + + did = PR_FALSE; should = PR_TRUE; + for (keys = 0; keys < 4; ++keys) + { + rv = PR_SetThreadPrivate(key[keys], NULL); + MY_ASSERT(PR_SUCCESS == rv); + } + PrintProgress(__LINE__); + + did = should = PR_FALSE; + for (keys = 0; keys < 4; ++keys) + { + rv = PR_SetThreadPrivate(key[keys], NULL); + MY_ASSERT(PR_SUCCESS == rv); + } + PrintProgress(__LINE__); + + did = should = PR_FALSE; + for (keys = 8; keys < 127; ++keys) + { + rv = PR_NewThreadPrivateIndex(&key[keys], Destructor); + MY_ASSERT(PR_SUCCESS == rv); + rv = PR_SetThreadPrivate(key[keys], "EXTENSION"); + MY_ASSERT(PR_SUCCESS == rv); + } + PrintProgress(__LINE__); + + did = PR_FALSE; should = PR_TRUE; + for (keys = 8; keys < 127; ++keys) + { + rv = PR_SetThreadPrivate(key[keys], NULL); + MY_ASSERT(PR_SUCCESS == rv); + } + PrintProgress(__LINE__); + + did = should = PR_FALSE; + for (keys = 8; keys < 127; ++keys) + { + rv = PR_SetThreadPrivate(key[keys], NULL); + MY_ASSERT(PR_SUCCESS == rv); + } + + thread = PR_CreateThread( + PR_USER_THREAD, Thread, NULL, PR_PRIORITY_NORMAL, + PR_LOCAL_THREAD, PR_JOINABLE_THREAD, 0); + + (void)PR_JoinThread(thread); + + PrintProgress(__LINE__); + +#if defined(WIN16) + printf( + "%s\n",((PR_TRUE == failed) ? "FAILED" : "PASSED")); +#else + (void)PR_fprintf( + fout, "%s\n",((PR_TRUE == failed) ? "FAILED" : "PASSED")); +#endif + + return 0; + +} /* Tpd */ + +int main(int argc, char **argv) +{ + PLOptStatus os; + PLOptState *opt = PL_CreateOptState(argc, argv, "dl:r:"); + while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) + { + if (PL_OPT_BAD == os) { + continue; + } + switch (opt->option) + { + case 'd': /* debug mode */ + debug = PR_TRUE; + break; + default: + break; + } + } + PL_DestroyOptState(opt); + PR_STDIO_INIT(); + return PR_Initialize(Tpd, argc, argv, 0); +} /* main */ + +/* tpd.c */ |