Bug 846687 - Set the transport as non-seekable if the server sends Accept-Ranges...
[gecko.git] / xpcom / tests / TestThreads.cpp
blob1d8bea6c4307ec06bbc37c2c7b5f354e64c82e4e
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 #include "nsThreadUtils.h"
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include "nspr.h"
10 #include "nsCOMPtr.h"
11 #include "nsIServiceManager.h"
12 #include "nsXPCOM.h"
14 class nsRunner : public nsIRunnable {
15 public:
16 NS_DECL_ISUPPORTS
18 NS_IMETHOD Run() {
19 nsCOMPtr<nsIThread> thread;
20 nsresult rv = NS_GetCurrentThread(getter_AddRefs(thread));
21 if (NS_FAILED(rv)) {
22 printf("failed to get current thread\n");
23 return rv;
25 printf("running %d on thread %p\n", mNum, (void *)thread.get());
27 // if we don't do something slow, we'll never see the other
28 // worker threads run
29 PR_Sleep(PR_MillisecondsToInterval(100));
31 return rv;
34 nsRunner(int num) : mNum(num) {
37 protected:
38 int mNum;
41 NS_IMPL_THREADSAFE_ISUPPORTS1(nsRunner, nsIRunnable)
43 nsresult
44 TestThreads()
46 nsresult rv;
48 nsCOMPtr<nsIRunnable> event = new nsRunner(0);
49 if (!event)
50 return NS_ERROR_OUT_OF_MEMORY;
52 nsCOMPtr<nsIThread> runner;
53 rv = NS_NewThread(getter_AddRefs(runner), event);
54 if (NS_FAILED(rv)) {
55 printf("failed to create thread\n");
56 return rv;
59 nsCOMPtr<nsIThread> thread;
60 rv = NS_GetCurrentThread(getter_AddRefs(thread));
61 if (NS_FAILED(rv)) {
62 printf("failed to get current thread\n");
63 return rv;
66 rv = runner->Shutdown(); // wait for the runner to die before quitting
67 if (NS_FAILED(rv)) {
68 printf("join failed\n");
71 PR_Sleep(PR_MillisecondsToInterval(100)); // hopefully the runner will quit here
73 return NS_OK;
76 class nsStressRunner : public nsIRunnable {
77 public:
78 NS_DECL_ISUPPORTS
80 NS_IMETHOD Run() {
81 NS_ASSERTION(!mWasRun, "run twice!");
82 mWasRun = true;
83 PR_Sleep(1);
84 if (!PR_AtomicDecrement(&gNum)) {
85 printf(" last thread was %d\n", mNum);
87 return NS_OK;
90 nsStressRunner(int num) : mNum(num), mWasRun(false) {
91 PR_AtomicIncrement(&gNum);
94 static int32_t GetGlobalCount() {return gNum;}
96 private:
97 ~nsStressRunner() {
98 NS_ASSERTION(mWasRun, "never run!");
101 protected:
102 static int32_t gNum;
103 int32_t mNum;
104 bool mWasRun;
107 int32_t nsStressRunner::gNum = 0;
109 NS_IMPL_THREADSAFE_ISUPPORTS1(nsStressRunner, nsIRunnable)
111 static int Stress(int loops, int threads)
114 for (int i = 0; i < loops; i++) {
115 printf("Loop %d of %d\n", i+1, loops);
117 int k;
118 nsIThread** array = new nsIThread*[threads];
119 NS_ASSERTION(array, "out of memory");
121 NS_ASSERTION(!nsStressRunner::GetGlobalCount(), "bad count of runnables");
123 for (k = 0; k < threads; k++) {
124 nsCOMPtr<nsIThread> t;
125 nsresult rv = NS_NewThread(getter_AddRefs(t), new nsStressRunner(k));
126 if (NS_FAILED(rv)) {
127 NS_ERROR("can't create thread");
128 return -1;
130 NS_ADDREF(array[k] = t);
133 for (k = threads-1; k >= 0; k--) {
134 array[k]->Shutdown();
135 NS_RELEASE(array[k]);
137 delete [] array;
139 return 0;
142 static void threadProc(void *arg)
144 // printf(" running thread %d\n", (int) arg);
145 PR_Sleep(1);
146 PR_ASSERT(PR_JOINABLE_THREAD == PR_GetThreadState(PR_GetCurrentThread()));
149 static int StressNSPR(int loops, int threads)
152 for (int i = 0; i < loops; i++) {
153 printf("Loop %d of %d\n", i+1, loops);
155 int k;
156 PRThread** array = new PRThread*[threads];
157 PR_ASSERT(array);
159 for (k = 0; k < threads; k++) {
160 array[k] = PR_CreateThread(PR_USER_THREAD,
161 threadProc, (void*) k,
162 PR_PRIORITY_NORMAL,
163 PR_GLOBAL_THREAD,
164 PR_JOINABLE_THREAD,
166 PR_ASSERT(array[k]);
169 for (k = 0; k < threads; k++) {
170 PR_ASSERT(PR_JOINABLE_THREAD == PR_GetThreadState(array[k]));
173 for (k = threads-1; k >= 0; k--) {
174 PR_JoinThread(array[k]);
176 delete [] array;
178 return 0;
183 main(int argc, char** argv)
185 int retval = 0;
186 nsresult rv;
188 rv = NS_InitXPCOM2(nullptr, nullptr, nullptr);
189 if (NS_FAILED(rv)) return -1;
191 if (argc > 1 && !strcmp(argv[1], "-stress")) {
192 int loops;
193 int threads;
194 if (argc != 4 || *argv[2] != '-' || *argv[3] != '-' ||
195 !(loops = atoi(argv[2]+1)) || !(threads = atoi(argv[3]+1))) {
196 printf("To use -stress you must pass loop count and thread count...\n"
197 " TestThreads -stress -1000 -50\n");
198 } else {
199 printf("Running stress test with %d loops of %d threads each\n",
200 loops, threads);
201 retval = Stress(loops, threads);
203 } else if (argc > 1 && !strcmp(argv[1], "-stress-nspr")) {
204 int loops;
205 int threads;
206 if (argc != 4 || *argv[2] != '-' || *argv[3] != '-' ||
207 !(loops = atoi(argv[2]+1)) || !(threads = atoi(argv[3]+1))) {
208 printf("To use -stress-nspr you must pass loop count and thread count...\n"
209 " TestThreads -stress -1000 -50\n");
210 } else {
211 printf("Running stress test with %d loops of %d threads each\n",
212 loops, threads);
213 retval = StressNSPR(loops, threads);
215 } else {
216 rv = TestThreads();
217 if (NS_FAILED(rv)) return -1;
220 rv = NS_ShutdownXPCOM(nullptr);
221 if (NS_FAILED(rv)) return -1;
222 return retval;