Sat, 03 Jan 2015 20:18:00 +0100
Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 * vim: sw=4 ts=4 et :
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "TestHarness.h"
9 #include "mozilla/CondVar.h"
10 #include "mozilla/Monitor.h"
11 #include "mozilla/Mutex.h"
12 #include "nsAutoLock.h"
14 using namespace mozilla;
16 static PRThread*
17 spawn(void (*run)(void*), void* arg)
18 {
19 return PR_CreateThread(PR_SYSTEM_THREAD,
20 run,
21 arg,
22 PR_PRIORITY_NORMAL,
23 PR_GLOBAL_THREAD,
24 PR_JOINABLE_THREAD,
25 0);
26 }
29 #define PASS() \
30 do { \
31 passed(__FUNCTION__); \
32 return NS_OK; \
33 } while (0)
35 #define FAIL(why) \
36 do { \
37 fail("%s | %s - %s", __FILE__, __FUNCTION__, why); \
38 return NS_ERROR_FAILURE; \
39 } while (0)
41 //-----------------------------------------------------------------------------
42 // Sanity check: tests that can be done on a single thread
43 //
44 static nsresult
45 Sanity()
46 {
47 Mutex lock("sanity::lock");
48 lock.Lock();
49 lock.AssertCurrentThreadOwns();
50 lock.Unlock();
52 {
53 MutexAutoLock autolock(lock);
54 lock.AssertCurrentThreadOwns();
55 }
57 lock.Lock();
58 lock.AssertCurrentThreadOwns();
59 {
60 MutexAutoUnlock autounlock(lock);
61 }
62 lock.AssertCurrentThreadOwns();
63 lock.Unlock();
65 Monitor mon("sanity::monitor");
66 mon.Enter();
67 mon.AssertCurrentThreadIn();
68 mon.Enter();
69 mon.AssertCurrentThreadIn();
70 mon.Exit();
71 mon.AssertCurrentThreadIn();
72 mon.Exit();
74 {
75 MonitorAutoEnter automon(mon);
76 mon.AssertCurrentThreadIn();
77 }
79 PASS();
80 }
82 //-----------------------------------------------------------------------------
83 // Mutex contention tests
84 //
85 static Mutex* gLock1;
87 static void
88 MutexContention_thread(void* /*arg*/)
89 {
90 for (int i = 0; i < 100000; ++i) {
91 gLock1->Lock();
92 gLock1->AssertCurrentThreadOwns();
93 gLock1->Unlock();
94 }
95 }
97 static nsresult
98 MutexContention()
99 {
100 gLock1 = new Mutex("lock1");
101 // PURPOSELY not checking for OOM. YAY!
103 PRThread* t1 = spawn(MutexContention_thread, nullptr);
104 PRThread* t2 = spawn(MutexContention_thread, nullptr);
105 PRThread* t3 = spawn(MutexContention_thread, nullptr);
107 PR_JoinThread(t1);
108 PR_JoinThread(t2);
109 PR_JoinThread(t3);
111 delete gLock1;
113 PASS();
114 }
116 //-----------------------------------------------------------------------------
117 // Monitor tests
118 //
119 static Monitor* gMon1;
121 static void
122 MonitorContention_thread(void* /*arg*/)
123 {
124 for (int i = 0; i < 100000; ++i) {
125 gMon1->Enter();
126 gMon1->AssertCurrentThreadIn();
127 gMon1->Exit();
128 }
129 }
131 static nsresult
132 MonitorContention()
133 {
134 gMon1 = new Monitor("mon1");
136 PRThread* t1 = spawn(MonitorContention_thread, nullptr);
137 PRThread* t2 = spawn(MonitorContention_thread, nullptr);
138 PRThread* t3 = spawn(MonitorContention_thread, nullptr);
140 PR_JoinThread(t1);
141 PR_JoinThread(t2);
142 PR_JoinThread(t3);
144 delete gMon1;
146 PASS();
147 }
150 static Monitor* gMon2;
152 static void
153 MonitorContention2_thread(void* /*arg*/)
154 {
155 for (int i = 0; i < 100000; ++i) {
156 gMon2->Enter();
157 gMon2->AssertCurrentThreadIn();
158 {
159 gMon2->Enter();
160 gMon2->AssertCurrentThreadIn();
161 gMon2->Exit();
162 }
163 gMon2->AssertCurrentThreadIn();
164 gMon2->Exit();
165 }
166 }
168 static nsresult
169 MonitorContention2()
170 {
171 gMon2 = new Monitor("mon1");
173 PRThread* t1 = spawn(MonitorContention2_thread, nullptr);
174 PRThread* t2 = spawn(MonitorContention2_thread, nullptr);
175 PRThread* t3 = spawn(MonitorContention2_thread, nullptr);
177 PR_JoinThread(t1);
178 PR_JoinThread(t2);
179 PR_JoinThread(t3);
181 delete gMon2;
183 PASS();
184 }
187 static Monitor* gMon3;
188 static int32_t gMonFirst;
190 static void
191 MonitorSyncSanity_thread(void* /*arg*/)
192 {
193 gMon3->Enter();
194 gMon3->AssertCurrentThreadIn();
195 if (gMonFirst) {
196 gMonFirst = 0;
197 gMon3->Wait();
198 gMon3->Enter();
199 } else {
200 gMon3->Notify();
201 gMon3->Enter();
202 }
203 gMon3->AssertCurrentThreadIn();
204 gMon3->Exit();
205 gMon3->AssertCurrentThreadIn();
206 gMon3->Exit();
207 }
209 static nsresult
210 MonitorSyncSanity()
211 {
212 gMon3 = new Monitor("monitor::syncsanity");
214 for (int32_t i = 0; i < 10000; ++i) {
215 gMonFirst = 1;
216 PRThread* ping = spawn(MonitorSyncSanity_thread, nullptr);
217 PRThread* pong = spawn(MonitorSyncSanity_thread, nullptr);
218 PR_JoinThread(ping);
219 PR_JoinThread(pong);
220 }
222 delete gMon3;
224 PASS();
225 }
227 //-----------------------------------------------------------------------------
228 // Condvar tests
229 //
230 static Mutex* gCvlock1;
231 static CondVar* gCv1;
232 static int32_t gCvFirst;
234 static void
235 CondVarSanity_thread(void* /*arg*/)
236 {
237 gCvlock1->Lock();
238 gCvlock1->AssertCurrentThreadOwns();
239 if (gCvFirst) {
240 gCvFirst = 0;
241 gCv1->Wait();
242 } else {
243 gCv1->Notify();
244 }
245 gCvlock1->AssertCurrentThreadOwns();
246 gCvlock1->Unlock();
247 }
249 static nsresult
250 CondVarSanity()
251 {
252 gCvlock1 = new Mutex("cvlock1");
253 gCv1 = new CondVar(*gCvlock1, "cvlock1");
255 for (int32_t i = 0; i < 10000; ++i) {
256 gCvFirst = 1;
257 PRThread* ping = spawn(CondVarSanity_thread, nullptr);
258 PRThread* pong = spawn(CondVarSanity_thread, nullptr);
259 PR_JoinThread(ping);
260 PR_JoinThread(pong);
261 }
263 delete gCv1;
264 delete gCvlock1;
266 PASS();
267 }
269 //-----------------------------------------------------------------------------
270 // AutoLock tests
271 //
272 static nsresult
273 AutoLock()
274 {
275 Mutex l1("autolock");
276 MutexAutoLock autol1(l1);
278 l1.AssertCurrentThreadOwns();
280 {
281 Mutex l2("autolock2");
282 MutexAutoLock autol2(l2);
284 l1.AssertCurrentThreadOwns();
285 l2.AssertCurrentThreadOwns();
286 }
288 l1.AssertCurrentThreadOwns();
290 PASS();
291 }
293 //-----------------------------------------------------------------------------
294 // AutoUnlock tests
295 //
296 static nsresult
297 AutoUnlock()
298 {
299 Mutex l1("autounlock");
300 Mutex l2("autounlock2");
302 l1.Lock();
303 l1.AssertCurrentThreadOwns();
305 {
306 MutexAutoUnlock autol1(l1);
307 {
308 l2.Lock();
309 l2.AssertCurrentThreadOwns();
311 MutexAutoUnlock autol2(l2);
312 }
313 l2.AssertCurrentThreadOwns();
314 l2.Unlock();
315 }
316 l1.AssertCurrentThreadOwns();
318 l1.Unlock();
320 PASS();
321 }
323 //-----------------------------------------------------------------------------
324 // AutoMonitor tests
325 //
326 static nsresult
327 AutoMonitor()
328 {
329 Monitor m1("automonitor");
330 Monitor m2("automonitor2");
332 m1.Enter();
333 m1.AssertCurrentThreadIn();
334 {
335 MonitorAutoEnter autom1(m1);
336 m1.AssertCurrentThreadIn();
338 m2.Enter();
339 m2.AssertCurrentThreadIn();
340 {
341 MonitorAutoEnter autom2(m2);
342 m1.AssertCurrentThreadIn();
343 m2.AssertCurrentThreadIn();
344 }
345 m2.AssertCurrentThreadIn();
346 m2.Exit();
348 m1.AssertCurrentThreadIn();
349 }
350 m1.AssertCurrentThreadIn();
351 m1.Exit();
353 PASS();
354 }
356 //-----------------------------------------------------------------------------
358 int
359 main(int argc, char** argv)
360 {
361 ScopedXPCOM xpcom("Synchronization (" __FILE__ ")");
362 if (xpcom.failed())
363 return 1;
365 int rv = 0;
367 if (NS_FAILED(Sanity()))
368 rv = 1;
369 if (NS_FAILED(MutexContention()))
370 rv = 1;
371 if (NS_FAILED(MonitorContention()))
372 rv = 1;
373 if (NS_FAILED(MonitorContention2()))
374 rv = 1;
375 if (NS_FAILED(MonitorSyncSanity()))
376 rv = 1;
377 if (NS_FAILED(CondVarSanity()))
378 rv = 1;
379 if (NS_FAILED(AutoLock()))
380 rv = 1;
381 if (NS_FAILED(AutoUnlock()))
382 rv = 1;
383 if (NS_FAILED(AutoMonitor()))
384 rv = 1;
386 return rv;
387 }