diff options
author | wez@chromium.org <wez@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-04-04 18:58:03 +0000 |
---|---|---|
committer | wez@chromium.org <wez@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-04-04 18:58:03 +0000 |
commit | f1e8af0b66c2dd27dc767bccf1179fbc9d4e7796 (patch) | |
tree | 1a89d4acb47e6634344a7c5550ec401a32090586 | |
parent | 310311c35845cdb7addc03473e4b6dc1d9e5264b (diff) | |
download | chromium_src-f1e8af0b66c2dd27dc767bccf1179fbc9d4e7796.zip chromium_src-f1e8af0b66c2dd27dc767bccf1179fbc9d4e7796.tar.gz chromium_src-f1e8af0b66c2dd27dc767bccf1179fbc9d4e7796.tar.bz2 |
Revert 130199 - Revert 128179 - Make sure the plugin scriptable object is released before NPP_Destroy.
We're reinstating this patch based on its impact on plugin crash rates between 20.0.1089.0 (with patch) and 20.0.1090.0 (without) builds.
When the we tear down a plugin instance the plugin process first invokes NPP_Destroy, and then tears down the IPC channel to the renderer, to give NPP_Destroy a chance to do last-minute scripting. When the IPC channel for the last instance is torn down we also clean up the IPC channels and stubs for any plugin-side NPObjects that remain.
We suspect that some plugins implement the scriptable object as part of the plugin instance, rather than independently ref-counted, so that our releasing the object after NPP_Destroy actually triggers the plugin process to crash.
This CL tears down the stub for the plugin's scriptable object before we call NPP_Destroy.
BUG=101968,119414
Original Review URL: http://codereview.chromium.org/9817023
Revert Review URL: https://chromiumcodereview.appspot.com/9959078
TBR=cpu@chromium.org
Review URL: https://chromiumcodereview.appspot.com/9979022
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@130698 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | content/common/npobject_stub.h | 5 | ||||
-rw-r--r-- | content/plugin/webplugin_delegate_stub.cc | 23 | ||||
-rw-r--r-- | content/plugin/webplugin_delegate_stub.h | 4 |
3 files changed, 22 insertions, 10 deletions
diff --git a/content/common/npobject_stub.h b/content/common/npobject_stub.h index 9b64ce8..6721a6f 100644 --- a/content/common/npobject_stub.h +++ b/content/common/npobject_stub.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // @@ -41,7 +41,8 @@ class NPObjectStub : public IPC::Channel::Listener, // Schedules tear-down of this stub. The underlying NPObject reference is // released, and further invokations form the IPC channel will fail once this // call has returned. Deletion of the stub is deferred to the main loop, in - // case it is touched as the stack unwinds. + // case it is touched as the stack unwinds. DeleteSoon() is safe to call + // more than once, until control returns to the main loop. void DeleteSoon(); // IPC::Message::Sender implementation: diff --git a/content/plugin/webplugin_delegate_stub.cc b/content/plugin/webplugin_delegate_stub.cc index bc130b2..c74f07b1 100644 --- a/content/plugin/webplugin_delegate_stub.cc +++ b/content/plugin/webplugin_delegate_stub.cc @@ -9,7 +9,6 @@ #include "base/bind.h" #include "base/command_line.h" #include "base/string_number_conversions.h" -#include "content/common/npobject_stub.h" #include "content/common/plugin_messages.h" #include "content/plugin/plugin_channel.h" #include "content/plugin/plugin_thread.h" @@ -31,7 +30,13 @@ using webkit::npapi::WebPlugin; using webkit::npapi::WebPluginResourceClient; static void DestroyWebPluginAndDelegate( - webkit::npapi::WebPluginDelegateImpl* delegate, WebPlugin* webplugin) { + base::WeakPtr<NPObjectStub> scriptable_object, + webkit::npapi::WebPluginDelegateImpl* delegate, + WebPlugin* webplugin) { + // The plugin may not expect us to try to release the scriptable object + // after calling NPP_Destroy on the instance, so delete the stub now. + if (scriptable_object.get()) + scriptable_object->DeleteSoon(); // WebPlugin must outlive WebPluginDelegate. if (delegate) delegate->PluginDestroyed(); @@ -58,10 +63,12 @@ WebPluginDelegateStub::~WebPluginDelegateStub() { // The delegate or an npobject is in the callstack, so don't delete it // right away. MessageLoop::current()->PostNonNestableTask(FROM_HERE, - base::Bind(&DestroyWebPluginAndDelegate, delegate_, webplugin_)); + base::Bind(&DestroyWebPluginAndDelegate, plugin_scriptable_object_, + delegate_, webplugin_)); } else { // Safe to delete right away. - DestroyWebPluginAndDelegate(delegate_, webplugin_); + DestroyWebPluginAndDelegate( + plugin_scriptable_object_, delegate_, webplugin_); } } @@ -282,11 +289,13 @@ void WebPluginDelegateStub::OnGetPluginScriptableObject(int* route_id) { } *route_id = channel_->GenerateRouteID(); - // The stub will delete itself when the proxy tells it that it's released, or - // otherwise when the channel is closed. - new NPObjectStub( + // We will delete the stub immediately before calling PluginDestroyed on the + // delegate. It will delete itself sooner if the proxy tells it that it has + // been released, or if the channel to the proxy is closed. + NPObjectStub* scriptable_stub = new NPObjectStub( object, channel_.get(), *route_id, webplugin_->containing_window(), page_url_); + plugin_scriptable_object_ = scriptable_stub->AsWeakPtr(); // Release ref added by GetPluginScriptableObject (our stub holds its own). WebBindings::releaseObject(object); diff --git a/content/plugin/webplugin_delegate_stub.h b/content/plugin/webplugin_delegate_stub.h index 8d7d3df..deddd49 100644 --- a/content/plugin/webplugin_delegate_stub.h +++ b/content/plugin/webplugin_delegate_stub.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -10,6 +10,7 @@ #include <vector> #include "base/memory/ref_counted.h" +#include "content/common/npobject_stub.h" #include "googleurl/src/gurl.h" #include "ipc/ipc_channel.h" #include "third_party/npapi/bindings/npapi.h" @@ -113,6 +114,7 @@ class WebPluginDelegateStub : public IPC::Channel::Listener, scoped_refptr<PluginChannel> channel_; + base::WeakPtr<NPObjectStub> plugin_scriptable_object_; webkit::npapi::WebPluginDelegateImpl* delegate_; WebPluginProxy* webplugin_; bool in_destructor_; |