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
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.
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"
49 #include "nsComponentManagerUtils.h"
50 #include "nsServiceManagerUtils.h"
51 #include "nsThreadUtils.h"
52 #include "nsXPCOMCIDInternal.h"
55 typedef nsresult(*TestFuncPtr
)();
57 #define TEST_NAME "TestProxies"
60 static PRLogModuleInfo
* sLog
= PR_NewLogModule(TEST_NAME
);
62 #define LOG(args) PR_LOG(sLog, PR_LOG_DEBUG, args)
64 static nsIThread
* gMainThread
= nsnull
;
65 static nsIThread
* gTestThread
= nsnull
;
68 GetProxyForObject(nsIEventTarget
* aTarget
,
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
,
83 class nsAutoTestThread
86 nsAutoTestThread(nsIThread
** aGlobal
= nsnull
)
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
);
110 void* nativeThread
= static_cast<void*>(mNativeThread
);
113 LOG(("Shutting down test thread [0x%p]", nativeThread
));
115 LOG(("Test thread successfully shut down [0x%p]", nativeThread
));
118 operator nsIThread
*() const
123 nsIThread
* operator->() const
130 nsCOMPtr
<nsIThread
> mThread
;
131 PRThread
* mNativeThread
;
134 class SimpleRunnable
: public nsRunnable
137 SimpleRunnable(const char* aType
= "SimpleRunnable")
143 LOG(("%s::Run() [0x%p]", mType
,
144 static_cast<void*>(static_cast<nsISupports
*>(this))));
151 class TestTargetThreadRunnable
: public SimpleRunnable
154 TestTargetThreadRunnable(nsIThread
* aTarget
)
155 : SimpleRunnable("TestTargetThreadRunnable"),
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
;
174 nsCOMPtr
<nsIThread
> mTarget
;
177 class ChainedProxyRunnable
: public SimpleRunnable
180 ChainedProxyRunnable(nsIThread
* aSecondTarget
,
181 nsIThread
* aThirdTarget
= nsnull
)
182 : SimpleRunnable("ChainedProxyRunnable"), mSecondTarget(aSecondTarget
),
183 mThirdTarget(aThirdTarget
)
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
);
203 NS_ENSURE_SUCCESS(rv
, rv
);
209 nsCOMPtr
<nsIThread
> mSecondTarget
;
210 nsCOMPtr
<nsIThread
> mThirdTarget
;
213 class IncrementingRunnable
: public SimpleRunnable
216 IncrementingRunnable(PRUint32
* aCounter
, PRLock
* aLock
= nsnull
)
217 : SimpleRunnable("IncrementingRunnable"), mCounter(aCounter
), mLock(aLock
)
222 nsresult rv
= SimpleRunnable::Run();
223 NS_ENSURE_SUCCESS(rv
, rv
);
241 class NonThreadsafeRunnable
: public nsIRunnable
246 NonThreadsafeRunnable(PRUint32
* aCounter
,
247 const char* aType
= "NonThreadsafeRunnable")
248 : mCounter(aCounter
),
252 virtual ~NonThreadsafeRunnable()
257 LOG(("%s::Run() [0x%p]", mType
,
258 static_cast<void*>(static_cast<nsISupports
*>(this))));
269 NS_IMPL_ISUPPORTS1(NonThreadsafeRunnable
, nsIRunnable
)
271 class MainThreadRunnable
: public NonThreadsafeRunnable
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!");
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
);
305 NS_IMPL_ISUPPORTS_INHERITED0(MainThreadRunnable
, NonThreadsafeRunnable
)
307 class ProxyGetter
: public nsRunnable
310 ProxyGetter(nsIRunnable
* aRunnable
, nsIRunnable
** retval
)
311 : mRunnable(aRunnable
), _retval(retval
)
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
);
334 nsIRunnable
* mRunnable
;
335 nsIRunnable
** _retval
;
338 class RunnableGetter
: public nsRunnable
341 RunnableGetter(PRUint32
* aCounter
, nsIRunnable
** retval
)
342 : mCounter(aCounter
), _retval(retval
)
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
);
363 nsIRunnable
** _retval
;
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
);
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
);
392 NS_ENSURE_SUCCESS(rv
, rv
);
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 ---"));
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
);
437 for (PRUint32 otherCounter
= 0; otherCounter
< 5;) {
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 ---"));
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;) {
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 ---"));
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;) {
499 NS_ENSURE_SUCCESS(rv
, rv
);
500 NS_ENSURE_TRUE(counter
== ++otherCounter
, NS_ERROR_FAILURE
);
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
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
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
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
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
571 NS_ENSURE_SUCCESS(rv
, rv
);
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
);
609 NS_ENSURE_SUCCESS(rv
, rv
);
610 NS_ENSURE_TRUE(counter
== ++otherCounter
, NS_ERROR_FAILURE
);
613 NS_ENSURE_SUCCESS(rv
, rv
);
614 NS_ENSURE_TRUE(counter
== ++otherCounter
, NS_ERROR_FAILURE
);
619 NS_ENSURE_SUCCESS(rv
, rv
);
620 NS_ENSURE_TRUE(counter
== ++otherCounter
, NS_ERROR_FAILURE
);
623 NS_ENSURE_SUCCESS(rv
, rv
);
624 NS_ENSURE_TRUE(counter
== ++otherCounter
, NS_ERROR_FAILURE
);
629 NS_ENSURE_SUCCESS(rv
, rv
);
630 NS_ENSURE_TRUE(counter
== ++otherCounter
, NS_ERROR_FAILURE
);
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
),
665 NS_ENSURE_SUCCESS(rv
, rv
);
666 NS_ENSURE_TRUE(counter
== ++otherCounter
, NS_ERROR_FAILURE
);
669 NS_ENSURE_SUCCESS(rv
, rv
);
670 NS_ENSURE_TRUE(counter
== ++otherCounter
, NS_ERROR_FAILURE
);
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
);
694 for (PRUint32 i
= 0; i
< 5; i
++) {
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
);
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
++) {
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
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
);
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
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"));
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
[] = {
779 // TestNonThreadsafeProxy, /* Not currently supported! */
781 TestReleaseOfRealObjects
,
782 TestCurrentThreadProxy
,
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 ---"));