diff --git a/dom/plugins/ChildAsyncCall.cpp b/dom/plugins/ChildAsyncCall.cpp index 574ccdd7e94..2ed5438a637 100644 --- a/dom/plugins/ChildAsyncCall.cpp +++ b/dom/plugins/ChildAsyncCall.cpp @@ -64,9 +64,11 @@ void ChildAsyncCall::Run() { if (mFunc) { + MutexAutoLock lock(mInstance->mAsyncCallMutex); mInstance->mPendingAsyncCalls.RemoveElement(this); - mFunc(mData); } + if (mFunc) + mFunc(mData); } } // namespace plugins diff --git a/dom/plugins/PluginInstanceChild.cpp b/dom/plugins/PluginInstanceChild.cpp index 2976c6e6a74..daedbb86236 100644 --- a/dom/plugins/PluginInstanceChild.cpp +++ b/dom/plugins/PluginInstanceChild.cpp @@ -42,6 +42,7 @@ #include "BrowserStreamChild.h" #include "PluginStreamChild.h" #include "StreamNotifyChild.h" +#include "PluginThreadChild.h" #include "mozilla/ipc/SyncChannel.h" @@ -97,6 +98,7 @@ PluginInstanceChild::PluginInstanceChild(const NPPluginFuncs* aPluginIface, , mCachedWinlessPluginHWND(0) , mWinlessPopupSurrogateHWND(0) #endif // OS_WIN + , mAsyncCallMutex("PluginInstanceChild::mAsyncCallMutex") { memset(&mWindow, 0, sizeof(mWindow)); mData.ndata = (void*) this; @@ -1724,6 +1726,18 @@ PluginInstanceChild::UnscheduleTimer(uint32_t id) mTimers.RemoveElement(id, ChildTimer::IDComparator()); } +void +PluginInstanceChild::AsyncCall(PluginThreadCallback aFunc, void* aUserData) +{ + ChildAsyncCall* task = new ChildAsyncCall(this, aFunc, aUserData); + + { + MutexAutoLock lock(mAsyncCallMutex); + mPendingAsyncCalls.AppendElement(task); + } + PluginThreadChild::current()->message_loop()->PostTask(FROM_HERE, task); +} + static PLDHashOperator InvalidateObject(DeletingObjectEntry* e, void* userArg) { @@ -1776,9 +1790,12 @@ PluginInstanceChild::AnswerNPP_Destroy(NPError* aResult) for (PRUint32 i = 0; i < streams.Length(); ++i) static_cast(streams[i])->FinishDelivery(); - for (PRUint32 i = 0; i < mPendingAsyncCalls.Length(); ++i) - mPendingAsyncCalls[i]->Cancel(); - mPendingAsyncCalls.TruncateLength(0); + { + MutexAutoLock lock(mAsyncCallMutex); + for (PRUint32 i = 0; i < mPendingAsyncCalls.Length(); ++i) + mPendingAsyncCalls[i]->Cancel(); + mPendingAsyncCalls.TruncateLength(0); + } mTimers.Clear(); diff --git a/dom/plugins/PluginInstanceChild.h b/dom/plugins/PluginInstanceChild.h index ce66117a97e..ad4ffeebfe4 100644 --- a/dom/plugins/PluginInstanceChild.h +++ b/dom/plugins/PluginInstanceChild.h @@ -194,6 +194,8 @@ public: uint32_t ScheduleTimer(uint32_t interval, bool repeat, TimerFunc func); void UnscheduleTimer(uint32_t id); + void AsyncCall(PluginThreadCallback aFunc, void* aUserData); + private: friend class PluginModuleChild; @@ -282,6 +284,8 @@ private: #endif friend class ChildAsyncCall; + + Mutex mAsyncCallMutex; nsTArray mPendingAsyncCalls; nsTArray > mTimers; diff --git a/dom/plugins/PluginModuleChild.cpp b/dom/plugins/PluginModuleChild.cpp index caf9f355cc6..eb146cd2dcf 100644 --- a/dom/plugins/PluginModuleChild.cpp +++ b/dom/plugins/PluginModuleChild.cpp @@ -1324,9 +1324,7 @@ _pluginthreadasynccall(NPP aNPP, if (!aFunc) return; - PluginThreadChild::current()->message_loop() - ->PostTask(FROM_HERE, new ChildAsyncCall(InstCast(aNPP), aFunc, - aUserData)); + InstCast(aNPP)->AsyncCall(aFunc, aUserData); } NPError NP_CALLBACK