Bug 863792 - Handle re-entry during plugin instantiation. r=josh

This commit is contained in:
John Schoenick 2013-04-17 17:11:58 -07:00
parent a4e365d0c5
commit c886bec401

View File

@ -745,6 +745,8 @@ nsObjectLoadingContent::InstantiatePluginInstance(bool aIsLoading)
// Flush layout so that the frame is created if possible and the plugin is
// initialized with the latest information.
doc->FlushPendingNotifications(Flush_Layout);
// Flushing layout may have re-entered and loaded something underneath us
NS_ENSURE_TRUE(mInstantiating, NS_OK);
if (!thisContent->GetPrimaryFrame()) {
LOG(("OBJLC [%p]: Not instantiating plugin with no frame", this));
@ -767,9 +769,36 @@ nsObjectLoadingContent::InstantiatePluginInstance(bool aIsLoading)
appShell->SuspendNative();
}
nsRefPtr<nsPluginInstanceOwner> newOwner;
rv = pluginHost->InstantiatePluginInstance(mContentType.get(),
mURI.get(), this,
getter_AddRefs(mInstanceOwner));
getter_AddRefs(newOwner));
// XXX(johns): We don't suspend native inside stopping plugins...
if (appShell) {
appShell->ResumeNative();
}
if (!mInstantiating || NS_FAILED(rv)) {
LOG(("OBJLC [%p]: Plugin instantiation failed or re-entered, "
"killing old instance", this));
// XXX(johns): This needs to be de-duplicated with DoStopPlugin, but we
// don't want to touch the protochain or delayed stop.
// (Bug 767635)
if (newOwner) {
nsRefPtr<nsNPAPIPluginInstance> inst;
newOwner->GetInstance(getter_AddRefs(inst));
newOwner->SetFrame(nullptr);
if (inst) {
pluginHost->StopPluginInstance(inst);
}
newOwner->Destroy();
}
return NS_OK;
}
mInstanceOwner = newOwner;
// Ensure the frame did not change during instantiation re-entry (common).
// HasNewFrame would not have mInstanceOwner yet, so the new frame would be
// dangling. (Bug 854082)
@ -778,14 +807,6 @@ nsObjectLoadingContent::InstantiatePluginInstance(bool aIsLoading)
mInstanceOwner->SetFrame(static_cast<nsObjectFrame*>(frame));
}
if (appShell) {
appShell->ResumeNative();
}
if (NS_FAILED(rv)) {
return rv;
}
// Set up scripting interfaces.
NotifyContentObjectWrapper();
@ -2157,6 +2178,10 @@ nsObjectLoadingContent::UnloadObject(bool aResetState)
mOriginalContentType.Truncate();
}
// InstantiatePluginInstance checks this after re-entrant calls and aborts if
// it was cleared from under it
mInstantiating = false;
mScriptRequested = false;
// This call should be last as it may re-enter