nsprpub/pr/src/cplus/tests/tpd.cpp

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
michael@0 2 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 3 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 5
michael@0 6 /*
michael@0 7 ** File: tpd.cpp
michael@0 8 ** Description: Exercising the thread private data bailywick.
michael@0 9 */
michael@0 10
michael@0 11 #include "prlog.h"
michael@0 12 #include "prprf.h"
michael@0 13 #include "rcthread.h"
michael@0 14
michael@0 15 #include <string.h>
michael@0 16
michael@0 17 #include "plgetopt.h"
michael@0 18
michael@0 19 /*
michael@0 20 ** class MyThread
michael@0 21 */
michael@0 22 class MyThread: public RCThread
michael@0 23 {
michael@0 24 public:
michael@0 25 MyThread();
michael@0 26
michael@0 27 private:
michael@0 28 ~MyThread();
michael@0 29 void RootFunction();
michael@0 30 }; /* MyThread */
michael@0 31
michael@0 32 /*
michael@0 33 ** class MyPrivateData
michael@0 34 */
michael@0 35 class MyPrivateData: public RCThreadPrivateData
michael@0 36 {
michael@0 37 public:
michael@0 38 virtual ~MyPrivateData();
michael@0 39
michael@0 40 MyPrivateData();
michael@0 41 MyPrivateData(char*);
michael@0 42 MyPrivateData(const MyPrivateData&);
michael@0 43
michael@0 44 void Release();
michael@0 45
michael@0 46 private:
michael@0 47 char *string;
michael@0 48 }; /* MyPrivateData */
michael@0 49
michael@0 50 static PRUintn key[128];
michael@0 51 static PRIntn debug = 0;
michael@0 52 static PRBool failed = PR_FALSE;
michael@0 53 static PRBool should = PR_TRUE;
michael@0 54 static PRBool did = PR_TRUE;
michael@0 55 static PRFileDesc *fout = NULL;
michael@0 56
michael@0 57 static void PrintProgress(PRIntn line)
michael@0 58 {
michael@0 59 failed = failed || (should && !did);
michael@0 60 failed = failed || (!should && did);
michael@0 61 if (debug > 0)
michael@0 62 {
michael@0 63 PR_fprintf(
michael@0 64 fout, "@ line %d destructor should %shave been called and was%s\n",
michael@0 65 line, ((should) ? "" : "NOT "), ((did) ? "" : " NOT"));
michael@0 66 }
michael@0 67 } /* PrintProgress */
michael@0 68
michael@0 69 static void MyAssert(const char *expr, const char *file, PRIntn line)
michael@0 70 {
michael@0 71 if (debug > 0)
michael@0 72 (void)PR_fprintf(fout, "'%s' in file: %s: %d\n", expr, file, line);
michael@0 73 } /* MyAssert */
michael@0 74
michael@0 75 #define MY_ASSERT(_expr) \
michael@0 76 ((_expr)?((void)0):MyAssert(# _expr,__FILE__,__LINE__))
michael@0 77
michael@0 78 int main(PRIntn argc, char *argv[])
michael@0 79 {
michael@0 80 PRStatus rv;
michael@0 81 PRUintn keys;
michael@0 82 MyThread *thread;
michael@0 83 const RCThreadPrivateData *pd;
michael@0 84 PLOptStatus os;
michael@0 85 PLOptState *opt = PL_CreateOptState(argc, argv, "d");
michael@0 86 RCThread *primordial = RCThread::WrapPrimordialThread();
michael@0 87 while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
michael@0 88 {
michael@0 89 if (PL_OPT_BAD == os) continue;
michael@0 90 switch (opt->option)
michael@0 91 {
michael@0 92 case 'd': /* debug mode */
michael@0 93 debug = PR_TRUE;
michael@0 94 break;
michael@0 95 default:
michael@0 96 break;
michael@0 97 }
michael@0 98 }
michael@0 99 PL_DestroyOptState(opt);
michael@0 100
michael@0 101 fout = PR_STDOUT;
michael@0 102
michael@0 103 MyPrivateData extension = MyPrivateData("EXTENSION");
michael@0 104 MyPrivateData key_string[] = {
michael@0 105 "Key #0", "Key #1", "Key #2", "Key #3",
michael@0 106 "Bogus #5", "Bogus #6", "Bogus #7", "Bogus #8"};
michael@0 107
michael@0 108
michael@0 109 did = should = PR_FALSE;
michael@0 110 for (keys = 0; keys < 4; ++keys)
michael@0 111 {
michael@0 112 rv = RCThread::NewPrivateIndex(&key[keys]);
michael@0 113 key[keys + 4] = key[keys] + 4;
michael@0 114 MY_ASSERT(PR_SUCCESS == rv);
michael@0 115 }
michael@0 116 PrintProgress(__LINE__);
michael@0 117
michael@0 118 /* the first four should be bu null, the last four undefined and null */
michael@0 119 did = should = PR_FALSE;
michael@0 120 for (keys = 0; keys < 8; ++keys)
michael@0 121 {
michael@0 122 pd = RCThread::GetPrivateData(key[keys]);
michael@0 123 MY_ASSERT(NULL == pd);
michael@0 124 }
michael@0 125 PrintProgress(__LINE__);
michael@0 126
michael@0 127 /* initially set private data for new keys */
michael@0 128 did = should = PR_FALSE;
michael@0 129 for (keys = 0; keys < 4; ++keys)
michael@0 130 {
michael@0 131 rv = RCThread::SetPrivateData(key[keys], &key_string[keys]);
michael@0 132 MY_ASSERT(PR_SUCCESS == rv);
michael@0 133 }
michael@0 134 PrintProgress(__LINE__);
michael@0 135
michael@0 136 /* re-assign the private data, albeit the same content */
michael@0 137 did = PR_FALSE; should = PR_TRUE;
michael@0 138 for (keys = 0; keys < 4; ++keys)
michael@0 139 {
michael@0 140 pd = RCThread::GetPrivateData(key[keys]);
michael@0 141 PR_ASSERT(NULL != pd);
michael@0 142 rv = RCThread::SetPrivateData(key[keys], &key_string[keys]);
michael@0 143 MY_ASSERT(PR_SUCCESS == rv);
michael@0 144 }
michael@0 145 PrintProgress(__LINE__);
michael@0 146
michael@0 147 /* set private to <empty> */
michael@0 148 did = PR_FALSE; should = PR_TRUE;
michael@0 149 for (keys = 0; keys < 4; ++keys)
michael@0 150 {
michael@0 151 rv = RCThread::SetPrivateData(key[keys]);
michael@0 152 MY_ASSERT(PR_SUCCESS == rv);
michael@0 153 }
michael@0 154 PrintProgress(__LINE__);
michael@0 155
michael@0 156 /* should all be null now */
michael@0 157 did = should = PR_FALSE;
michael@0 158 for (keys = 0; keys < 4; ++keys)
michael@0 159 {
michael@0 160 pd = RCThread::GetPrivateData(key[keys]);
michael@0 161 PR_ASSERT(NULL == pd);
michael@0 162 }
michael@0 163 PrintProgress(__LINE__);
michael@0 164
michael@0 165 /* allocate another batch of keys and assign data to them */
michael@0 166 did = should = PR_FALSE;
michael@0 167 for (keys = 8; keys < 127; ++keys)
michael@0 168 {
michael@0 169 rv = RCThread::NewPrivateIndex(&key[keys]);
michael@0 170 MY_ASSERT(PR_SUCCESS == rv);
michael@0 171 rv = RCThread::SetPrivateData(key[keys], &extension);
michael@0 172 MY_ASSERT(PR_SUCCESS == rv);
michael@0 173 }
michael@0 174 PrintProgress(__LINE__);
michael@0 175
michael@0 176 /* set all the extended slots to <empty> */
michael@0 177 did = PR_FALSE; should = PR_TRUE;
michael@0 178 for (keys = 8; keys < 127; ++keys)
michael@0 179 {
michael@0 180 rv = RCThread::SetPrivateData(key[keys]);
michael@0 181 MY_ASSERT(PR_SUCCESS == rv);
michael@0 182 }
michael@0 183 PrintProgress(__LINE__);
michael@0 184
michael@0 185 /* set all the extended slots to <empty> again (noop) */
michael@0 186 did = should = PR_FALSE;
michael@0 187 for (keys = 8; keys < 127; ++keys)
michael@0 188 {
michael@0 189 rv = RCThread::SetPrivateData(key[keys]);
michael@0 190 MY_ASSERT(PR_SUCCESS == rv);
michael@0 191 }
michael@0 192
michael@0 193 if (debug) PR_fprintf(fout, "Creating thread\n");
michael@0 194 thread = new MyThread();
michael@0 195 if (debug) PR_fprintf(fout, "Starting thread\n");
michael@0 196 thread->Start();
michael@0 197 if (debug) PR_fprintf(fout, "Joining thread\n");
michael@0 198 (void)thread->Join();
michael@0 199 if (debug) PR_fprintf(fout, "Joined thread\n");
michael@0 200
michael@0 201 failed |= (PR_FAILURE == RCPrimordialThread::Cleanup());
michael@0 202
michael@0 203 (void)PR_fprintf(
michael@0 204 fout, "%s\n",((PR_TRUE == failed) ? "FAILED" : "PASSED"));
michael@0 205
michael@0 206 return (failed) ? 1 : 0;
michael@0 207
michael@0 208 } /* main */
michael@0 209
michael@0 210 /*
michael@0 211 ** class MyPrivateData
michael@0 212 */
michael@0 213 MyPrivateData::~MyPrivateData()
michael@0 214 {
michael@0 215 PR_fprintf(
michael@0 216 fout, "MyPrivateData::~MyPrivateData[%s]\n",
michael@0 217 (NULL != string) ? string : "NULL");
michael@0 218 } /* MyPrivateData::~MyPrivateData */
michael@0 219
michael@0 220 MyPrivateData::MyPrivateData(): RCThreadPrivateData()
michael@0 221 {
michael@0 222 PR_fprintf(fout, "MyPrivateData::MyPrivateData()\n");
michael@0 223 string = NULL;
michael@0 224 } /* MyPrivateData::MyPrivateData */
michael@0 225
michael@0 226 MyPrivateData::MyPrivateData(char* data): RCThreadPrivateData()
michael@0 227 {
michael@0 228 PR_fprintf(fout, "MyPrivateData::MyPrivateData(char* data)\n");
michael@0 229 string = data;
michael@0 230 } /* MyPrivateData:: MyPrivateData */
michael@0 231
michael@0 232 MyPrivateData::MyPrivateData(const MyPrivateData& him): RCThreadPrivateData(him)
michael@0 233 {
michael@0 234 PR_fprintf(fout, "MyPrivateData::MyPrivateData(const MyPrivateData& him)\n");
michael@0 235 string = him.string;
michael@0 236 } /* MyPrivateData:: MyPrivateData */
michael@0 237
michael@0 238 void MyPrivateData::Release()
michael@0 239 {
michael@0 240 if (should) did = PR_TRUE;
michael@0 241 else failed = PR_TRUE;
michael@0 242 } /* MyPrivateData::operator= */
michael@0 243
michael@0 244 /*
michael@0 245 ** class MyThread
michael@0 246 */
michael@0 247 MyThread::~MyThread() { }
michael@0 248 MyThread::MyThread(): RCThread(RCThread::global, RCThread::joinable) { }
michael@0 249
michael@0 250
michael@0 251 void MyThread::RootFunction()
michael@0 252 {
michael@0 253 PRStatus rv;
michael@0 254 PRUintn keys;
michael@0 255 const RCThreadPrivateData *pd;
michael@0 256
michael@0 257 MyPrivateData extension = MyPrivateData("EXTENSION");
michael@0 258 MyPrivateData key_string[] = {
michael@0 259 "Key #0", "Key #1", "Key #2", "Key #3",
michael@0 260 "Bogus #5", "Bogus #6", "Bogus #7", "Bogus #8"};
michael@0 261
michael@0 262 did = should = PR_FALSE;
michael@0 263 for (keys = 0; keys < 8; ++keys)
michael@0 264 {
michael@0 265 pd = GetPrivateData(key[keys]);
michael@0 266 MY_ASSERT(NULL == pd);
michael@0 267 }
michael@0 268 PrintProgress(__LINE__);
michael@0 269
michael@0 270 did = should = PR_FALSE;
michael@0 271 for (keys = 0; keys < 4; ++keys)
michael@0 272 {
michael@0 273 rv = SetPrivateData(keys, &key_string[keys]);
michael@0 274 MY_ASSERT(PR_SUCCESS == rv);
michael@0 275 }
michael@0 276 PrintProgress(__LINE__);
michael@0 277
michael@0 278 #if !defined(DEBUG)
michael@0 279 did = should = PR_FALSE;
michael@0 280 for (keys = 4; keys < 8; ++keys)
michael@0 281 {
michael@0 282 rv = SetPrivateData(keys, &key_string[keys]);
michael@0 283 MY_ASSERT(PR_FAILURE == rv);
michael@0 284 }
michael@0 285 PrintProgress(__LINE__);
michael@0 286 #endif
michael@0 287
michael@0 288 did = PR_FALSE; should = PR_TRUE;
michael@0 289 for (keys = 0; keys < 4; ++keys)
michael@0 290 {
michael@0 291 rv = SetPrivateData(key[keys], &key_string[keys]);
michael@0 292 MY_ASSERT(PR_SUCCESS == rv);
michael@0 293 }
michael@0 294 PrintProgress(__LINE__);
michael@0 295
michael@0 296 did = PR_FALSE; should = PR_TRUE;
michael@0 297 for (keys = 0; keys < 4; ++keys)
michael@0 298 {
michael@0 299 rv = SetPrivateData(key[keys]);
michael@0 300 MY_ASSERT(PR_SUCCESS == rv);
michael@0 301 }
michael@0 302 PrintProgress(__LINE__);
michael@0 303
michael@0 304 did = should = PR_FALSE;
michael@0 305 for (keys = 0; keys < 4; ++keys)
michael@0 306 {
michael@0 307 rv = SetPrivateData(key[keys]);
michael@0 308 MY_ASSERT(PR_SUCCESS == rv);
michael@0 309 }
michael@0 310 PrintProgress(__LINE__);
michael@0 311
michael@0 312 did = should = PR_FALSE;
michael@0 313 for (keys = 8; keys < 127; ++keys)
michael@0 314 {
michael@0 315 rv = SetPrivateData(key[keys], &extension);
michael@0 316 MY_ASSERT(PR_SUCCESS == rv);
michael@0 317 }
michael@0 318 PrintProgress(__LINE__);
michael@0 319
michael@0 320 did = PR_FALSE; should = PR_TRUE;
michael@0 321 for (keys = 8; keys < 127; ++keys)
michael@0 322 {
michael@0 323 rv = SetPrivateData(key[keys]);
michael@0 324 MY_ASSERT(PR_SUCCESS == rv);
michael@0 325 }
michael@0 326 PrintProgress(__LINE__);
michael@0 327
michael@0 328 did = should = PR_FALSE;
michael@0 329 for (keys = 8; keys < 127; ++keys)
michael@0 330 {
michael@0 331 rv = SetPrivateData(key[keys]);
michael@0 332 MY_ASSERT(PR_SUCCESS == rv);
michael@0 333 }
michael@0 334 } /* MyThread::RootFunction */
michael@0 335
michael@0 336 /* tpd.c */

mercurial