Bug 846687 - Set the transport as non-seekable if the server sends Accept-Ranges...
[gecko.git] / xpcom / tests / TestSynchronization.cpp
blobb01a4c8d33f27b6ceb4fa750c74e7e2c3cc1b1a4
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)
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);
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
44 static nsresult
45 Sanity()
47 Mutex lock("sanity::lock");
48 lock.Lock();
49 lock.AssertCurrentThreadOwns();
50 lock.Unlock();
53 MutexAutoLock autolock(lock);
54 lock.AssertCurrentThreadOwns();
57 lock.Lock();
58 lock.AssertCurrentThreadOwns();
60 MutexAutoUnlock autounlock(lock);
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();
75 MonitorAutoEnter automon(mon);
76 mon.AssertCurrentThreadIn();
79 PASS();
82 //-----------------------------------------------------------------------------
83 // Mutex contention tests
85 static Mutex* gLock1;
87 static void
88 MutexContention_thread(void* /*arg*/)
90 for (int i = 0; i < 100000; ++i) {
91 gLock1->Lock();
92 gLock1->AssertCurrentThreadOwns();
93 gLock1->Unlock();
97 static nsresult
98 MutexContention()
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();
116 //-----------------------------------------------------------------------------
117 // Monitor tests
119 static Monitor* gMon1;
121 static void
122 MonitorContention_thread(void* /*arg*/)
124 for (int i = 0; i < 100000; ++i) {
125 gMon1->Enter();
126 gMon1->AssertCurrentThreadIn();
127 gMon1->Exit();
131 static nsresult
132 MonitorContention()
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();
150 static Monitor* gMon2;
152 static void
153 MonitorContention2_thread(void* /*arg*/)
155 for (int i = 0; i < 100000; ++i) {
156 gMon2->Enter();
157 gMon2->AssertCurrentThreadIn();
159 gMon2->Enter();
160 gMon2->AssertCurrentThreadIn();
161 gMon2->Exit();
163 gMon2->AssertCurrentThreadIn();
164 gMon2->Exit();
168 static nsresult
169 MonitorContention2()
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();
187 static Monitor* gMon3;
188 static int32_t gMonFirst;
190 static void
191 MonitorSyncSanity_thread(void* /*arg*/)
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();
203 gMon3->AssertCurrentThreadIn();
204 gMon3->Exit();
205 gMon3->AssertCurrentThreadIn();
206 gMon3->Exit();
209 static nsresult
210 MonitorSyncSanity()
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);
222 delete gMon3;
224 PASS();
227 //-----------------------------------------------------------------------------
228 // Condvar tests
230 static Mutex* gCvlock1;
231 static CondVar* gCv1;
232 static int32_t gCvFirst;
234 static void
235 CondVarSanity_thread(void* /*arg*/)
237 gCvlock1->Lock();
238 gCvlock1->AssertCurrentThreadOwns();
239 if (gCvFirst) {
240 gCvFirst = 0;
241 gCv1->Wait();
242 } else {
243 gCv1->Notify();
245 gCvlock1->AssertCurrentThreadOwns();
246 gCvlock1->Unlock();
249 static nsresult
250 CondVarSanity()
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);
263 delete gCv1;
264 delete gCvlock1;
266 PASS();
269 //-----------------------------------------------------------------------------
270 // AutoLock tests
272 static nsresult
273 AutoLock()
275 Mutex l1("autolock");
276 MutexAutoLock autol1(l1);
278 l1.AssertCurrentThreadOwns();
281 Mutex l2("autolock2");
282 MutexAutoLock autol2(l2);
284 l1.AssertCurrentThreadOwns();
285 l2.AssertCurrentThreadOwns();
288 l1.AssertCurrentThreadOwns();
290 PASS();
293 //-----------------------------------------------------------------------------
294 // AutoUnlock tests
296 static nsresult
297 AutoUnlock()
299 Mutex l1("autounlock");
300 Mutex l2("autounlock2");
302 l1.Lock();
303 l1.AssertCurrentThreadOwns();
306 MutexAutoUnlock autol1(l1);
308 l2.Lock();
309 l2.AssertCurrentThreadOwns();
311 MutexAutoUnlock autol2(l2);
313 l2.AssertCurrentThreadOwns();
314 l2.Unlock();
316 l1.AssertCurrentThreadOwns();
318 l1.Unlock();
320 PASS();
323 //-----------------------------------------------------------------------------
324 // AutoMonitor tests
326 static nsresult
327 AutoMonitor()
329 Monitor m1("automonitor");
330 Monitor m2("automonitor2");
332 m1.Enter();
333 m1.AssertCurrentThreadIn();
335 MonitorAutoEnter autom1(m1);
336 m1.AssertCurrentThreadIn();
338 m2.Enter();
339 m2.AssertCurrentThreadIn();
341 MonitorAutoEnter autom2(m2);
342 m1.AssertCurrentThreadIn();
343 m2.AssertCurrentThreadIn();
345 m2.AssertCurrentThreadIn();
346 m2.Exit();
348 m1.AssertCurrentThreadIn();
350 m1.AssertCurrentThreadIn();
351 m1.Exit();
353 PASS();
356 //-----------------------------------------------------------------------------
359 main(int argc, char** argv)
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;