Bug 1156800: Post a task to send async NPP_New result from child to parent; r=jimm a=lhenry
authorAaron Klotz <aklotz@mozilla.com>
Mon, 27 Apr 2015 16:07:28 -0600
changeset 265810 5193c1c752ed82d33a14f57d5b11b7a5c80058ff
parent 265809 c15aa6ab2bf4ce76428d0ac3f657feec250d9f65
child 265811 9b759b93773c882247a943dc3ce3dab6bfc18690
push id4718
push userraliiev@mozilla.com
push dateMon, 11 May 2015 18:39:53 +0000
treeherdermozilla-beta@c20c4ef55f08 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjimm, lhenry
bugs1156800
milestone39.0a2
Bug 1156800: Post a task to send async NPP_New result from child to parent; r=jimm a=lhenry
dom/plugins/ipc/PluginInstanceChild.cpp
dom/plugins/ipc/PluginInstanceChild.h
dom/plugins/ipc/PluginModuleChild.cpp
--- a/dom/plugins/ipc/PluginInstanceChild.cpp
+++ b/dom/plugins/ipc/PluginInstanceChild.cpp
@@ -2360,21 +2360,17 @@ bool
 PluginInstanceChild::RecvAsyncNPP_NewStream(PBrowserStreamChild* actor,
                                             const nsCString& mimeType,
                                             const bool& seekable)
 {
     // Reusing ChildAsyncCall so that the task is cancelled properly on Destroy
     BrowserStreamChild* child = static_cast<BrowserStreamChild*>(actor);
     NewStreamAsyncCall* task = new NewStreamAsyncCall(this, child, mimeType,
                                                       seekable);
-    {
-        MutexAutoLock lock(mAsyncCallMutex);
-        mPendingAsyncCalls.AppendElement(task);
-    }
-    MessageLoop::current()->PostTask(FROM_HERE, task);
+    PostChildAsyncCall(task);
     return true;
 }
 
 PBrowserStreamChild*
 PluginInstanceChild::AllocPBrowserStreamChild(const nsCString& url,
                                               const uint32_t& length,
                                               const uint32_t& lastmodified,
                                               PStreamNotifyChild* notifyData,
@@ -3642,22 +3638,27 @@ PluginInstanceChild::UnscheduleTimer(uin
 
     mTimers.RemoveElement(id, ChildTimer::IDComparator());
 }
 
 void
 PluginInstanceChild::AsyncCall(PluginThreadCallback aFunc, void* aUserData)
 {
     ChildAsyncCall* task = new ChildAsyncCall(this, aFunc, aUserData);
-
+    PostChildAsyncCall(task);
+}
+
+void
+PluginInstanceChild::PostChildAsyncCall(ChildAsyncCall* aTask)
+{
     {
         MutexAutoLock lock(mAsyncCallMutex);
-        mPendingAsyncCalls.AppendElement(task);
+        mPendingAsyncCalls.AppendElement(aTask);
     }
-    ProcessChild::message_loop()->PostTask(FROM_HERE, task);
+    ProcessChild::message_loop()->PostTask(FROM_HERE, aTask);
 }
 
 static PLDHashOperator
 InvalidateObject(DeletingObjectEntry* e, void* userArg)
 {
     NPObject* o = e->GetKey();
     if (!e->mDeleted && o->_class && o->_class->invalidate)
         o->_class->invalidate(o);
--- a/dom/plugins/ipc/PluginInstanceChild.h
+++ b/dom/plugins/ipc/PluginInstanceChild.h
@@ -245,16 +245,18 @@ public:
 #ifdef MOZ_WIDGET_COCOA
     void Invalidate();
 #endif // definied(MOZ_WIDGET_COCOA)
 
     uint32_t ScheduleTimer(uint32_t interval, bool repeat, TimerFunc func);
     void UnscheduleTimer(uint32_t id);
 
     void AsyncCall(PluginThreadCallback aFunc, void* aUserData);
+    // This function is a more general version of AsyncCall
+    void PostChildAsyncCall(ChildAsyncCall* aTask);
 
     int GetQuirks();
 
     void NPN_URLRedirectResponse(void* notifyData, NPBool allow);
 
     void DoAsyncRedraw();
 private:
     friend class PluginModuleChild;
--- a/dom/plugins/ipc/PluginModuleChild.cpp
+++ b/dom/plugins/ipc/PluginModuleChild.cpp
@@ -2181,25 +2181,46 @@ PluginModuleChild::AnswerSyncNPP_New(PPl
     PLUGIN_LOG_DEBUG_METHOD;
     PluginInstanceChild* childInstance =
         reinterpret_cast<PluginInstanceChild*>(aActor);
     AssertPluginThread();
     *rv = childInstance->DoNPP_New();
     return true;
 }
 
+class AsyncNewResultSender : public ChildAsyncCall
+{
+public:
+    AsyncNewResultSender(PluginInstanceChild* aInstance, NPError aResult)
+        : ChildAsyncCall(aInstance, nullptr, nullptr)
+        , mResult(aResult)
+    {
+    }
+
+    void Run() override
+    {
+        RemoveFromAsyncList();
+        DebugOnly<bool> sendOk = mInstance->SendAsyncNPP_NewResult(mResult);
+        MOZ_ASSERT(sendOk);
+    }
+
+private:
+    NPError  mResult;
+};
+
 bool
 PluginModuleChild::RecvAsyncNPP_New(PPluginInstanceChild* aActor)
 {
     PLUGIN_LOG_DEBUG_METHOD;
     PluginInstanceChild* childInstance =
         reinterpret_cast<PluginInstanceChild*>(aActor);
     AssertPluginThread();
     NPError rv = childInstance->DoNPP_New();
-    childInstance->SendAsyncNPP_NewResult(rv);
+    AsyncNewResultSender* task = new AsyncNewResultSender(childInstance, rv);
+    childInstance->PostChildAsyncCall(task);
     return true;
 }
 
 bool
 PluginModuleChild::DeallocPPluginInstanceChild(PPluginInstanceChild* aActor)
 {
     PLUGIN_LOG_DEBUG_METHOD;
     AssertPluginThread();