Bug 1315260 - Suspend idle callbacks. r?bkelly draft
authorAndreas Farre <farre@mozilla.com>
Wed, 09 Nov 2016 15:51:31 +0100
changeset 439813 14ea7f5420f130cbd9a6e830152ccd6af1f5678a
parent 439808 955f175d503b2dde4a617f029c2d97e89e160c97
child 537265 6d277886b6ed7fa9da4d59e9647e258c87b82a84
push id36107
push userbmo:afarre@mozilla.com
push dateWed, 16 Nov 2016 17:43:52 +0000
reviewersbkelly
bugs1315260
milestone52.0a1
Bug 1315260 - Suspend idle callbacks. r?bkelly MozReview-Commit-ID: HXlkNGIJXuw
dom/base/IdleRequest.cpp
dom/base/IdleRequest.h
dom/base/nsGlobalWindow.cpp
dom/base/nsGlobalWindow.h
--- a/dom/base/IdleRequest.cpp
+++ b/dom/base/IdleRequest.cpp
@@ -84,17 +84,17 @@ IdleRequest::Dispatch()
   NS_IdleDispatchToCurrentThread(kungFuDeathGrip.forget());
   mRunning = true;
 }
 
 nsresult
 IdleRequest::Run()
 {
   MOZ_ASSERT(NS_IsMainThread());
-  if (mCallback) {
+  if (mRunning && mCallback) {
     RunIdleRequestCallback(false);
   }
 
   return NS_OK;
 }
 
 nsresult
 IdleRequest::Cancel()
--- a/dom/base/IdleRequest.h
+++ b/dom/base/IdleRequest.h
@@ -45,16 +45,18 @@ public:
   virtual void SetDeadline(mozilla::TimeStamp aDeadline) override;
 
   uint32_t Handle() const
   {
     return mHandle;
   }
 
   void Dispatch();
+  void Suspend() { mRunning = false; }
+
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(IdleRequest, nsITimeoutHandler)
 
 private:
   ~IdleRequest();
 
   // filename, line number and JS language version string of the
   // caller of setTimeout()
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -547,16 +547,24 @@ DialogValueHolder::Get(JSContext* aCx, J
     aError = nsContentUtils::XPConnect()->VariantToJS(aCx, aScope,
                                                       mValue, aResult);
   } else {
     aResult.setUndefined();
   }
 }
 
 void
+nsGlobalWindow::SuspendIdleCallbacks()
+{
+  if (RefPtr<IdleRequest> request = mIdleRequestCallbacks.getFirst()) {
+    request->Suspend();
+  }
+}
+
+void
 nsGlobalWindow::DispatchIdleRequest()
 {
   if (RefPtr<IdleRequest> request = mIdleRequestCallbacks.getFirst()) {
     request->Dispatch();
   }
 }
 
 void
@@ -11868,16 +11876,18 @@ nsGlobalWindow::Suspend()
     }
   }
 
   // Suspend all of the AudioContexts for this window
   for (uint32_t i = 0; i < mAudioContexts.Length(); ++i) {
     ErrorResult dummy;
     RefPtr<Promise> d = mAudioContexts[i]->Suspend(dummy);
   }
+
+  SuspendIdleCallbacks();
 }
 
 void
 nsGlobalWindow::Resume()
 {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(IsInnerWindow());
 
@@ -11897,16 +11907,18 @@ nsGlobalWindow::Resume()
   nsCOMPtr<nsIDeviceSensors> ac = do_GetService(NS_DEVICE_SENSORS_CONTRACTID);
   if (ac) {
     for (uint32_t i = 0; i < mEnabledSensors.Length(); i++)
       ac->AddWindowListener(mEnabledSensors[i], this);
   }
   EnableGamepadUpdates();
   EnableVRUpdates();
 
+  DispatchNextIdleRequest();
+
   // Resume all of the AudioContexts for this window
   for (uint32_t i = 0; i < mAudioContexts.Length(); ++i) {
     ErrorResult dummy;
     RefPtr<Promise> d = mAudioContexts[i]->Resume(dummy);
   }
 
   TimeStamp now = TimeStamp::Now();
   DebugOnly<bool> _seenDummyTimeout = false;
--- a/dom/base/nsGlobalWindow.h
+++ b/dom/base/nsGlobalWindow.h
@@ -1861,16 +1861,18 @@ protected:
 
   // the method that was used to focus mFocusedNode
   uint32_t mFocusMethod;
 
   uint32_t mSerial;
 
   void DisableIdleCallbackRequests();
 
+  void SuspendIdleCallbacks();
+  void ResumeIdleCallbacks();
 
   void DispatchNextIdleRequest();
   void DispatchIdleRequest();
 
   typedef mozilla::LinkedList<mozilla::dom::IdleRequest> IdleRequests;
   static void InsertIdleCallbackIntoList(mozilla::dom::IdleRequest* aRequest,
                                          IdleRequests& aList);