Add copy of .ttf font with .eot extension for testing
[wine-gecko.git] / xpcom / tests / TestProxies.cpp
blob779466ea855df5718ec4d517525fa3aed9018794
1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /* ***** BEGIN LICENSE BLOCK *****
3 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 * The contents of this file are subject to the Mozilla Public License Version
6 * 1.1 (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 * http://www.mozilla.org/MPL/
10 * Software distributed under the License is distributed on an "AS IS" basis,
11 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 * for the specific language governing rights and limitations under the
13 * License.
15 * The Original Code is Proxy Test Code.
17 * The Initial Developer of the Original Code is
18 * Ben Turner <bent.mozilla@gmail.com>.
19 * Portions created by the Initial Developer are Copyright (C) 2008
20 * the Initial Developer. All Rights Reserved.
22 * Contributor(s):
24 * Alternatively, the contents of this file may be used under the terms of
25 * either the GNU General Public License Version 2 or later (the "GPL"), or
26 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27 * in which case the provisions of the GPL or the LGPL are applicable instead
28 * of those above. If you wish to allow use of your version of this file only
29 * under the terms of either the GPL or the LGPL, and not to allow others to
30 * use your version of this file under the terms of the MPL, indicate your
31 * decision by deleting the provisions above and replace them with the notice
32 * and other provisions required by the GPL or the LGPL. If you do not delete
33 * the provisions above, a recipient may use your version of this file under
34 * the terms of any one of the MPL, the GPL or the LGPL.
36 * ***** END LICENSE BLOCK ***** */
38 #include "TestHarness.h"
40 #include "nsIEventTarget.h"
41 #include "nsIProxyObjectManager.h"
42 #include "nsIRunnable.h"
43 #include "nsIThread.h"
44 #include "nsIThreadPool.h"
46 #include "nsAutoLock.h"
47 #include "nsAutoPtr.h"
48 #include "nsCOMPtr.h"
49 #include "nsComponentManagerUtils.h"
50 #include "nsServiceManagerUtils.h"
51 #include "nsThreadUtils.h"
52 #include "nsXPCOMCIDInternal.h"
53 #include "prlog.h"
55 typedef nsresult(*TestFuncPtr)();
57 #define TEST_NAME "TestProxies"
59 #ifdef PR_LOGGING
60 static PRLogModuleInfo* sLog = PR_NewLogModule(TEST_NAME);
61 #endif
62 #define LOG(args) PR_LOG(sLog, PR_LOG_DEBUG, args)
64 static nsIThread* gMainThread = nsnull;
65 static nsIThread* gTestThread = nsnull;
67 static nsresult
68 GetProxyForObject(nsIEventTarget* aTarget,
69 REFNSIID aIID,
70 nsISupports* aObj,
71 PRInt32 aProxyType,
72 void** aProxyObject)
74 nsresult rv;
75 nsCOMPtr<nsIProxyObjectManager> proxyObjMgr =
76 do_GetService(NS_XPCOMPROXY_CONTRACTID, &rv);
77 NS_ENSURE_SUCCESS(rv, rv);
79 return proxyObjMgr->GetProxyForObject(aTarget, aIID, aObj, aProxyType,
80 aProxyObject);
83 class nsAutoTestThread
85 public:
86 nsAutoTestThread(nsIThread** aGlobal = nsnull)
87 : mGlobal(aGlobal)
89 nsCOMPtr<nsIThread> newThread;
90 nsresult rv = NS_NewThread(getter_AddRefs(newThread));
91 NS_ENSURE_SUCCESS(rv,);
93 rv = newThread->GetPRThread(&mNativeThread);
94 NS_ENSURE_SUCCESS(rv,);
96 LOG(("Created test thread [0x%p]", static_cast<void*>(mNativeThread)));
98 newThread.swap(mThread);
100 if (mGlobal)
101 *mGlobal = mThread;
104 ~nsAutoTestThread()
106 if (mGlobal)
107 *mGlobal = nsnull;
109 #ifdef PR_LOGGING
110 void* nativeThread = static_cast<void*>(mNativeThread);
111 #endif
113 LOG(("Shutting down test thread [0x%p]", nativeThread));
114 mThread->Shutdown();
115 LOG(("Test thread successfully shut down [0x%p]", nativeThread));
118 operator nsIThread*() const
120 return mThread;
123 nsIThread* operator->() const
125 return mThread;
128 private:
129 nsIThread** mGlobal;
130 nsCOMPtr<nsIThread> mThread;
131 PRThread* mNativeThread;
134 class SimpleRunnable : public nsRunnable
136 public:
137 SimpleRunnable(const char* aType = "SimpleRunnable")
138 : mType(aType)
141 NS_IMETHOD Run()
143 LOG(("%s::Run() [0x%p]", mType,
144 static_cast<void*>(static_cast<nsISupports*>(this))));
145 return NS_OK;
147 private:
148 const char* mType;
151 class TestTargetThreadRunnable : public SimpleRunnable
153 public:
154 TestTargetThreadRunnable(nsIThread* aTarget)
155 : SimpleRunnable("TestTargetThreadRunnable"),
156 mTarget(aTarget)
159 NS_IMETHOD Run()
161 nsresult rv = SimpleRunnable::Run();
162 NS_ENSURE_SUCCESS(rv, rv);
164 nsCOMPtr<nsIThread> currentThread(do_GetCurrentThread());
165 if (currentThread != mTarget) {
166 NS_ERROR("Proxy sent call to wrong thread!");
167 return NS_ERROR_FAILURE;
170 return NS_OK;
173 private:
174 nsCOMPtr<nsIThread> mTarget;
177 class ChainedProxyRunnable : public SimpleRunnable
179 public:
180 ChainedProxyRunnable(nsIThread* aSecondTarget,
181 nsIThread* aThirdTarget = nsnull)
182 : SimpleRunnable("ChainedProxyRunnable"), mSecondTarget(aSecondTarget),
183 mThirdTarget(aThirdTarget)
186 NS_IMETHOD Run()
188 nsresult rv = SimpleRunnable::Run();
189 NS_ENSURE_SUCCESS(rv, rv);
191 nsRefPtr<SimpleRunnable> runnable = mThirdTarget ?
192 new ChainedProxyRunnable(mThirdTarget) :
193 new SimpleRunnable();
194 NS_ENSURE_TRUE(runnable, NS_ERROR_OUT_OF_MEMORY);
196 nsCOMPtr<nsIRunnable> proxy;
197 rv = GetProxyForObject(mSecondTarget, NS_GET_IID(nsIRunnable), runnable,
198 NS_PROXY_SYNC | NS_PROXY_ALWAYS,
199 getter_AddRefs(proxy));
200 NS_ENSURE_SUCCESS(rv, rv);
202 rv = proxy->Run();
203 NS_ENSURE_SUCCESS(rv, rv);
205 return NS_OK;
208 private:
209 nsCOMPtr<nsIThread> mSecondTarget;
210 nsCOMPtr<nsIThread> mThirdTarget;
213 class IncrementingRunnable : public SimpleRunnable
215 public:
216 IncrementingRunnable(PRUint32* aCounter, PRLock* aLock = nsnull)
217 : SimpleRunnable("IncrementingRunnable"), mCounter(aCounter), mLock(aLock)
220 NS_IMETHOD Run()
222 nsresult rv = SimpleRunnable::Run();
223 NS_ENSURE_SUCCESS(rv, rv);
225 if (mLock)
226 PR_Lock(mLock);
228 (*mCounter)++;
230 if (mLock)
231 PR_Unlock(mLock);
233 return NS_OK;
236 private:
237 PRUint32* mCounter;
238 PRLock* mLock;
241 class NonThreadsafeRunnable : public nsIRunnable
243 public:
244 NS_DECL_ISUPPORTS
246 NonThreadsafeRunnable(PRUint32* aCounter,
247 const char* aType = "NonThreadsafeRunnable")
248 : mCounter(aCounter),
249 mType(aType)
252 virtual ~NonThreadsafeRunnable()
253 { };
255 NS_IMETHOD Run()
257 LOG(("%s::Run() [0x%p]", mType,
258 static_cast<void*>(static_cast<nsISupports*>(this))));
260 (*mCounter)++;
261 return NS_OK;
264 private:
265 PRUint32* mCounter;
266 const char* mType;
269 NS_IMPL_ISUPPORTS1(NonThreadsafeRunnable, nsIRunnable)
271 class MainThreadRunnable : public NonThreadsafeRunnable
273 public:
274 NS_DECL_ISUPPORTS_INHERITED
276 MainThreadRunnable(PRUint32* aCounter)
277 : NonThreadsafeRunnable(aCounter, "MainThreadRunnable")
279 if (!NS_IsMainThread()) {
280 NS_ERROR("Not running on the main thread!");
284 virtual ~MainThreadRunnable()
286 if (!NS_IsMainThread()) {
287 NS_ERROR("Not running on the main thread!");
291 NS_IMETHOD Run()
293 if (!NS_IsMainThread()) {
294 NS_ERROR("Not running on the main thread!");
295 return NS_ERROR_FAILURE;
298 nsresult rv = NonThreadsafeRunnable::Run();
299 NS_ENSURE_SUCCESS(rv, rv);
301 return NS_OK;
305 NS_IMPL_ISUPPORTS_INHERITED0(MainThreadRunnable, NonThreadsafeRunnable)
307 class ProxyGetter : public nsRunnable
309 public:
310 ProxyGetter(nsIRunnable* aRunnable, nsIRunnable** retval)
311 : mRunnable(aRunnable), _retval(retval)
314 NS_IMETHOD Run()
316 *_retval = nsnull;
318 if (NS_IsMainThread()) {
319 NS_ERROR("Shouldn't be running on the main thread!");
320 return NS_ERROR_FAILURE;
323 nsCOMPtr<nsIRunnable> proxy;
324 nsresult rv = GetProxyForObject(gMainThread, NS_GET_IID(nsIRunnable),
325 mRunnable, NS_PROXY_SYNC | NS_PROXY_ALWAYS,
326 getter_AddRefs(proxy));
327 NS_ENSURE_SUCCESS(rv, rv);
329 proxy.forget(_retval);
330 return NS_OK;
333 private:
334 nsIRunnable* mRunnable;
335 nsIRunnable** _retval;
338 class RunnableGetter : public nsRunnable
340 public:
341 RunnableGetter(PRUint32* aCounter, nsIRunnable** retval)
342 : mCounter(aCounter), _retval(retval)
345 NS_IMETHOD Run()
347 *_retval = nsnull;
349 if (NS_IsMainThread()) {
350 NS_ERROR("Shouldn't be running on the main thread!");
351 return NS_ERROR_FAILURE;
354 nsCOMPtr<nsIRunnable> runnable = new NonThreadsafeRunnable(mCounter);
355 NS_ENSURE_TRUE(runnable, NS_ERROR_OUT_OF_MEMORY);
357 runnable.forget(_retval);
358 return NS_OK;
361 private:
362 PRUint32* mCounter;
363 nsIRunnable** _retval;
366 nsresult
367 TestTargetThread()
369 LOG(("--- Running TestTargetThread ---"));
371 nsRefPtr<TestTargetThreadRunnable> runnable =
372 new TestTargetThreadRunnable(gMainThread);
373 NS_ENSURE_TRUE(runnable, NS_ERROR_OUT_OF_MEMORY);
375 nsCOMPtr<nsIRunnable> proxy;
376 nsresult rv = GetProxyForObject(gMainThread, NS_GET_IID(nsIRunnable),
377 runnable, NS_PROXY_SYNC | NS_PROXY_ALWAYS,
378 getter_AddRefs(proxy));
379 NS_ENSURE_SUCCESS(rv, rv);
381 rv = proxy->Run();
382 NS_ENSURE_SUCCESS(rv, rv);
384 runnable = new TestTargetThreadRunnable(gTestThread);
385 NS_ENSURE_TRUE(runnable, NS_ERROR_OUT_OF_MEMORY);
387 rv = GetProxyForObject(gTestThread, NS_GET_IID(nsIRunnable), runnable,
388 NS_PROXY_SYNC | NS_PROXY_ALWAYS, getter_AddRefs(proxy));
389 NS_ENSURE_SUCCESS(rv, rv);
391 rv = proxy->Run();
392 NS_ENSURE_SUCCESS(rv, rv);
394 return NS_OK;
397 nsresult
398 TestNonThreadsafeProxy()
400 LOG(("--- Running TestNonThreadsafeProxy 1 ---"));
402 // Make sure a non-threadsafe object and proxy to it (both created on the same
403 // thread) can be used on the same thread.
405 PRUint32 counter = 0;
406 nsCOMPtr<nsIRunnable> runnable(new MainThreadRunnable(&counter));
407 NS_ENSURE_TRUE(runnable, NS_ERROR_OUT_OF_MEMORY);
409 nsCOMPtr<nsIRunnable> proxy;
410 nsresult rv = GetProxyForObject(gMainThread, NS_GET_IID(nsIRunnable),
411 runnable, NS_PROXY_SYNC | NS_PROXY_ALWAYS,
412 getter_AddRefs(proxy));
413 NS_ENSURE_SUCCESS(rv, rv);
415 for (PRUint32 otherCounter = 0; otherCounter < 5;) {
416 rv = gTestThread->Dispatch(proxy, NS_DISPATCH_SYNC);
417 NS_ENSURE_SUCCESS(rv, rv);
418 NS_ENSURE_TRUE(counter == ++otherCounter, NS_ERROR_FAILURE);
421 // Make sure a non-threadsafe object and proxy to it (both created on the same
422 // thread) can be used on a different thread.
424 LOG(("--- Running TestNonThreadsafeProxy 2 ---"));
426 counter = 0;
427 runnable = new NonThreadsafeRunnable(&counter);
428 NS_ENSURE_TRUE(runnable, NS_ERROR_OUT_OF_MEMORY);
430 rv = GetProxyForObject(gTestThread, NS_GET_IID(nsIRunnable),
431 runnable, NS_PROXY_SYNC | NS_PROXY_ALWAYS,
432 getter_AddRefs(proxy));
433 NS_ENSURE_SUCCESS(rv, rv);
435 runnable = nsnull;
437 for (PRUint32 otherCounter = 0; otherCounter < 5;) {
438 rv = proxy->Run();
439 NS_ENSURE_SUCCESS(rv, rv);
440 NS_ENSURE_TRUE(counter == ++otherCounter, NS_ERROR_FAILURE);
443 NS_ENSURE_TRUE(counter == 5, NS_ERROR_FAILURE);
445 // Make sure a non-threadsafe object and proxy to it (created on different
446 // threads) can be used by any thread.
448 LOG(("--- Running TestNonThreadsafeProxy 3 ---"));
450 counter = 0;
451 proxy = nsnull;
453 runnable = new MainThreadRunnable(&counter);
454 NS_ENSURE_TRUE(runnable, NS_ERROR_OUT_OF_MEMORY);
456 nsCOMPtr<nsIRunnable> proxyGetter =
457 new ProxyGetter(runnable, getter_AddRefs(proxy));
458 NS_ENSURE_TRUE(proxyGetter, NS_ERROR_OUT_OF_MEMORY);
460 rv = gTestThread->Dispatch(proxyGetter, NS_DISPATCH_SYNC);
461 NS_ENSURE_SUCCESS(rv, rv);
462 NS_ENSURE_TRUE(proxy, NS_ERROR_FAILURE);
464 for (PRUint32 otherCounter = 0; otherCounter < 5;) {
465 rv = proxy->Run();
466 NS_ENSURE_SUCCESS(rv, rv);
467 NS_ENSURE_TRUE(counter == ++otherCounter, NS_ERROR_FAILURE);
470 // Make sure a non-threadsafe object (created on thread 1) and proxy to it
471 // (created on thread 2) can be used by thread 3.
473 LOG(("--- Running TestNonThreadsafeProxy 4 ---"));
475 counter = 0;
476 proxy = nsnull;
477 runnable = nsnull;
479 nsCOMPtr<nsIRunnable> runnableGetter =
480 new RunnableGetter(&counter, getter_AddRefs(runnable));
481 NS_ENSURE_TRUE(runnableGetter, NS_ERROR_OUT_OF_MEMORY);
483 rv = gTestThread->Dispatch(runnableGetter, NS_DISPATCH_SYNC);
484 NS_ENSURE_SUCCESS(rv, rv);
485 NS_ENSURE_TRUE(runnable, NS_ERROR_FAILURE);
487 proxyGetter = new ProxyGetter(runnable, getter_AddRefs(proxy));
488 NS_ENSURE_TRUE(proxyGetter, NS_ERROR_OUT_OF_MEMORY);
490 nsAutoTestThread otherTestThread;
491 NS_ENSURE_TRUE(otherTestThread, NS_ERROR_FAILURE);
493 rv = otherTestThread->Dispatch(proxyGetter, NS_DISPATCH_SYNC);
494 NS_ENSURE_SUCCESS(rv, rv);
495 NS_ENSURE_TRUE(proxy, NS_ERROR_FAILURE);
497 for (PRUint32 otherCounter = 0; otherCounter < 5;) {
498 rv = proxy->Run();
499 NS_ENSURE_SUCCESS(rv, rv);
500 NS_ENSURE_TRUE(counter == ++otherCounter, NS_ERROR_FAILURE);
503 return NS_OK;
506 nsresult
507 TestChainedProxy()
509 LOG(("--- Running TestChainedProxy ---"));
511 nsRefPtr<ChainedProxyRunnable> runnable =
512 new ChainedProxyRunnable(gMainThread);
513 NS_ENSURE_TRUE(runnable, NS_ERROR_OUT_OF_MEMORY);
515 nsCOMPtr<nsIRunnable> proxy;
516 nsresult rv = GetProxyForObject(gTestThread, NS_GET_IID(nsIRunnable),
517 runnable, NS_PROXY_SYNC | NS_PROXY_ALWAYS,
518 getter_AddRefs(proxy));
519 NS_ENSURE_SUCCESS(rv, rv);
521 // This will do a test->main call
522 rv = proxy->Run();
523 NS_ENSURE_SUCCESS(rv, rv);
525 runnable = new ChainedProxyRunnable(gTestThread);
526 NS_ENSURE_TRUE(runnable, NS_ERROR_OUT_OF_MEMORY);
528 rv = GetProxyForObject(gMainThread, NS_GET_IID(nsIRunnable), runnable,
529 NS_PROXY_SYNC | NS_PROXY_ALWAYS,
530 getter_AddRefs(proxy));
531 NS_ENSURE_SUCCESS(rv, rv);
533 // This will do a main->test call
534 rv = proxy->Run();
535 NS_ENSURE_SUCCESS(rv, rv);
537 runnable = new ChainedProxyRunnable(gMainThread);
538 NS_ENSURE_TRUE(runnable, NS_ERROR_OUT_OF_MEMORY);
540 rv = GetProxyForObject(gMainThread, NS_GET_IID(nsIRunnable), runnable,
541 NS_PROXY_SYNC | NS_PROXY_ALWAYS,
542 getter_AddRefs(proxy));
543 NS_ENSURE_SUCCESS(rv, rv);
545 // This will do a main->main call
546 rv = proxy->Run();
547 NS_ENSURE_SUCCESS(rv, rv);
549 runnable = new ChainedProxyRunnable(gTestThread);
550 NS_ENSURE_TRUE(runnable, NS_ERROR_OUT_OF_MEMORY);
552 rv = GetProxyForObject(gTestThread, NS_GET_IID(nsIRunnable), runnable,
553 NS_PROXY_SYNC | NS_PROXY_ALWAYS,
554 getter_AddRefs(proxy));
555 NS_ENSURE_SUCCESS(rv, rv);
557 // This will do a test->test call
558 rv = proxy->Run();
559 NS_ENSURE_SUCCESS(rv, rv);
561 runnable = new ChainedProxyRunnable(gMainThread, gTestThread);
562 NS_ENSURE_TRUE(runnable, NS_ERROR_OUT_OF_MEMORY);
564 rv = GetProxyForObject(gTestThread, NS_GET_IID(nsIRunnable), runnable,
565 NS_PROXY_SYNC | NS_PROXY_ALWAYS,
566 getter_AddRefs(proxy));
567 NS_ENSURE_SUCCESS(rv, rv);
569 // This will do a test->main->test call
570 rv = proxy->Run();
571 NS_ENSURE_SUCCESS(rv, rv);
573 return NS_OK;
576 nsresult
577 TestReleaseOfRealObjects()
579 LOG(("--- Running TestReleaseOfRealObjects ---"));
581 PRUint32 counter = 0, otherCounter = 0;
583 nsRefPtr<IncrementingRunnable> runnable(new IncrementingRunnable(&counter));
584 NS_ENSURE_TRUE(runnable, NS_ERROR_OUT_OF_MEMORY);
586 nsCOMPtr<nsIRunnable> proxy1;
587 nsresult rv = GetProxyForObject(gTestThread, NS_GET_IID(nsIRunnable),
588 runnable, NS_PROXY_SYNC | NS_PROXY_ALWAYS,
589 getter_AddRefs(proxy1));
590 NS_ENSURE_SUCCESS(rv, rv);
592 nsCOMPtr<nsIRunnable> proxy2;
593 rv = GetProxyForObject(gMainThread, NS_GET_IID(nsIRunnable), runnable,
594 NS_PROXY_SYNC | NS_PROXY_ALWAYS,
595 getter_AddRefs(proxy2));
596 NS_ENSURE_SUCCESS(rv, rv);
598 nsCOMPtr<nsIRunnable> proxy3;
599 rv = GetProxyForObject(gMainThread, NS_GET_IID(nsIRunnable), runnable,
600 NS_PROXY_SYNC | NS_PROXY_ALWAYS,
601 getter_AddRefs(proxy3));
602 NS_ENSURE_SUCCESS(rv, rv);
604 NS_ENSURE_FALSE(proxy1 == proxy2, NS_ERROR_FAILURE);
605 NS_ENSURE_TRUE(proxy2 == proxy3, NS_ERROR_FAILURE);
606 proxy3 = nsnull;
608 rv = proxy1->Run();
609 NS_ENSURE_SUCCESS(rv, rv);
610 NS_ENSURE_TRUE(counter == ++otherCounter, NS_ERROR_FAILURE);
612 rv = proxy2->Run();
613 NS_ENSURE_SUCCESS(rv, rv);
614 NS_ENSURE_TRUE(counter == ++otherCounter, NS_ERROR_FAILURE);
616 runnable = nsnull;
618 rv = proxy1->Run();
619 NS_ENSURE_SUCCESS(rv, rv);
620 NS_ENSURE_TRUE(counter == ++otherCounter, NS_ERROR_FAILURE);
622 rv = proxy2->Run();
623 NS_ENSURE_SUCCESS(rv, rv);
624 NS_ENSURE_TRUE(counter == ++otherCounter, NS_ERROR_FAILURE);
626 proxy1 = nsnull;
628 rv = proxy2->Run();
629 NS_ENSURE_SUCCESS(rv, rv);
630 NS_ENSURE_TRUE(counter == ++otherCounter, NS_ERROR_FAILURE);
632 return NS_OK;
635 nsresult
636 TestCurrentThreadProxy()
638 LOG(("--- Running TestCurrentThreadProxy ---"));
640 PRUint32 counter = 0, otherCounter = 0;
641 nsRefPtr<IncrementingRunnable> runnable(new IncrementingRunnable(&counter));
642 NS_ENSURE_TRUE(runnable, NS_ERROR_OUT_OF_MEMORY);
644 nsCOMPtr<nsIRunnable> proxy1;
645 nsresult rv = GetProxyForObject(gMainThread, NS_GET_IID(nsIRunnable),
646 runnable, NS_PROXY_SYNC,
647 getter_AddRefs(proxy1));
648 NS_ENSURE_SUCCESS(rv, rv);
650 nsCOMPtr<nsIRunnable> proxy2;
651 rv = GetProxyForObject(gMainThread, NS_GET_IID(nsIRunnable), runnable,
652 NS_PROXY_SYNC | NS_PROXY_ALWAYS,
653 getter_AddRefs(proxy2));
654 NS_ENSURE_SUCCESS(rv, rv);
656 NS_ENSURE_FALSE(proxy1 == proxy2, NS_ERROR_FAILURE);
658 nsCOMPtr<nsIRunnable> realRunnable(do_QueryInterface(runnable));
659 NS_ENSURE_TRUE(realRunnable, NS_ERROR_FAILURE);
661 NS_ENSURE_TRUE(static_cast<void*>(realRunnable) == static_cast<void*>(runnable),
662 NS_ERROR_FAILURE);
664 rv = proxy1->Run();
665 NS_ENSURE_SUCCESS(rv, rv);
666 NS_ENSURE_TRUE(counter == ++otherCounter, NS_ERROR_FAILURE);
668 rv = proxy2->Run();
669 NS_ENSURE_SUCCESS(rv, rv);
670 NS_ENSURE_TRUE(counter == ++otherCounter, NS_ERROR_FAILURE);
672 return NS_OK;
675 nsresult
676 TestAsyncProxy()
678 LOG(("--- Running TestAsyncProxy ---"));
680 // Test async proxies to the current thread.
682 PRUint32 counter = 0;
683 nsRefPtr<SimpleRunnable> runnable(new IncrementingRunnable(&counter));
684 NS_ENSURE_TRUE(runnable, NS_ERROR_OUT_OF_MEMORY);
686 nsCOMPtr<nsIRunnable> proxy;
687 nsresult rv = GetProxyForObject(gMainThread, NS_GET_IID(nsIRunnable),
688 runnable, NS_PROXY_ASYNC,
689 getter_AddRefs(proxy));
690 NS_ENSURE_SUCCESS(rv, rv);
692 runnable = nsnull;
694 for (PRUint32 i = 0; i < 5; i++) {
695 rv = proxy->Run();
696 NS_ENSURE_SUCCESS(rv, rv);
699 while (counter < 5) {
700 rv = NS_ProcessPendingEvents(gMainThread, PR_SecondsToInterval(1));
701 NS_ENSURE_SUCCESS(rv, rv);
704 // Now test async proxies to another thread.
706 PRLock* counterLock = nsAutoLock::NewLock("counterLock");
707 NS_ENSURE_TRUE(counterLock, NS_ERROR_OUT_OF_MEMORY);
709 counter = 0;
710 runnable = new IncrementingRunnable(&counter, counterLock);
711 NS_ENSURE_TRUE(runnable, NS_ERROR_OUT_OF_MEMORY);
713 rv = GetProxyForObject(gTestThread, NS_GET_IID(nsIRunnable), runnable,
714 NS_PROXY_ASYNC, getter_AddRefs(proxy));
715 NS_ENSURE_SUCCESS(rv, rv);
717 for (PRUint32 i = 0; i < 5; i++) {
718 rv = proxy->Run();
719 NS_ENSURE_SUCCESS(rv, rv);
722 PRUint32 safeCounter = 0;
723 while (safeCounter < 5) {
724 rv = NS_ProcessPendingEvents(gMainThread, PR_SecondsToInterval(1));
725 NS_ENSURE_SUCCESS(rv, rv);
727 nsAutoLock lock(counterLock);
728 safeCounter = counter;
731 nsAutoLock::DestroyLock(counterLock);
733 // Now test async proxies to another thread that create sync proxies to this
734 // thread.
736 runnable = new ChainedProxyRunnable(gMainThread);
737 NS_ENSURE_TRUE(runnable, NS_ERROR_OUT_OF_MEMORY);
739 rv = GetProxyForObject(gTestThread, NS_GET_IID(nsIRunnable),
740 runnable, NS_PROXY_ASYNC,
741 getter_AddRefs(proxy));
742 NS_ENSURE_SUCCESS(rv, rv);
744 rv = proxy->Run();
745 NS_ENSURE_SUCCESS(rv, rv);
747 // That was async, so make sure to wait for all the events on the test thread
748 // to be processed before we return. This is easy to do with an empty sync
749 // event.
750 nsCOMPtr<nsIRunnable> flusher = new nsRunnable();
751 NS_ENSURE_TRUE(flusher, NS_ERROR_OUT_OF_MEMORY);
753 LOG(("Flushing events on test thread"));
755 rv = gTestThread->Dispatch(flusher, NS_DISPATCH_SYNC);
756 NS_ENSURE_SUCCESS(rv, rv);
758 LOG(("Flushing events completed"));
760 return NS_OK;
763 int main(int argc, char** argv)
765 ScopedXPCOM xpcom(TEST_NAME);
766 NS_ENSURE_FALSE(xpcom.failed(), 1);
768 nsCOMPtr<nsIThread> mainThread(do_GetMainThread());
769 NS_ENSURE_TRUE(mainThread, 1);
771 LOG(("Got main thread"));
772 gMainThread = mainThread;
774 nsAutoTestThread testThread(&gTestThread);
775 NS_ENSURE_TRUE(testThread, 1);
777 static TestFuncPtr testsToRun[] = {
778 TestTargetThread,
779 // TestNonThreadsafeProxy, /* Not currently supported! */
780 TestChainedProxy,
781 TestReleaseOfRealObjects,
782 TestCurrentThreadProxy,
783 TestAsyncProxy
785 static PRUint32 testCount = sizeof(testsToRun) / sizeof(testsToRun[0]);
787 for (PRUint32 i = 0; i < testCount; i++) {
788 nsresult rv = testsToRun[i]();
789 NS_ENSURE_SUCCESS(rv, 1);
792 LOG(("--- Finished all tests ---"));
793 return 0;