Bug 1103036 - Use nsITimer for ContentParent shutdown timer (r=bent)
authorBill McCloskey <wmccloskey@mozilla.com>
Tue, 06 Jan 2015 21:42:23 -0800
changeset 248962 ebb500eb92d8cbadf2bff07540b6cca70204c33d
parent 248961 5c4c5685381fc6511ef71d5ecf0c346833e9dbfd
child 248963 66083ac0f3c069c5b0bb4908b50cffb15d7d2eb6
push id4489
push userraliiev@mozilla.com
push dateMon, 23 Feb 2015 15:17:55 +0000
treeherdermozilla-beta@fd7c3dc24146 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbent
bugs1103036
milestone37.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 1103036 - Use nsITimer for ContentParent shutdown timer (r=bent)
dom/ipc/ContentParent.cpp
dom/ipc/ContentParent.h
--- a/dom/ipc/ContentParent.cpp
+++ b/dom/ipc/ContentParent.cpp
@@ -111,16 +111,17 @@
 #include "nsIMutable.h"
 #include "nsIObserverService.h"
 #include "nsIPresShell.h"
 #include "nsIScriptError.h"
 #include "nsISiteSecurityService.h"
 #include "nsISpellChecker.h"
 #include "nsIStyleSheet.h"
 #include "nsISupportsPrimitives.h"
+#include "nsITimer.h"
 #include "nsIURIFixup.h"
 #include "nsIWindowWatcher.h"
 #include "nsIXULRuntime.h"
 #include "nsMemoryInfoDumper.h"
 #include "nsMemoryReporterManager.h"
 #include "nsServiceManagerUtils.h"
 #include "nsStyleSheetService.h"
 #include "nsThreadUtils.h"
@@ -1763,19 +1764,19 @@ struct DelayedDeleteContentParentTask : 
     nsRefPtr<ContentParent> mObj;
 };
 
 }
 
 void
 ContentParent::ActorDestroy(ActorDestroyReason why)
 {
-    if (mForceKillTask) {
-        mForceKillTask->Cancel();
-        mForceKillTask = nullptr;
+    if (mForceKillTimer) {
+        mForceKillTimer->Cancel();
+        mForceKillTimer = nullptr;
     }
 
     // Signal shutdown completion regardless of error state,
     // so we can finish waiting in the xpcom-shutdown observer.
     mIPCOpen = false;
 
     if (why == NormalShutdown && !mCalledClose) {
         // If we shut down normally but haven't called Close, assume somebody
@@ -1917,24 +1918,26 @@ ContentParent::NotifyTabDestroying(PBrow
     if (mNumDestroyingTabs != numLiveTabs) {
         return;
     }
 
     // We're dying now, so prevent this content process from being
     // recycled during its shutdown procedure.
     MarkAsDead();
 
-    MOZ_ASSERT(!mForceKillTask);
+    MOZ_ASSERT(!mForceKillTimer);
     int32_t timeoutSecs =
         Preferences::GetInt("dom.ipc.tabs.shutdownTimeoutSecs", 5);
     if (timeoutSecs > 0) {
-        MessageLoop::current()->PostDelayedTask(
-            FROM_HERE,
-            mForceKillTask = NewRunnableMethod(this, &ContentParent::KillHard),
-            timeoutSecs * 1000);
+        mForceKillTimer = do_CreateInstance("@mozilla.org/timer;1");
+        MOZ_ASSERT(mForceKillTimer);
+        mForceKillTimer->InitWithFuncCallback(ContentParent::ForceKillTimerCallback,
+                                              this,
+                                              timeoutSecs * 1000,
+                                              nsITimer::TYPE_ONE_SHOT);
     }
 }
 
 void
 ContentParent::NotifyTabDestroyed(PBrowserParent* aTab,
                                   bool aNotifiedDestroying)
 {
     if (aNotifiedDestroying) {
@@ -1984,17 +1987,16 @@ ContentParent::GetTestShellSingleton()
 }
 
 void
 ContentParent::InitializeMembers()
 {
     mSubprocess = nullptr;
     mChildID = gContentChildID++;
     mGeolocationWatchID = -1;
-    mForceKillTask = nullptr;
     mNumDestroyingTabs = 0;
     mIsAlive = true;
     mSendPermissionUpdates = false;
     mSendDataStoreInfos = false;
     mCalledClose = false;
     mCalledCloseWithError = false;
     mCalledKillHard = false;
     mCreatedPairedMinidumps = false;
@@ -2162,18 +2164,18 @@ ContentParent::ContentParent(ContentPare
                  false  /* Send registered chrome */);
 
     ContentProcessManager::GetSingleton()->AddContentProcess(this);
 }
 #endif  // MOZ_NUWA_PROCESS
 
 ContentParent::~ContentParent()
 {
-    if (mForceKillTask) {
-        mForceKillTask->Cancel();
+    if (mForceKillTimer) {
+        mForceKillTimer->Cancel();
     }
 
     if (OtherProcess())
         base::CloseProcessHandle(OtherProcess());
 
     NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
 
     // We should be removed from all these lists in ActorDestroy.
@@ -3154,27 +3156,34 @@ ContentParent::AllocPRemoteSpellcheckEng
 
 bool
 ContentParent::DeallocPRemoteSpellcheckEngineParent(PRemoteSpellcheckEngineParent *parent)
 {
     delete parent;
     return true;
 }
 
+/* static */ void
+ContentParent::ForceKillTimerCallback(nsITimer* aTimer, void* aClosure)
+{
+    auto self = static_cast<ContentParent*>(aClosure);
+    self->KillHard();
+}
+
 void
 ContentParent::KillHard()
 {
     // On Windows, calling KillHard multiple times causes problems - the
     // process handle becomes invalid on the first call, causing a second call
     // to crash our process - more details in bug 890840.
     if (mCalledKillHard) {
         return;
     }
     mCalledKillHard = true;
-    mForceKillTask = nullptr;
+    mForceKillTimer = nullptr;
 
 #if defined(MOZ_CRASHREPORTER) && !defined(MOZ_B2G)
     if (ManagedPCrashReporterParent().Length() > 0) {
         CrashReporterParent* crashReporter =
             static_cast<CrashReporterParent*>(ManagedPCrashReporterParent()[0]);
 
         // We're about to kill the child process associated with this
         // ContentParent. Something has gone wrong to get us here,
--- a/dom/ipc/ContentParent.h
+++ b/dom/ipc/ContentParent.h
@@ -28,16 +28,17 @@
 #define CHILD_PROCESS_SHUTDOWN_MESSAGE NS_LITERAL_STRING("child-process-shutdown")
 
 class mozIApplication;
 class nsConsoleService;
 class nsICycleCollectorLogSink;
 class nsIDOMBlob;
 class nsIDumpGCAndCCLogsCallback;
 class nsIMemoryReporter;
+class nsITimer;
 class ParentIdleListener;
 
 namespace mozilla {
 class PRemoteSpellcheckEngineParent;
 
 namespace ipc {
 class OptionalURIParams;
 class PFileDescriptorSetParent;
@@ -459,16 +460,18 @@ private:
      * is an abnormal shutdown (e.g. a crash).
      */
     void ShutDownProcess(ShutDownMethod aMethod);
 
     // Perform any steps necesssary to gracefully shtudown the message
     // manager and null out mMessageManager.
     void ShutDownMessageManager();
 
+    static void ForceKillTimerCallback(nsITimer* aTimer, void* aClosure);
+
     PCompositorParent*
     AllocPCompositorParent(mozilla::ipc::Transport* aTransport,
                            base::ProcessId aOtherProcess) MOZ_OVERRIDE;
     PImageBridgeParent*
     AllocPImageBridgeParent(mozilla::ipc::Transport* aTransport,
                             base::ProcessId aOtherProcess) MOZ_OVERRIDE;
 
     PSharedBufferManagerParent*
@@ -785,17 +788,17 @@ private:
      * expensive.
      */
     nsString mAppName;
 
     // After we initiate shutdown, we also start a timer to ensure
     // that even content processes that are 100% blocked (say from
     // SIGSTOP), are still killed eventually.  This task enforces that
     // timer.
-    CancelableTask* mForceKillTask;
+    nsCOMPtr<nsITimer> mForceKillTimer;
     // How many tabs we're waiting to finish their destruction
     // sequence.  Precisely, how many TabParents have called
     // NotifyTabDestroying() but not called NotifyTabDestroyed().
     int32_t mNumDestroyingTabs;
     // True only while this is ready to be used to host remote tabs.
     // This must not be used for new purposes after mIsAlive goes to
     // false, but some previously scheduled IPC traffic may still pass
     // through.