mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1099410 - [e10s] Fix re-entrant plugin loading (r=bsmedberg)
This commit is contained in:
parent
94a3194d6b
commit
c822973e54
@ -97,29 +97,82 @@ mozilla::plugins::SetupBridge(uint32_t aPluginId, dom::ContentParent* aContentPa
|
|||||||
return PPluginModule::Bridge(aContentParent, chromeParent);
|
return PPluginModule::Bridge(aContentParent, chromeParent);
|
||||||
}
|
}
|
||||||
|
|
||||||
PluginModuleContentParent* PluginModuleContentParent::sSavedModuleParent;
|
// A linked list used to fetch newly created PluginModuleContentParent instances
|
||||||
|
// for LoadModule. Each pending LoadModule call owns an element in this list.
|
||||||
|
// The element's mModule field is filled in when the new
|
||||||
|
// PluginModuleContentParent arrives from chrome.
|
||||||
|
struct MOZ_STACK_CLASS SavedPluginModule
|
||||||
|
{
|
||||||
|
SavedPluginModule() : mModule(nullptr), mNext(sSavedModuleStack)
|
||||||
|
{
|
||||||
|
sSavedModuleStack = this;
|
||||||
|
}
|
||||||
|
~SavedPluginModule()
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(sSavedModuleStack == this);
|
||||||
|
sSavedModuleStack = mNext;
|
||||||
|
}
|
||||||
|
|
||||||
|
PluginModuleContentParent* GetModule() { return mModule; }
|
||||||
|
|
||||||
|
// LoadModule can be on the stack multiple times since the intr message it
|
||||||
|
// sends will dispatch arbitrary incoming messages from the chrome process,
|
||||||
|
// which can include new HTTP data. This makes it somewhat tricky to match
|
||||||
|
// up the object created in PluginModuleContentParent::Create with the
|
||||||
|
// LoadModule call that asked for it.
|
||||||
|
//
|
||||||
|
// Each invocation of LoadModule pushes a new SavedPluginModule object on
|
||||||
|
// the sSavedModuleStack stack, with the most recent invocation at the
|
||||||
|
// front. LoadModule messages are always processed by the chrome process in
|
||||||
|
// order, and PluginModuleContentParent allocation messages will also be
|
||||||
|
// received in order. Therefore, we need to match up the first received
|
||||||
|
// PluginModuleContentParent creation message with the first sent LoadModule
|
||||||
|
// call. This call will be the last one in the list that doesn't already
|
||||||
|
// have a module attached to it.
|
||||||
|
static void SaveModule(PluginModuleContentParent* module)
|
||||||
|
{
|
||||||
|
SavedPluginModule* saved = sSavedModuleStack;
|
||||||
|
SavedPluginModule* prev = nullptr;
|
||||||
|
while (saved && !saved->mModule) {
|
||||||
|
prev = saved;
|
||||||
|
saved = saved->mNext;
|
||||||
|
}
|
||||||
|
MOZ_ASSERT(prev);
|
||||||
|
MOZ_ASSERT(!prev->mModule);
|
||||||
|
prev->mModule = module;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
PluginModuleContentParent* mModule;
|
||||||
|
SavedPluginModule* mNext;
|
||||||
|
|
||||||
|
static SavedPluginModule* sSavedModuleStack;
|
||||||
|
};
|
||||||
|
|
||||||
|
SavedPluginModule* SavedPluginModule::sSavedModuleStack;
|
||||||
|
|
||||||
/* static */ PluginLibrary*
|
/* static */ PluginLibrary*
|
||||||
PluginModuleContentParent::LoadModule(uint32_t aPluginId)
|
PluginModuleContentParent::LoadModule(uint32_t aPluginId)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(!sSavedModuleParent);
|
SavedPluginModule saved;
|
||||||
|
|
||||||
MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Content);
|
MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Content);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We send a LoadPlugin message to the chrome process using an intr
|
* We send a LoadPlugin message to the chrome process using an intr
|
||||||
* message. Before it sends its response, it sends a message to create
|
* message. Before it sends its response, it sends a message to create a
|
||||||
* PluginModuleParent instance. That message is handled by
|
* PluginModuleContentParent instance. That message is handled by
|
||||||
* PluginModuleContentParent::Create, which saves the instance in
|
* PluginModuleContentParent::Create. See SavedPluginModule for details
|
||||||
* sSavedModuleParent. We fetch it from there after LoadPlugin finishes.
|
* about how we match up the result of PluginModuleContentParent::Create
|
||||||
|
* with the LoadModule call that requested it.
|
||||||
*/
|
*/
|
||||||
dom::ContentChild* cp = dom::ContentChild::GetSingleton();
|
dom::ContentChild* cp = dom::ContentChild::GetSingleton();
|
||||||
if (!cp->CallLoadPlugin(aPluginId)) {
|
if (!cp->CallLoadPlugin(aPluginId)) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
PluginModuleContentParent* parent = sSavedModuleParent;
|
PluginModuleContentParent* parent = saved.GetModule();
|
||||||
MOZ_ASSERT(parent);
|
MOZ_ASSERT(parent);
|
||||||
sSavedModuleParent = nullptr;
|
|
||||||
|
|
||||||
return parent;
|
return parent;
|
||||||
}
|
}
|
||||||
@ -135,8 +188,7 @@ PluginModuleContentParent::Create(mozilla::ipc::Transport* aTransport,
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
MOZ_ASSERT(!sSavedModuleParent);
|
SavedPluginModule::SaveModule(parent);
|
||||||
sSavedModuleParent = parent;
|
|
||||||
|
|
||||||
DebugOnly<bool> ok = parent->Open(aTransport, handle, XRE_GetIOMessageLoop(),
|
DebugOnly<bool> ok = parent->Open(aTransport, handle, XRE_GetIOMessageLoop(),
|
||||||
mozilla::ipc::ParentSide);
|
mozilla::ipc::ParentSide);
|
||||||
|
@ -274,8 +274,6 @@ class PluginModuleContentParent : public PluginModuleParent
|
|||||||
#ifdef MOZ_CRASHREPORTER_INJECTOR
|
#ifdef MOZ_CRASHREPORTER_INJECTOR
|
||||||
void OnCrash(DWORD processID) MOZ_OVERRIDE {}
|
void OnCrash(DWORD processID) MOZ_OVERRIDE {}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static PluginModuleContentParent* sSavedModuleParent;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class PluginModuleChromeParent
|
class PluginModuleChromeParent
|
||||||
|
Loading…
Reference in New Issue
Block a user