Bug 581341 - Part 4: Always run the IPC testshell callback, regardless of execution success or failure. r=bent
authorJosh Matthews <josh@joshmatthews.net>
Wed, 29 Jun 2011 15:29:52 -0400
changeset 72732 f3aee8cc69e39797362239f0722b156e4b6b1c36
parent 72731 4b7e21df87657bb2a9c5c21522537c05a2d65913
child 72733 ec1c5047fa39892340f2e352511e228f8a7d5986
push id45
push userffxbld
push dateThu, 22 Sep 2011 17:29:26 +0000
treeherdermozilla-release@b3273da80b44 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbent
bugs581341
milestone7.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 581341 - Part 4: Always run the IPC testshell callback, regardless of execution success or failure. r=bent
dom/ipc/ContentParent.cpp
dom/ipc/ContentParent.h
ipc/testshell/TestShellParent.cpp
ipc/testshell/TestShellParent.h
toolkit/xre/nsEmbedFunctions.cpp
--- a/dom/ipc/ContentParent.cpp
+++ b/dom/ipc/ContentParent.cpp
@@ -322,16 +322,24 @@ ContentParent::CreateTestShell()
 }
 
 bool
 ContentParent::DestroyTestShell(TestShellParent* aTestShell)
 {
     return PTestShellParent::Send__delete__(aTestShell);
 }
 
+TestShellParent*
+ContentParent::GetTestShellSingleton()
+{
+    if (!ManagedPTestShellParent().Length())
+        return nsnull;
+    return static_cast<TestShellParent*>(ManagedPTestShellParent()[0]);
+}
+
 ContentParent::ContentParent()
     : mGeolocationWatchID(-1)
     , mRunToCompletionDepth(0)
     , mShouldCallUnblockChild(false)
     , mIsAlive(true)
 {
     NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
     mSubprocess = new GeckoChildProcessHost(GeckoProcessType_Content);
--- a/dom/ipc/ContentParent.h
+++ b/dom/ipc/ContentParent.h
@@ -89,16 +89,17 @@ public:
     NS_DECL_NSITHREADOBSERVER
     NS_DECL_NSIDOMGEOPOSITIONCALLBACK
     NS_DECL_NSIDEVICEMOTIONLISTENER
 
     TabParent* CreateTab(PRUint32 aChromeFlags);
 
     TestShellParent* CreateTestShell();
     bool DestroyTestShell(TestShellParent* aTestShell);
+    TestShellParent* GetTestShellSingleton();
 
     void ReportChildAlreadyBlocked();
     bool RequestRunToCompletion();
 
     bool IsAlive();
 
     void SetChildMemoryReporters(const InfallibleTArray<MemoryReport>& report);
 
--- a/ipc/testshell/TestShellParent.cpp
+++ b/ipc/testshell/TestShellParent.cpp
@@ -141,8 +141,23 @@ TestShellCommandParent::RunCallback(cons
   return JS_TRUE;
 }
 
 void
 TestShellCommandParent::ReleaseCallback()
 {
   mCallback.Release();
 }
+
+bool
+TestShellCommandParent::ExecuteCallback(const nsString& aResponse)
+{
+  return static_cast<TestShellParent*>(Manager())->CommandDone(
+      this, aResponse);
+}
+
+void
+TestShellCommandParent::ActorDestroy(ActorDestroyReason why)
+{
+  if (why == AbnormalShutdown) {
+    ExecuteCallback(EmptyString());
+  }
+}
--- a/ipc/testshell/TestShellParent.h
+++ b/ipc/testshell/TestShellParent.h
@@ -87,19 +87,22 @@ public:
   JSBool SetCallback(JSContext* aCx,
                      jsval aCallback);
 
   JSBool RunCallback(const nsString& aResponse);
 
   void ReleaseCallback();
 
 protected:
+  bool ExecuteCallback(const nsString& aResponse);
+
+  void ActorDestroy(ActorDestroyReason why);
+  
   bool Recv__delete__(const nsString& aResponse) {
-    return static_cast<TestShellParent*>(Manager())->CommandDone(
-      this, aResponse);
+    return ExecuteCallback(aResponse);
   }
 
 private:
   JSContext* mCx;
   nsAutoJSValHolder mCallback;
 };
 
 
--- a/toolkit/xre/nsEmbedFunctions.cpp
+++ b/toolkit/xre/nsEmbedFunctions.cpp
@@ -701,26 +701,28 @@ XRE_ShutdownChildProcess()
       // that case, we fire off an Exit() here.  If we were indeed
       // above MessagePump::Run(), this Exit() is just superfluous.
       appShell->Exit();
   }
 #endif // XP_MACOSX
 }
 
 namespace {
-TestShellParent* gTestShellParent = nsnull;
 TestShellParent* GetOrCreateTestShellParent()
 {
-    if (!gTestShellParent) {
-        ContentParent* parent = ContentParent::GetSingleton();
-        NS_ENSURE_TRUE(parent, nsnull);
-        gTestShellParent = parent->CreateTestShell();
-        NS_ENSURE_TRUE(gTestShellParent, nsnull);
+    ContentParent* parent = ContentParent::GetSingleton();
+    if (!parent) {
+      return nsnull;
     }
-    return gTestShellParent;
+    TestShellParent* testShell = parent->GetTestShellSingleton();
+    if (testShell) {
+      return testShell;
+    }
+    testShell = parent->CreateTestShell();
+    return testShell;
 }
 }
 
 bool
 XRE_SendTestShellCommand(JSContext* aCx,
                          JSString* aCommand,
                          void* aCallback)
 {
@@ -749,19 +751,21 @@ XRE_GetChildGlobalObject(JSContext* aCx,
 {
     TestShellParent* tsp = GetOrCreateTestShellParent();
     return tsp && tsp->GetGlobalJSObject(aCx, aGlobalP);
 }
 
 bool
 XRE_ShutdownTestShell()
 {
-  if (!gTestShellParent)
+  ContentParent* cp = ContentParent::GetSingleton(PR_FALSE);
+  TestShellParent* tsp = cp ? cp->GetTestShellSingleton() : nsnull;
+  if (!tsp)
     return true;
-  return ContentParent::GetSingleton()->DestroyTestShell(gTestShellParent);
+  return cp->DestroyTestShell(tsp);
 }
 
 #ifdef MOZ_X11
 void
 XRE_InstallX11ErrorHandler()
 {
   InstallX11ErrorHandler();
 }