Bug 800838 - Remove unnecessary delay when unscheduling plugin timers. r=blassey, a=bajaj
authorJames Willcox <jwillcox@mozilla.com>
Mon, 17 Dec 2012 10:05:49 -0500
changeset 122337 45d2b0f59abb79fead1bf0378285d7ab2bf96279
parent 122336 db37840616639873d092e0dede1070843a2dfefc
child 122338 e511f4bbab30313448a23859ee39023811a7b877
push id1997
push userakeybl@mozilla.com
push dateMon, 07 Jan 2013 21:25:26 +0000
treeherdermozilla-beta@4baf45cdcf21 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersblassey, bajaj
bugs800838
milestone19.0a2
Bug 800838 - Remove unnecessary delay when unscheduling plugin timers. r=blassey, a=bajaj
dom/plugins/base/nsNPAPIPluginInstance.cpp
dom/plugins/base/nsNPAPIPluginInstance.h
--- a/dom/plugins/base/nsNPAPIPluginInstance.cpp
+++ b/dom/plugins/base/nsNPAPIPluginInstance.cpp
@@ -1366,45 +1366,23 @@ nsNPAPIPluginInstance::PrivateModeStateC
     return NS_ERROR_FAILURE;
 
   NPPluginFuncs* pluginFunctions = mPlugin->PluginFuncs();
 
   if (!pluginFunctions->setvalue)
     return NS_ERROR_FAILURE;
 
   PluginDestructionGuard guard(this);
-    
+
   NPError error;
   NPBool value = static_cast<NPBool>(enabled);
   NS_TRY_SAFE_CALL_RETURN(error, (*pluginFunctions->setvalue)(&mNPP, NPNVprivateModeBool, &value), this);
   return (error == NPERR_NO_ERROR) ? NS_OK : NS_ERROR_FAILURE;
 }
 
-class DelayUnscheduleEvent : public nsRunnable {
-public:
-  nsRefPtr<nsNPAPIPluginInstance> mInstance;
-  uint32_t mTimerID;
-  DelayUnscheduleEvent(nsNPAPIPluginInstance* aInstance, uint32_t aTimerId)
-    : mInstance(aInstance)
-    , mTimerID(aTimerId)
-  {}
-
-  ~DelayUnscheduleEvent() {}
-
-  NS_IMETHOD Run();
-};
-
-NS_IMETHODIMP
-DelayUnscheduleEvent::Run()
-{
-  mInstance->UnscheduleTimer(mTimerID);
-  return NS_OK;
-}
-
-
 static void
 PluginTimerCallback(nsITimer *aTimer, void *aClosure)
 {
   nsNPAPITimer* t = (nsNPAPITimer*)aClosure;
   NPP npp = t->npp;
   uint32_t id = t->id;
 
   PLUGIN_LOG(PLUGIN_LOG_NOISY, ("nsNPAPIPluginInstance running plugin timer callback this=%p\n", npp->ndata));
@@ -1420,18 +1398,18 @@ PluginTimerCallback(nsITimer *aTimer, vo
   // after the callback.
   nsNPAPIPluginInstance *inst = (nsNPAPIPluginInstance*)npp->ndata;
   if (!inst || !inst->TimerWithID(id, NULL))
     return;
 
   // use UnscheduleTimer to clean up if this is a one-shot timer
   uint32_t timerType;
   t->timer->GetType(&timerType);
-  if (timerType == nsITimer::TYPE_ONE_SHOT)
-      inst->UnscheduleTimer(id);
+  if (t->needUnschedule || timerType == nsITimer::TYPE_ONE_SHOT)
+    inst->UnscheduleTimer(id);
 }
 
 nsNPAPITimer*
 nsNPAPIPluginInstance::TimerWithID(uint32_t id, uint32_t* index)
 {
   uint32_t len = mTimers.Length();
   for (uint32_t i = 0; i < len; i++) {
     if (mTimers[i]->id == id) {
@@ -1446,17 +1424,17 @@ nsNPAPIPluginInstance::TimerWithID(uint3
 uint32_t
 nsNPAPIPluginInstance::ScheduleTimer(uint32_t interval, NPBool repeat, void (*timerFunc)(NPP npp, uint32_t timerID))
 {
   if (RUNNING != mRunning)
     return 0;
 
   nsNPAPITimer *newTimer = new nsNPAPITimer();
 
-  newTimer->inCallback = false;
+  newTimer->inCallback = newTimer->needUnschedule = false;
   newTimer->npp = &mNPP;
 
   // generate ID that is unique to this instance
   uint32_t uniqueID = mTimers.Length();
   while ((uniqueID == 0) || TimerWithID(uniqueID, NULL))
     uniqueID++;
   newTimer->id = uniqueID;
 
@@ -1485,18 +1463,17 @@ nsNPAPIPluginInstance::UnscheduleTimer(u
 {
   // find the timer struct by ID
   uint32_t index;
   nsNPAPITimer* t = TimerWithID(timerID, &index);
   if (!t)
     return;
 
   if (t->inCallback) {
-    nsCOMPtr<nsIRunnable> e = new DelayUnscheduleEvent(this, timerID);
-    NS_DispatchToCurrentThread(e);
+    t->needUnschedule = true;
     return;
   }
 
   // cancel the timer
   t->timer->Cancel();
 
   // remove timer struct from array
   mTimers.RemoveElementAt(index);
--- a/dom/plugins/base/nsNPAPIPluginInstance.h
+++ b/dom/plugins/base/nsNPAPIPluginInstance.h
@@ -53,16 +53,17 @@ const NPDrawingModel kDefaultDrawingMode
 class nsNPAPITimer
 {
 public:
   NPP npp;
   uint32_t id;
   nsCOMPtr<nsITimer> timer;
   void (*callback)(NPP npp, uint32_t timerID);
   bool inCallback;
+  bool needUnschedule;
 };
 
 class nsNPAPIPluginInstance : public nsISupports
 {
 private:
   typedef mozilla::PluginLibrary PluginLibrary;
 
 public: