1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/ipc/ipdl/test/cxx/TestCrashCleanup.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,116 @@ 1.4 +#include "TestCrashCleanup.h" 1.5 + 1.6 +#include "mozilla/CondVar.h" 1.7 +#include "mozilla/Mutex.h" 1.8 + 1.9 +#include "IPDLUnitTests.h" // fail etc. 1.10 +#include "IPDLUnitTestSubprocess.h" 1.11 + 1.12 +using mozilla::CondVar; 1.13 +using mozilla::Mutex; 1.14 +using mozilla::MutexAutoLock; 1.15 + 1.16 +namespace mozilla { 1.17 +namespace _ipdltest { 1.18 + 1.19 +//----------------------------------------------------------------------------- 1.20 +// parent 1.21 + 1.22 +namespace { 1.23 + 1.24 +// NB: this test does its own shutdown, rather than going through 1.25 +// QuitParent(), because it's testing degenerate edge cases 1.26 + 1.27 +void DeleteSubprocess(Mutex* mutex, CondVar* cvar) 1.28 +{ 1.29 + MutexAutoLock lock(*mutex); 1.30 + 1.31 + delete gSubprocess; 1.32 + gSubprocess = nullptr; 1.33 + 1.34 + cvar->Notify(); 1.35 +} 1.36 + 1.37 +void DeleteTheWorld() 1.38 +{ 1.39 + delete static_cast<TestCrashCleanupParent*>(gParentActor); 1.40 + gParentActor = nullptr; 1.41 + 1.42 + // needs to be synchronous to avoid affecting event ordering on 1.43 + // the main thread 1.44 + Mutex mutex("TestCrashCleanup.DeleteTheWorld.mutex"); 1.45 + CondVar cvar(mutex, "TestCrashCleanup.DeleteTheWorld.cvar"); 1.46 + 1.47 + MutexAutoLock lock(mutex); 1.48 + 1.49 + XRE_GetIOMessageLoop()->PostTask( 1.50 + FROM_HERE, 1.51 + NewRunnableFunction(DeleteSubprocess, &mutex, &cvar)); 1.52 + 1.53 + cvar.Wait(); 1.54 +} 1.55 + 1.56 +void Done() 1.57 +{ 1.58 + static NS_DEFINE_CID(kAppShellCID, NS_APPSHELL_CID); 1.59 + nsCOMPtr<nsIAppShell> appShell (do_GetService(kAppShellCID)); 1.60 + appShell->Exit(); 1.61 + 1.62 + passed(__FILE__); 1.63 +} 1.64 + 1.65 +} // namespace <anon> 1.66 + 1.67 +TestCrashCleanupParent::TestCrashCleanupParent() : mCleanedUp(false) 1.68 +{ 1.69 + MOZ_COUNT_CTOR(TestCrashCleanupParent); 1.70 +} 1.71 + 1.72 +TestCrashCleanupParent::~TestCrashCleanupParent() 1.73 +{ 1.74 + MOZ_COUNT_DTOR(TestCrashCleanupParent); 1.75 + 1.76 + if (!mCleanedUp) 1.77 + fail("should have been ActorDestroy()d!"); 1.78 +} 1.79 + 1.80 +void 1.81 +TestCrashCleanupParent::Main() 1.82 +{ 1.83 + // NB: has to be enqueued before IO thread's error notification 1.84 + MessageLoop::current()->PostTask( 1.85 + FROM_HERE, NewRunnableFunction(DeleteTheWorld)); 1.86 + 1.87 + if (CallDIEDIEDIE()) 1.88 + fail("expected an error!"); 1.89 + 1.90 + Close(); 1.91 + 1.92 + MessageLoop::current()->PostTask(FROM_HERE, NewRunnableFunction(Done)); 1.93 +} 1.94 + 1.95 + 1.96 +//----------------------------------------------------------------------------- 1.97 +// child 1.98 + 1.99 +TestCrashCleanupChild::TestCrashCleanupChild() 1.100 +{ 1.101 + MOZ_COUNT_CTOR(TestCrashCleanupChild); 1.102 +} 1.103 + 1.104 +TestCrashCleanupChild::~TestCrashCleanupChild() 1.105 +{ 1.106 + MOZ_COUNT_DTOR(TestCrashCleanupChild); 1.107 +} 1.108 + 1.109 +bool 1.110 +TestCrashCleanupChild::AnswerDIEDIEDIE() 1.111 +{ 1.112 + _exit(0); 1.113 + NS_RUNTIMEABORT("unreached"); 1.114 + return false; 1.115 +} 1.116 + 1.117 + 1.118 +} // namespace _ipdltest 1.119 +} // namespace mozilla