Bug 820905 - backout ea1643fd4285 a=bajaj
authorJames Willcox <jwillcox@mozilla.com>
Thu, 13 Dec 2012 14:23:07 -0500
changeset 117520 84bba6bf11bb57dc01ce968cf44fea44c35a4ec0
parent 117517 baf41da2066b0b7fa3e0cb1044cfa68fc8d10a37
child 117521 865b57171950cb6c047c8f39465ec8c338a82436
child 117522 0fbab071e3816ecab078eb1b528d0f11aedfaded
push id1934
push userjwillcox@mozilla.com
push dateThu, 13 Dec 2012 19:35:43 +0000
treeherdermozilla-beta@84bba6bf11bb [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbajaj
bugs820905
milestone18.0
Bug 820905 - backout ea1643fd4285 a=bajaj
dom/plugins/base/nsNPAPIPluginInstance.cpp
dom/plugins/base/nsNPAPIPluginInstance.h
--- a/dom/plugins/base/nsNPAPIPluginInstance.cpp
+++ b/dom/plugins/base/nsNPAPIPluginInstance.cpp
@@ -1384,24 +1384,50 @@ nsNPAPIPluginInstance::PrivateModeStateC
   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;
 
+  // Some plugins (Flash on Android) calls unscheduletimer
+  // from this callback.
+  t->inCallback = true;
   (*(t->callback))(npp, id);
+  t->inCallback = false;
 
   // Make sure we still have an instance and the timer is still alive
   // 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
@@ -1428,16 +1454,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->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;
 
@@ -1465,16 +1492,22 @@ void
 nsNPAPIPluginInstance::UnscheduleTimer(uint32_t timerID)
 {
   // 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);
+    return;
+  }
+
   // cancel the timer
   t->timer->Cancel();
 
   // remove timer struct from array
   mTimers.RemoveElementAt(index);
 
   // delete timer
   delete t;
--- a/dom/plugins/base/nsNPAPIPluginInstance.h
+++ b/dom/plugins/base/nsNPAPIPluginInstance.h
@@ -52,16 +52,17 @@ const NPDrawingModel kDefaultDrawingMode
 
 class nsNPAPITimer
 {
 public:
   NPP npp;
   uint32_t id;
   nsCOMPtr<nsITimer> timer;
   void (*callback)(NPP npp, uint32_t timerID);
+  bool inCallback;
 };
 
 class nsNPAPIPluginInstance : public nsISupports
 {
 private:
   typedef mozilla::PluginLibrary PluginLibrary;
 
 public: