1 #include "TestCrashCleanup.h" 2 3 #include "base/task.h" 4 #include "mozilla/CondVar.h" 5 #include "mozilla/Mutex.h" 6 7 #include "IPDLUnitTests.h" // fail etc. 8 #include "IPDLUnitTestSubprocess.h" 9 10 using mozilla::CondVar; 11 using mozilla::Mutex; 12 using mozilla::MutexAutoLock; 13 14 namespace mozilla { 15 namespace _ipdltest { 16 17 //----------------------------------------------------------------------------- 18 // parent 19 20 namespace { 21 22 // NB: this test does its own shutdown, rather than going through 23 // QuitParent(), because it's testing degenerate edge cases 24 25 void DeleteSubprocess(Mutex* mutex, CondVar* cvar) 26 { 27 MutexAutoLock lock(*mutex); 28 29 delete gSubprocess; 30 gSubprocess = nullptr; 31 32 cvar->Notify(); 33 } 34 35 void DeleteTheWorld() 36 { 37 delete static_cast<TestCrashCleanupParent*>(gParentActor); 38 gParentActor = nullptr; 39 40 // needs to be synchronous to avoid affecting event ordering on 41 // the main thread 42 Mutex mutex("TestCrashCleanup.DeleteTheWorld.mutex"); 43 CondVar cvar(mutex, "TestCrashCleanup.DeleteTheWorld.cvar"); 44 45 MutexAutoLock lock(mutex); 46 47 XRE_GetIOMessageLoop()->PostTask( 48 NewRunnableFunction(DeleteSubprocess, &mutex, &cvar)); 49 50 cvar.Wait(); 51 } 52 53 void Done() 54 { 55 static NS_DEFINE_CID(kAppShellCID, NS_APPSHELL_CID); 56 nsCOMPtr<nsIAppShell> appShell (do_GetService(kAppShellCID)); 57 appShell->Exit(); 58 59 passed(__FILE__); 60 } 61 62 } // namespace <anon> 63 64 TestCrashCleanupParent::TestCrashCleanupParent() : mCleanedUp(false) 65 { 66 MOZ_COUNT_CTOR(TestCrashCleanupParent); 67 } 68 69 TestCrashCleanupParent::~TestCrashCleanupParent() 70 { 71 MOZ_COUNT_DTOR(TestCrashCleanupParent); 72 73 if (!mCleanedUp) 74 fail("should have been ActorDestroy()d!"); 75 } 76 77 void 78 TestCrashCleanupParent::Main() 79 { 80 // NB: has to be enqueued before IO thread's error notification 81 MessageLoop::current()->PostTask( 82 NewRunnableFunction(DeleteTheWorld)); 83 84 if (CallDIEDIEDIE()) 85 fail("expected an error!"); 86 87 Close(); 88 89 MessageLoop::current()->PostTask(NewRunnableFunction(Done)); 90 } 91 92 93 //----------------------------------------------------------------------------- 94 // child 95 96 TestCrashCleanupChild::TestCrashCleanupChild() 97 { 98 MOZ_COUNT_CTOR(TestCrashCleanupChild); 99 } 100 101 TestCrashCleanupChild::~TestCrashCleanupChild() 102 { 103 MOZ_COUNT_DTOR(TestCrashCleanupChild); 104 } 105 106 bool 107 TestCrashCleanupChild::AnswerDIEDIEDIE() 108 { 109 _exit(0); 110 NS_RUNTIMEABORT("unreached"); 111 return false; 112 } 113 114 115 } // namespace _ipdltest 116 } // namespace mozilla 117