diff --git a/dom/plugins/PPluginInstance.ipdl b/dom/plugins/PPluginInstance.ipdl index 82bb1c988682..75e82d9490dd 100644 --- a/dom/plugins/PPluginInstance.ipdl +++ b/dom/plugins/PPluginInstance.ipdl @@ -80,6 +80,9 @@ child: rpc NPP_HandleEvent(NPRemoteEvent event) returns (int16_t handled); + // special case of HandleEvent to make mediating races simpler + rpc Paint(NPRemoteEvent event) + returns (int16_t handled); rpc NPP_Destroy() returns (NPError rv); diff --git a/dom/plugins/PluginInstanceChild.h b/dom/plugins/PluginInstanceChild.h index 6d4dba484b27..0cfa28eba097 100644 --- a/dom/plugins/PluginInstanceChild.h +++ b/dom/plugins/PluginInstanceChild.h @@ -87,6 +87,13 @@ protected: virtual bool AnswerNPP_HandleEvent(const NPRemoteEvent& event, int16_t* handled); + NS_OVERRIDE + virtual bool + AnswerPaint(const NPRemoteEvent& event, int16_t* handled) + { + return AnswerNPP_HandleEvent(event, handled); + } + virtual bool AnswerNPP_Destroy(NPError* result); diff --git a/dom/plugins/PluginInstanceParent.cpp b/dom/plugins/PluginInstanceParent.cpp index dc7288934537..7eeed2a6d59d 100644 --- a/dom/plugins/PluginInstanceParent.cpp +++ b/dom/plugins/PluginInstanceParent.cpp @@ -536,7 +536,7 @@ PluginInstanceParent::NPP_HandleEvent(void* event) { RECT rect; SharedSurfaceBeforePaint(rect, npremoteevent); - CallNPP_HandleEvent(npremoteevent, &handled); + CallPaint(npremoteevent, &handled); SharedSurfaceAfterPaint(npevent); return handled; } @@ -561,12 +561,6 @@ PluginInstanceParent::NPP_HandleEvent(void* event) } break; } - if (!CallNPP_HandleEvent(npremoteevent, &handled)) - return 0; - } - else { - if (!CallNPP_HandleEvent(npremoteevent, &handled)) - return 0; } #endif @@ -586,11 +580,14 @@ PluginInstanceParent::NPP_HandleEvent(void* event) # elif defined(MOZ_WIDGET_QT) XSync(QX11Info::display(), False); # endif + + if (!CallPaint(npremoteevent, &handled)) + return 0; } +#endif if (!CallNPP_HandleEvent(npremoteevent, &handled)) return 0; // no good way to handle errors here... -#endif return handled; } diff --git a/dom/plugins/PluginMessageUtils.cpp b/dom/plugins/PluginMessageUtils.cpp index 80171a35d602..a27e44d818f4 100644 --- a/dom/plugins/PluginMessageUtils.cpp +++ b/dom/plugins/PluginMessageUtils.cpp @@ -45,6 +45,8 @@ #include "PluginScriptableObjectParent.h" #include "PluginScriptableObjectChild.h" +using mozilla::ipc::RPCChannel; + namespace { class DeferNPObjectReleaseRunnable : public nsRunnable @@ -76,6 +78,16 @@ DeferNPObjectReleaseRunnable::Run() namespace mozilla { namespace plugins { +RPCChannel::RacyRPCPolicy +MediateRace(const RPCChannel::Message& parent, + const RPCChannel::Message& child) +{ + // our code relies on the frame list not changing during paints + bool isPaint = (PPluginInstance::Msg_Paint__ID == parent.type()); + + return isPaint ? RPCChannel::RRPParentWins : RPCChannel::RRPChildWins; +} + PRLogModuleInfo* gPluginLog = PR_NewLogModule("IPCPlugins"); void diff --git a/dom/plugins/PluginMessageUtils.h b/dom/plugins/PluginMessageUtils.h index e8c259935e02..75c7c73975ad 100644 --- a/dom/plugins/PluginMessageUtils.h +++ b/dom/plugins/PluginMessageUtils.h @@ -42,6 +42,8 @@ #include "IPC/IPCMessageUtils.h" #include "base/message_loop.h" +#include "mozilla/ipc/RPCChannel.h" + #include "npapi.h" #include "npruntime.h" #include "npfunctions.h" @@ -73,6 +75,10 @@ enum ScriptableObjectType Proxy }; +mozilla::ipc::RPCChannel::RacyRPCPolicy +MediateRace(const mozilla::ipc::RPCChannel::Message& parent, + const mozilla::ipc::RPCChannel::Message& child); + extern PRLogModuleInfo* gPluginLog; #if defined(_MSC_VER) diff --git a/dom/plugins/PluginModuleChild.h b/dom/plugins/PluginModuleChild.h index 92f8ac0b3dff..59234c9a4a57 100644 --- a/dom/plugins/PluginModuleChild.h +++ b/dom/plugins/PluginModuleChild.h @@ -93,6 +93,13 @@ class PluginInstanceChild; class PluginModuleChild : public PPluginModuleChild { protected: + NS_OVERRIDE + virtual mozilla::ipc::RPCChannel::RacyRPCPolicy + MediateRPCRace(const Message& parent, const Message& child) + { + return MediateRace(parent, child); + } + // Implement the PPluginModuleChild interface virtual bool AnswerNP_Initialize(NPError* rv); diff --git a/dom/plugins/PluginModuleParent.h b/dom/plugins/PluginModuleParent.h index 6f3885befdd8..00e415fd9c71 100644 --- a/dom/plugins/PluginModuleParent.h +++ b/dom/plugins/PluginModuleParent.h @@ -125,6 +125,13 @@ public: } protected: + NS_OVERRIDE + virtual mozilla::ipc::RPCChannel::RacyRPCPolicy + MediateRPCRace(const Message& parent, const Message& child) + { + return MediateRace(parent, child); + } + NS_OVERRIDE virtual bool ShouldContinueFromReplyTimeout();