Bug 1348738 - (Part 2) Make nsRepeatService use InitWithFuncCallback instead of InitWithCallback. r?dholbert draft
authorKuoE0 <kuoe0.tw@gmail.com>
Wed, 29 Mar 2017 15:54:49 +0800
changeset 556267 24647ced947fd8b065c072c198cbc7e36b8c8d78
parent 555983 564ded2cb66cccbcb08c9fe95d7438d42b3b6431
child 556268 a88938e89ced64957facc39c9c7ceaa6716b1ef9
push id52481
push userbmo:kuoe0@mozilla.com
push dateWed, 05 Apr 2017 14:40:19 +0000
reviewersdholbert
bugs1348738
milestone55.0a1
Bug 1348738 - (Part 2) Make nsRepeatService use InitWithFuncCallback instead of InitWithCallback. r?dholbert This patch makes nsRepeatService stop inheriting from nsITimerCallback. We needed that inheritance for InitWithCallback, but we do not need it for InitWithFuncCallback. This patch also makes nsRepeatService singly-owned instead of being refcounted, since we're left with only a single owning pointer. MozReview-Commit-ID: Fl8beVC8kGH
layout/xul/nsRepeatService.cpp
layout/xul/nsRepeatService.h
--- a/layout/xul/nsRepeatService.cpp
+++ b/layout/xul/nsRepeatService.cpp
@@ -6,21 +6,22 @@
 //
 // Eric Vaughan
 // Netscape Communications
 //
 // See documentation in associated header file
 //
 
 #include "nsRepeatService.h"
+#include "mozilla/StaticPtr.h"
 #include "nsIServiceManager.h"
 
 using namespace mozilla;
 
-static StaticRefPtr<nsRepeatService> gRepeatService;
+static StaticAutoPtr<nsRepeatService> gRepeatService;
 
 nsRepeatService::nsRepeatService()
 : mCallback(nullptr), mCallbackData(nullptr)
 {
 }
 
 nsRepeatService::~nsRepeatService()
 {
@@ -66,28 +67,32 @@ void nsRepeatService::Stop(Callback aCal
   if (mRepeatTimer) {
      mRepeatTimer->Cancel();
      mRepeatTimer = nullptr;
   }
   mCallback = nullptr;
   mCallbackData = nullptr;
 }
 
-NS_IMETHODIMP nsRepeatService::Notify(nsITimer *timer)
-{
-  // do callback
-  if (mCallback)
-    mCallback(mCallbackData);
-
-  // start timer again.
-  InitTimerCallback(REPEAT_DELAY);
-  return NS_OK;
-}
-
 void
 nsRepeatService::InitTimerCallback(uint32_t aInitialDelay)
 {
-  if (mRepeatTimer) {
-    mRepeatTimer->InitWithCallback(this, aInitialDelay, nsITimer::TYPE_ONE_SHOT);
+  if (!mRepeatTimer) {
+    return;
   }
-}
 
-NS_IMPL_ISUPPORTS(nsRepeatService, nsITimerCallback)
+  mRepeatTimer->InitWithFuncCallback([](nsITimer* aTimer, void* aClosure) {
+    // Use gRepeatService instead of nsRepeatService::GetInstance() (because
+    // we don't want nsRepeatService::GetInstance() to re-create a new instance
+    // for us, if we happen to get invoked after nsRepeatService::Shutdown() has
+    // nulled out gRepeatService).
+    nsRepeatService* rs = gRepeatService;
+    if (!rs) {
+      return;
+    }
+
+    if (rs->mCallback) {
+      rs->mCallback(rs->mCallbackData);
+    }
+
+    rs->InitTimerCallback(REPEAT_DELAY);
+  }, nullptr, aInitialDelay, nsITimer::TYPE_ONE_SHOT);
+}
--- a/layout/xul/nsRepeatService.h
+++ b/layout/xul/nsRepeatService.h
@@ -17,42 +17,38 @@
 #ifdef XP_MACOSX
 #define REPEAT_DELAY        25
 #else
 #define REPEAT_DELAY        50
 #endif
 
 class nsITimer;
 
-class nsRepeatService final : public nsITimerCallback
+class nsRepeatService final
 {
 public:
+  typedef void (* Callback)(void* aData);
 
-  typedef void (* Callback)(void* aData);
-    
-  NS_DECL_NSITIMERCALLBACK
+  ~nsRepeatService();
 
   // Start dispatching timer events to the callback. There is no memory
   // management of aData here; it is the caller's responsibility to call
   // Stop() before aData's memory is released.
   void Start(Callback aCallback, void* aData,
              uint32_t aInitialDelay = INITAL_REPEAT_DELAY);
   // Stop dispatching timer events to the callback. If the repeat service
   // is not currently configured with the given callback and data, this
   // is just ignored.
   void Stop(Callback aCallback, void* aData);
 
   static nsRepeatService* GetInstance();
   static void Shutdown();
 
-  NS_DECL_ISUPPORTS
-
 protected:
   nsRepeatService();
-  virtual ~nsRepeatService();
 
 private:
   // helper function to initialize callback function to mRepeatTimer
   void InitTimerCallback(uint32_t aInitialDelay);
 
   Callback           mCallback;
   void*              mCallbackData;
   nsCOMPtr<nsITimer> mRepeatTimer;