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