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 "nsAutoPtr.h"
48 #include "nsComponentManagerUtils.h"
49 #include "nsServiceManagerUtils.h"
50 #include "nsThreadUtils.h"
51 #include "nsXPCOMCIDInternal.h"
54 #include "mozilla/Mutex.h"
55 using namespace mozilla
;
57 typedef nsresult(*TestFuncPtr
)();
59 #define TEST_NAME "TestProxies"
62 static PRLogModuleInfo
* sLog
= PR_NewLogModule(TEST_NAME
);
64 #define LOG(args) PR_LOG(sLog, PR_LOG_DEBUG, args)
66 static nsIThread
* gMainThread
= nsnull
;
67 static nsIThread
* gTestThread
= nsnull
;
70 GetProxyForObject(nsIEventTarget
* aTarget
,
77 nsCOMPtr
<nsIProxyObjectManager
> proxyObjMgr
=
78 do_GetService(NS_XPCOMPROXY_CONTRACTID
, &rv
);
79 NS_ENSURE_SUCCESS(rv
, rv
);
81 return proxyObjMgr
->GetProxyForObject(aTarget
, aIID
, aObj
, aProxyType
,
85 class nsAutoTestThread
88 nsAutoTestThread(nsIThread
** aGlobal
= nsnull
)
91 nsCOMPtr
<nsIThread
> newThread
;
92 nsresult rv
= NS_NewThread(getter_AddRefs(newThread
));
96 rv
= newThread
->GetPRThread(&mNativeThread
);
100 LOG(("Created test thread [0x%p]", static_cast<void*>(mNativeThread
)));
102 newThread
.swap(mThread
);
114 void* nativeThread
= static_cast<void*>(mNativeThread
);
117 LOG(("Shutting down test thread [0x%p]", nativeThread
));
119 LOG(("Test thread successfully shut down [0x%p]", nativeThread
));
122 operator nsIThread
*() const
127 nsIThread
* operator->() const
134 nsCOMPtr
<nsIThread
> mThread
;
135 PRThread
* mNativeThread
;
138 class SimpleRunnable
: public nsRunnable
141 SimpleRunnable(const char* aType
= "SimpleRunnable")
147 LOG(("%s::Run() [0x%p]", mType
,
148 static_cast<void*>(static_cast<nsISupports
*>(this))));
155 class TestTargetThreadRunnable
: public SimpleRunnable
158 TestTargetThreadRunnable(nsIThread
* aTarget
)
159 : SimpleRunnable("TestTargetThreadRunnable"),
165 nsresult rv
= SimpleRunnable::Run();
166 NS_ENSURE_SUCCESS(rv
, rv
);
168 nsCOMPtr
<nsIThread
> currentThread(do_GetCurrentThread());
169 if (currentThread
!= mTarget
) {
170 NS_ERROR("Proxy sent call to wrong thread!");
171 return NS_ERROR_FAILURE
;
178 nsCOMPtr
<nsIThread
> mTarget
;
181 class ChainedProxyRunnable
: public SimpleRunnable
184 ChainedProxyRunnable(nsIThread
* aSecondTarget
,
185 nsIThread
* aThirdTarget
= nsnull
)
186 : SimpleRunnable("ChainedProxyRunnable"), mSecondTarget(aSecondTarget
),
187 mThirdTarget(aThirdTarget
)
192 nsresult rv
= SimpleRunnable::Run();
193 NS_ENSURE_SUCCESS(rv
, rv
);
195 nsRefPtr
<SimpleRunnable
> runnable
= mThirdTarget
?
196 new ChainedProxyRunnable(mThirdTarget
) :
197 new SimpleRunnable();
198 NS_ENSURE_TRUE(runnable
, NS_ERROR_OUT_OF_MEMORY
);
200 nsCOMPtr
<nsIRunnable
> proxy
;
201 rv
= GetProxyForObject(mSecondTarget
, NS_GET_IID(nsIRunnable
), runnable
,
202 NS_PROXY_SYNC
| NS_PROXY_ALWAYS
,
203 getter_AddRefs(proxy
));
204 NS_ENSURE_SUCCESS(rv
, rv
);
207 NS_ENSURE_SUCCESS(rv
, rv
);
213 nsCOMPtr
<nsIThread
> mSecondTarget
;
214 nsCOMPtr
<nsIThread
> mThirdTarget
;
217 class IncrementingRunnable
: public SimpleRunnable
220 IncrementingRunnable(PRUint32
* aCounter
, Mutex
* aLock
= nsnull
)
221 : SimpleRunnable("IncrementingRunnable"), mCounter(aCounter
), mLock(aLock
)
226 nsresult rv
= SimpleRunnable::Run();
227 NS_ENSURE_SUCCESS(rv
, rv
);
245 class NonThreadsafeRunnable
: public nsIRunnable
250 NonThreadsafeRunnable(PRUint32
* aCounter
,
251 const char* aType
= "NonThreadsafeRunnable")
252 : mCounter(aCounter
),
256 virtual ~NonThreadsafeRunnable()
261 LOG(("%s::Run() [0x%p]", mType
,
262 static_cast<void*>(static_cast<nsISupports
*>(this))));
273 NS_IMPL_ISUPPORTS1(NonThreadsafeRunnable
, nsIRunnable
)
275 class MainThreadRunnable
: public NonThreadsafeRunnable
278 NS_DECL_ISUPPORTS_INHERITED
280 MainThreadRunnable(PRUint32
* aCounter
)
281 : NonThreadsafeRunnable(aCounter
, "MainThreadRunnable")
283 if (!NS_IsMainThread()) {
284 NS_ERROR("Not running on the main thread!");
288 virtual ~MainThreadRunnable()
290 if (!NS_IsMainThread()) {
291 NS_ERROR("Not running on the main thread!");
297 if (!NS_IsMainThread()) {
298 NS_ERROR("Not running on the main thread!");
299 return NS_ERROR_FAILURE
;
302 nsresult rv
= NonThreadsafeRunnable::Run();
303 NS_ENSURE_SUCCESS(rv
, rv
);
309 NS_IMPL_ISUPPORTS_INHERITED0(MainThreadRunnable
, NonThreadsafeRunnable
)
311 class ProxyGetter
: public nsRunnable
314 ProxyGetter(nsIRunnable
* aRunnable
, nsIRunnable
** retval
)
315 : mRunnable(aRunnable
), _retval(retval
)
322 if (NS_IsMainThread()) {
323 NS_ERROR("Shouldn't be running on the main thread!");
324 return NS_ERROR_FAILURE
;
327 nsCOMPtr
<nsIRunnable
> proxy
;
328 nsresult rv
= GetProxyForObject(gMainThread
, NS_GET_IID(nsIRunnable
),
329 mRunnable
, NS_PROXY_SYNC
| NS_PROXY_ALWAYS
,
330 getter_AddRefs(proxy
));
331 NS_ENSURE_SUCCESS(rv
, rv
);
333 proxy
.forget(_retval
);
338 nsIRunnable
* mRunnable
;
339 nsIRunnable
** _retval
;
342 class RunnableGetter
: public nsRunnable
345 RunnableGetter(PRUint32
* aCounter
, nsIRunnable
** retval
)
346 : mCounter(aCounter
), _retval(retval
)
353 if (NS_IsMainThread()) {
354 NS_ERROR("Shouldn't be running on the main thread!");
355 return NS_ERROR_FAILURE
;
358 nsCOMPtr
<nsIRunnable
> runnable
= new NonThreadsafeRunnable(mCounter
);
359 NS_ENSURE_TRUE(runnable
, NS_ERROR_OUT_OF_MEMORY
);
361 runnable
.forget(_retval
);
367 nsIRunnable
** _retval
;
373 LOG(("--- Running TestTargetThread ---"));
375 nsRefPtr
<TestTargetThreadRunnable
> runnable
=
376 new TestTargetThreadRunnable(gMainThread
);
377 NS_ENSURE_TRUE(runnable
, NS_ERROR_OUT_OF_MEMORY
);
379 nsCOMPtr
<nsIRunnable
> proxy
;
380 nsresult rv
= GetProxyForObject(gMainThread
, NS_GET_IID(nsIRunnable
),
381 runnable
, NS_PROXY_SYNC
| NS_PROXY_ALWAYS
,
382 getter_AddRefs(proxy
));
383 NS_ENSURE_SUCCESS(rv
, rv
);
386 NS_ENSURE_SUCCESS(rv
, rv
);
388 runnable
= new TestTargetThreadRunnable(gTestThread
);
389 NS_ENSURE_TRUE(runnable
, NS_ERROR_OUT_OF_MEMORY
);
391 rv
= GetProxyForObject(gTestThread
, NS_GET_IID(nsIRunnable
), runnable
,
392 NS_PROXY_SYNC
| NS_PROXY_ALWAYS
, getter_AddRefs(proxy
));
393 NS_ENSURE_SUCCESS(rv
, rv
);
396 NS_ENSURE_SUCCESS(rv
, rv
);
402 TestNonThreadsafeProxy()
404 LOG(("--- Running TestNonThreadsafeProxy 1 ---"));
406 // Make sure a non-threadsafe object and proxy to it (both created on the same
407 // thread) can be used on the same thread.
409 PRUint32 counter
= 0;
410 nsCOMPtr
<nsIRunnable
> runnable(new MainThreadRunnable(&counter
));
411 NS_ENSURE_TRUE(runnable
, NS_ERROR_OUT_OF_MEMORY
);
413 nsCOMPtr
<nsIRunnable
> proxy
;
414 nsresult rv
= GetProxyForObject(gMainThread
, NS_GET_IID(nsIRunnable
),
415 runnable
, NS_PROXY_SYNC
| NS_PROXY_ALWAYS
,
416 getter_AddRefs(proxy
));
417 NS_ENSURE_SUCCESS(rv
, rv
);
419 for (PRUint32 otherCounter
= 0; otherCounter
< 5;) {
420 rv
= gTestThread
->Dispatch(proxy
, NS_DISPATCH_SYNC
);
421 NS_ENSURE_SUCCESS(rv
, rv
);
422 NS_ENSURE_TRUE(counter
== ++otherCounter
, NS_ERROR_FAILURE
);
425 // Make sure a non-threadsafe object and proxy to it (both created on the same
426 // thread) can be used on a different thread.
428 LOG(("--- Running TestNonThreadsafeProxy 2 ---"));
431 runnable
= new NonThreadsafeRunnable(&counter
);
432 NS_ENSURE_TRUE(runnable
, NS_ERROR_OUT_OF_MEMORY
);
434 rv
= GetProxyForObject(gTestThread
, NS_GET_IID(nsIRunnable
),
435 runnable
, NS_PROXY_SYNC
| NS_PROXY_ALWAYS
,
436 getter_AddRefs(proxy
));
437 NS_ENSURE_SUCCESS(rv
, rv
);
441 for (PRUint32 otherCounter
= 0; otherCounter
< 5;) {
443 NS_ENSURE_SUCCESS(rv
, rv
);
444 NS_ENSURE_TRUE(counter
== ++otherCounter
, NS_ERROR_FAILURE
);
447 NS_ENSURE_TRUE(counter
== 5, NS_ERROR_FAILURE
);
449 // Make sure a non-threadsafe object and proxy to it (created on different
450 // threads) can be used by any thread.
452 LOG(("--- Running TestNonThreadsafeProxy 3 ---"));
457 runnable
= new MainThreadRunnable(&counter
);
458 NS_ENSURE_TRUE(runnable
, NS_ERROR_OUT_OF_MEMORY
);
460 nsCOMPtr
<nsIRunnable
> proxyGetter
=
461 new ProxyGetter(runnable
, getter_AddRefs(proxy
));
462 NS_ENSURE_TRUE(proxyGetter
, NS_ERROR_OUT_OF_MEMORY
);
464 rv
= gTestThread
->Dispatch(proxyGetter
, NS_DISPATCH_SYNC
);
465 NS_ENSURE_SUCCESS(rv
, rv
);
466 NS_ENSURE_TRUE(proxy
, NS_ERROR_FAILURE
);
468 for (PRUint32 otherCounter
= 0; otherCounter
< 5;) {
470 NS_ENSURE_SUCCESS(rv
, rv
);
471 NS_ENSURE_TRUE(counter
== ++otherCounter
, NS_ERROR_FAILURE
);
474 // Make sure a non-threadsafe object (created on thread 1) and proxy to it
475 // (created on thread 2) can be used by thread 3.
477 LOG(("--- Running TestNonThreadsafeProxy 4 ---"));
483 nsCOMPtr
<nsIRunnable
> runnableGetter
=
484 new RunnableGetter(&counter
, getter_AddRefs(runnable
));
485 NS_ENSURE_TRUE(runnableGetter
, NS_ERROR_OUT_OF_MEMORY
);
487 rv
= gTestThread
->Dispatch(runnableGetter
, NS_DISPATCH_SYNC
);
488 NS_ENSURE_SUCCESS(rv
, rv
);
489 NS_ENSURE_TRUE(runnable
, NS_ERROR_FAILURE
);
491 proxyGetter
= new ProxyGetter(runnable
, getter_AddRefs(proxy
));
492 NS_ENSURE_TRUE(proxyGetter
, NS_ERROR_OUT_OF_MEMORY
);
494 nsAutoTestThread otherTestThread
;
495 NS_ENSURE_TRUE(otherTestThread
, NS_ERROR_FAILURE
);
497 rv
= otherTestThread
->Dispatch(proxyGetter
, NS_DISPATCH_SYNC
);
498 NS_ENSURE_SUCCESS(rv
, rv
);
499 NS_ENSURE_TRUE(proxy
, NS_ERROR_FAILURE
);
501 for (PRUint32 otherCounter
= 0; otherCounter
< 5;) {
503 NS_ENSURE_SUCCESS(rv
, rv
);
504 NS_ENSURE_TRUE(counter
== ++otherCounter
, NS_ERROR_FAILURE
);
513 LOG(("--- Running TestChainedProxy ---"));
515 nsRefPtr
<ChainedProxyRunnable
> runnable
=
516 new ChainedProxyRunnable(gMainThread
);
517 NS_ENSURE_TRUE(runnable
, NS_ERROR_OUT_OF_MEMORY
);
519 nsCOMPtr
<nsIRunnable
> proxy
;
520 nsresult rv
= GetProxyForObject(gTestThread
, NS_GET_IID(nsIRunnable
),
521 runnable
, NS_PROXY_SYNC
| NS_PROXY_ALWAYS
,
522 getter_AddRefs(proxy
));
523 NS_ENSURE_SUCCESS(rv
, rv
);
525 // This will do a test->main call
527 NS_ENSURE_SUCCESS(rv
, rv
);
529 runnable
= new ChainedProxyRunnable(gTestThread
);
530 NS_ENSURE_TRUE(runnable
, NS_ERROR_OUT_OF_MEMORY
);
532 rv
= GetProxyForObject(gMainThread
, NS_GET_IID(nsIRunnable
), runnable
,
533 NS_PROXY_SYNC
| NS_PROXY_ALWAYS
,
534 getter_AddRefs(proxy
));
535 NS_ENSURE_SUCCESS(rv
, rv
);
537 // This will do a main->test call
539 NS_ENSURE_SUCCESS(rv
, rv
);
541 runnable
= new ChainedProxyRunnable(gMainThread
);
542 NS_ENSURE_TRUE(runnable
, NS_ERROR_OUT_OF_MEMORY
);
544 rv
= GetProxyForObject(gMainThread
, NS_GET_IID(nsIRunnable
), runnable
,
545 NS_PROXY_SYNC
| NS_PROXY_ALWAYS
,
546 getter_AddRefs(proxy
));
547 NS_ENSURE_SUCCESS(rv
, rv
);
549 // This will do a main->main call
551 NS_ENSURE_SUCCESS(rv
, rv
);
553 runnable
= new ChainedProxyRunnable(gTestThread
);
554 NS_ENSURE_TRUE(runnable
, NS_ERROR_OUT_OF_MEMORY
);
556 rv
= GetProxyForObject(gTestThread
, NS_GET_IID(nsIRunnable
), runnable
,
557 NS_PROXY_SYNC
| NS_PROXY_ALWAYS
,
558 getter_AddRefs(proxy
));
559 NS_ENSURE_SUCCESS(rv
, rv
);
561 // This will do a test->test call
563 NS_ENSURE_SUCCESS(rv
, rv
);
565 runnable
= new ChainedProxyRunnable(gMainThread
, gTestThread
);
566 NS_ENSURE_TRUE(runnable
, NS_ERROR_OUT_OF_MEMORY
);
568 rv
= GetProxyForObject(gTestThread
, NS_GET_IID(nsIRunnable
), runnable
,
569 NS_PROXY_SYNC
| NS_PROXY_ALWAYS
,
570 getter_AddRefs(proxy
));
571 NS_ENSURE_SUCCESS(rv
, rv
);
573 // This will do a test->main->test call
575 NS_ENSURE_SUCCESS(rv
, rv
);
581 TestReleaseOfRealObjects()
583 LOG(("--- Running TestReleaseOfRealObjects ---"));
585 PRUint32 counter
= 0, otherCounter
= 0;
587 nsRefPtr
<IncrementingRunnable
> runnable(new IncrementingRunnable(&counter
));
588 NS_ENSURE_TRUE(runnable
, NS_ERROR_OUT_OF_MEMORY
);
590 nsCOMPtr
<nsIRunnable
> proxy1
;
591 nsresult rv
= GetProxyForObject(gTestThread
, NS_GET_IID(nsIRunnable
),
592 runnable
, NS_PROXY_SYNC
| NS_PROXY_ALWAYS
,
593 getter_AddRefs(proxy1
));
594 NS_ENSURE_SUCCESS(rv
, rv
);
596 nsCOMPtr
<nsIRunnable
> proxy2
;
597 rv
= GetProxyForObject(gMainThread
, NS_GET_IID(nsIRunnable
), runnable
,
598 NS_PROXY_SYNC
| NS_PROXY_ALWAYS
,
599 getter_AddRefs(proxy2
));
600 NS_ENSURE_SUCCESS(rv
, rv
);
602 nsCOMPtr
<nsIRunnable
> proxy3
;
603 rv
= GetProxyForObject(gMainThread
, NS_GET_IID(nsIRunnable
), runnable
,
604 NS_PROXY_SYNC
| NS_PROXY_ALWAYS
,
605 getter_AddRefs(proxy3
));
606 NS_ENSURE_SUCCESS(rv
, rv
);
608 NS_ENSURE_FALSE(proxy1
== proxy2
, NS_ERROR_FAILURE
);
609 NS_ENSURE_TRUE(proxy2
== proxy3
, NS_ERROR_FAILURE
);
613 NS_ENSURE_SUCCESS(rv
, rv
);
614 NS_ENSURE_TRUE(counter
== ++otherCounter
, NS_ERROR_FAILURE
);
617 NS_ENSURE_SUCCESS(rv
, rv
);
618 NS_ENSURE_TRUE(counter
== ++otherCounter
, NS_ERROR_FAILURE
);
623 NS_ENSURE_SUCCESS(rv
, rv
);
624 NS_ENSURE_TRUE(counter
== ++otherCounter
, NS_ERROR_FAILURE
);
627 NS_ENSURE_SUCCESS(rv
, rv
);
628 NS_ENSURE_TRUE(counter
== ++otherCounter
, NS_ERROR_FAILURE
);
633 NS_ENSURE_SUCCESS(rv
, rv
);
634 NS_ENSURE_TRUE(counter
== ++otherCounter
, NS_ERROR_FAILURE
);
640 TestCurrentThreadProxy()
642 LOG(("--- Running TestCurrentThreadProxy ---"));
644 PRUint32 counter
= 0, otherCounter
= 0;
645 nsRefPtr
<IncrementingRunnable
> runnable(new IncrementingRunnable(&counter
));
646 NS_ENSURE_TRUE(runnable
, NS_ERROR_OUT_OF_MEMORY
);
648 nsCOMPtr
<nsIRunnable
> proxy1
;
649 nsresult rv
= GetProxyForObject(gMainThread
, NS_GET_IID(nsIRunnable
),
650 runnable
, NS_PROXY_SYNC
,
651 getter_AddRefs(proxy1
));
652 NS_ENSURE_SUCCESS(rv
, rv
);
654 nsCOMPtr
<nsIRunnable
> proxy2
;
655 rv
= GetProxyForObject(gMainThread
, NS_GET_IID(nsIRunnable
), runnable
,
656 NS_PROXY_SYNC
| NS_PROXY_ALWAYS
,
657 getter_AddRefs(proxy2
));
658 NS_ENSURE_SUCCESS(rv
, rv
);
660 NS_ENSURE_FALSE(proxy1
== proxy2
, NS_ERROR_FAILURE
);
662 nsCOMPtr
<nsIRunnable
> realRunnable(do_QueryInterface(runnable
));
663 NS_ENSURE_TRUE(realRunnable
, NS_ERROR_FAILURE
);
665 NS_ENSURE_TRUE(static_cast<void*>(realRunnable
) == static_cast<void*>(runnable
),
669 NS_ENSURE_SUCCESS(rv
, rv
);
670 NS_ENSURE_TRUE(counter
== ++otherCounter
, NS_ERROR_FAILURE
);
673 NS_ENSURE_SUCCESS(rv
, rv
);
674 NS_ENSURE_TRUE(counter
== ++otherCounter
, NS_ERROR_FAILURE
);
682 LOG(("--- Running TestAsyncProxy ---"));
684 // Test async proxies to the current thread.
686 PRUint32 counter
= 0;
687 nsRefPtr
<SimpleRunnable
> runnable(new IncrementingRunnable(&counter
));
688 NS_ENSURE_TRUE(runnable
, NS_ERROR_OUT_OF_MEMORY
);
690 nsCOMPtr
<nsIRunnable
> proxy
;
691 nsresult rv
= GetProxyForObject(gMainThread
, NS_GET_IID(nsIRunnable
),
692 runnable
, NS_PROXY_ASYNC
,
693 getter_AddRefs(proxy
));
694 NS_ENSURE_SUCCESS(rv
, rv
);
698 for (PRUint32 i
= 0; i
< 5; i
++) {
700 NS_ENSURE_SUCCESS(rv
, rv
);
703 while (counter
< 5) {
704 rv
= NS_ProcessPendingEvents(gMainThread
, PR_SecondsToInterval(1));
705 NS_ENSURE_SUCCESS(rv
, rv
);
708 // Now test async proxies to another thread.
710 Mutex
* counterLock
= new Mutex("counterLock");
711 NS_ENSURE_TRUE(counterLock
, NS_ERROR_OUT_OF_MEMORY
);
714 runnable
= new IncrementingRunnable(&counter
, counterLock
);
715 NS_ENSURE_TRUE(runnable
, NS_ERROR_OUT_OF_MEMORY
);
717 rv
= GetProxyForObject(gTestThread
, NS_GET_IID(nsIRunnable
), runnable
,
718 NS_PROXY_ASYNC
, getter_AddRefs(proxy
));
719 NS_ENSURE_SUCCESS(rv
, rv
);
721 for (PRUint32 i
= 0; i
< 5; i
++) {
723 NS_ENSURE_SUCCESS(rv
, rv
);
726 PRUint32 safeCounter
= 0;
727 while (safeCounter
< 5) {
728 rv
= NS_ProcessPendingEvents(gMainThread
, PR_SecondsToInterval(1));
729 NS_ENSURE_SUCCESS(rv
, rv
);
731 MutexAutoLock
lock(*counterLock
);
732 safeCounter
= counter
;
737 // Now test async proxies to another thread that create sync proxies to this
740 runnable
= new ChainedProxyRunnable(gMainThread
);
741 NS_ENSURE_TRUE(runnable
, NS_ERROR_OUT_OF_MEMORY
);
743 rv
= GetProxyForObject(gTestThread
, NS_GET_IID(nsIRunnable
),
744 runnable
, NS_PROXY_ASYNC
,
745 getter_AddRefs(proxy
));
746 NS_ENSURE_SUCCESS(rv
, rv
);
749 NS_ENSURE_SUCCESS(rv
, rv
);
751 // That was async, so make sure to wait for all the events on the test thread
752 // to be processed before we return. This is easy to do with an empty sync
754 nsCOMPtr
<nsIRunnable
> flusher
= new nsRunnable();
755 NS_ENSURE_TRUE(flusher
, NS_ERROR_OUT_OF_MEMORY
);
757 LOG(("Flushing events on test thread"));
759 rv
= gTestThread
->Dispatch(flusher
, NS_DISPATCH_SYNC
);
760 NS_ENSURE_SUCCESS(rv
, rv
);
762 LOG(("Flushing events completed"));
767 int main(int argc
, char** argv
)
769 ScopedXPCOM
xpcom(TEST_NAME
);
770 NS_ENSURE_FALSE(xpcom
.failed(), 1);
772 nsCOMPtr
<nsIThread
> mainThread(do_GetMainThread());
773 NS_ENSURE_TRUE(mainThread
, 1);
775 LOG(("Got main thread"));
776 gMainThread
= mainThread
;
778 nsAutoTestThread
testThread(&gTestThread
);
779 NS_ENSURE_TRUE(testThread
, 1);
781 static TestFuncPtr testsToRun
[] = {
783 // TestNonThreadsafeProxy, /* Not currently supported! */
785 TestReleaseOfRealObjects
,
786 TestCurrentThreadProxy
,
789 static PRUint32 testCount
= sizeof(testsToRun
) / sizeof(testsToRun
[0]);
791 for (PRUint32 i
= 0; i
< testCount
; i
++) {
792 nsresult rv
= testsToRun
[i
]();
793 NS_ENSURE_SUCCESS(rv
, 1);
796 LOG(("--- Finished all tests ---"));