diff options
author | jam@chromium.org <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-02-21 08:10:29 +0000 |
---|---|---|
committer | jam@chromium.org <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-02-21 08:10:29 +0000 |
commit | b62de6b223ad59c0183fb0890f27121c7d24d852 (patch) | |
tree | 92787f54447c363052070044c7033f56c62e262f /chrome/plugin | |
parent | 8930d471c128ed74b11beaa78ea1b171c1ac7157 (diff) | |
download | chromium_src-b62de6b223ad59c0183fb0890f27121c7d24d852.zip chromium_src-b62de6b223ad59c0183fb0890f27121c7d24d852.tar.gz chromium_src-b62de6b223ad59c0183fb0890f27121c7d24d852.tar.bz2 |
Fix plugin hang that Earth team found.
Normally an NPObjectProxy uses the modal dialog event to figure out when it needs to pump window messages in an invoke. However, an NPObjectProxy created by an NPObjectStub never got access to this event, which led to this hang.
BUG=7793
Review URL: http://codereview.chromium.org/20515
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@10145 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/plugin')
-rw-r--r-- | chrome/plugin/npobject_proxy.cc | 7 | ||||
-rw-r--r-- | chrome/plugin/npobject_stub.cc | 25 | ||||
-rw-r--r-- | chrome/plugin/npobject_stub.h | 11 | ||||
-rw-r--r-- | chrome/plugin/npobject_util.cc | 5 | ||||
-rw-r--r-- | chrome/plugin/npobject_util.h | 3 | ||||
-rw-r--r-- | chrome/plugin/webplugin_delegate_stub.cc | 3 | ||||
-rw-r--r-- | chrome/plugin/webplugin_proxy.h | 4 |
7 files changed, 43 insertions, 15 deletions
diff --git a/chrome/plugin/npobject_proxy.cc b/chrome/plugin/npobject_proxy.cc index 3c4f811..0af1f32 100644 --- a/chrome/plugin/npobject_proxy.cc +++ b/chrome/plugin/npobject_proxy.cc @@ -163,7 +163,8 @@ bool NPObjectProxy::NPInvokePrivate(NPP npp, std::vector<NPVariant_Param> args_param; for (unsigned int i = 0; i < arg_count; ++i) { NPVariant_Param param; - CreateNPVariantParam(args[i], channel_copy, ¶m, false); + CreateNPVariantParam( + args[i], channel_copy, ¶m, false, proxy->modal_dialog_event_); args_param.push_back(param); } @@ -266,7 +267,9 @@ bool NPObjectProxy::NPSetProperty(NPObject *obj, CreateNPIdentifierParam(name, &name_param); NPVariant_Param value_param; - CreateNPVariantParam(*value, proxy->channel(), &value_param, false); + CreateNPVariantParam( + *value, proxy->channel(), &value_param, false, + proxy->modal_dialog_event_); proxy->Send(new NPObjectMsg_SetProperty( proxy->route_id(), name_param, value_param, &result)); diff --git a/chrome/plugin/npobject_stub.cc b/chrome/plugin/npobject_stub.cc index ec276b0..a36a5f2 100644 --- a/chrome/plugin/npobject_stub.cc +++ b/chrome/plugin/npobject_stub.cc @@ -12,12 +12,16 @@ #include "third_party/npapi/bindings/npruntime.h" NPObjectStub::NPObjectStub( - NPObject* npobject, PluginChannelBase* channel, int route_id) + NPObject* npobject, + PluginChannelBase* channel, + int route_id, + base::WaitableEvent* modal_dialog_event) : channel_(channel), npobject_(npobject), route_id_(route_id), valid_(true), - web_plugin_delegate_proxy_(NULL) { + web_plugin_delegate_proxy_(NULL), + modal_dialog_event_(modal_dialog_event) { channel_->AddRoute(route_id, this, true); // We retain the object just as PluginHost does if everything was in-process. @@ -110,8 +114,10 @@ void NPObjectStub::OnInvoke(bool is_default, int arg_count = static_cast<int>(args.size()); NPVariant* args_var = new NPVariant[arg_count]; - for (int i = 0; i < arg_count; ++i) - CreateNPVariant(args[i], local_channel, &(args_var[i]), NULL); + for (int i = 0; i < arg_count; ++i) { + CreateNPVariant( + args[i], local_channel, &(args_var[i]), modal_dialog_event_); + } if (is_default) { if (IsPluginProcess()) { @@ -145,7 +151,8 @@ void NPObjectStub::OnInvoke(bool is_default, delete[] args_var; - CreateNPVariantParam(result_var, local_channel, &result_param, true); + CreateNPVariantParam( + result_var, local_channel, &result_param, true, modal_dialog_event_); NPObjectMsg_Invoke::WriteReplyParams(reply_msg, result_param, return_value); local_channel->Send(reply_msg); } @@ -181,7 +188,8 @@ void NPObjectStub::OnGetProperty(const NPIdentifier_Param& name, *result = NPN_GetProperty(0, npobject_, id, &result_var); } - CreateNPVariantParam(result_var, channel_, property, true); + CreateNPVariantParam( + result_var, channel_, property, true, modal_dialog_event_); } void NPObjectStub::OnSetProperty(const NPIdentifier_Param& name, @@ -191,7 +199,7 @@ void NPObjectStub::OnSetProperty(const NPIdentifier_Param& name, VOID_TO_NPVARIANT(result_var); NPIdentifier id = CreateNPIdentifier(name); NPVariant property_var; - CreateNPVariant(property, channel_, &property_var, NULL); + CreateNPVariant(property, channel_, &property_var, modal_dialog_event_); if (IsPluginProcess()) { if (npobject_->_class->setProperty) { @@ -282,7 +290,8 @@ void NPObjectStub::OnEvaluate(const std::string& script, &script_string, &result_var); NPVariant_Param result_param; - CreateNPVariantParam(result_var, local_channel, &result_param, true); + CreateNPVariantParam( + result_var, local_channel, &result_param, true, modal_dialog_event_); NPObjectMsg_Evaluate::WriteReplyParams(reply_msg, result_param, return_value); local_channel->Send(reply_msg); } diff --git a/chrome/plugin/npobject_stub.h b/chrome/plugin/npobject_stub.h index 653a400..cd75853 100644 --- a/chrome/plugin/npobject_stub.h +++ b/chrome/plugin/npobject_stub.h @@ -13,6 +13,10 @@ #include "base/ref_counted.h" #include "chrome/common/ipc_channel.h" +namespace base { +class WaitableEvent; +} + class PluginChannelBase; class WebPluginDelegateProxy; struct NPIdentifier_Param; @@ -25,7 +29,10 @@ struct NPVariant_Param; class NPObjectStub : public IPC::Channel::Listener, public IPC::Message::Sender { public: - NPObjectStub(NPObject* npobject, PluginChannelBase* channel, int route_id); + NPObjectStub(NPObject* npobject, + PluginChannelBase* channel, + int route_id, + base::WaitableEvent* modal_dialog_event); ~NPObjectStub(); // IPC::Message::Sender implementation: @@ -74,6 +81,8 @@ class NPObjectStub : public IPC::Channel::Listener, int route_id_; scoped_refptr<PluginChannelBase> channel_; + base::WaitableEvent* modal_dialog_event_; + // These variables are used to ensure that the window script object is not // called after the plugin widget has gone away, as the frame manually // deallocates it and ignores the refcount to avoid leaks. diff --git a/chrome/plugin/npobject_util.cc b/chrome/plugin/npobject_util.cc index e3ba520..7bed9b4 100644 --- a/chrome/plugin/npobject_util.cc +++ b/chrome/plugin/npobject_util.cc @@ -139,7 +139,8 @@ NPIdentifier CreateNPIdentifier(const NPIdentifier_Param& param) { void CreateNPVariantParam(const NPVariant& variant, PluginChannelBase* channel, NPVariant_Param* param, - bool release) { + bool release, + base::WaitableEvent* modal_dialog_event) { switch (variant.type) { case NPVariantType_Void: param->type = NPVARIANT_PARAM_VOID; @@ -184,7 +185,7 @@ void CreateNPVariantParam(const NPVariant& variant, param->type = NPVARIANT_PARAM_OBJECT_ROUTING_ID; int route_id = channel->GenerateRouteID(); NPObjectStub* object_stub = new NPObjectStub( - variant.value.objectValue, channel, route_id); + variant.value.objectValue, channel, route_id, modal_dialog_event); param->npobject_routing_id = route_id; param->npobject_pointer = variant.value.objectValue; } else { diff --git a/chrome/plugin/npobject_util.h b/chrome/plugin/npobject_util.h index ba74a6b..2c2590f 100644 --- a/chrome/plugin/npobject_util.h +++ b/chrome/plugin/npobject_util.h @@ -48,7 +48,8 @@ NPIdentifier CreateNPIdentifier(const NPIdentifier_Param& param); void CreateNPVariantParam(const NPVariant& variant, PluginChannelBase* channel, NPVariant_Param* param, - bool release); + bool release, + base::WaitableEvent* modal_dialog_event); #if defined(OS_WIN) // Creates an NPVariant from the marshalled object. diff --git a/chrome/plugin/webplugin_delegate_stub.cc b/chrome/plugin/webplugin_delegate_stub.cc index 1a35ecf..b2041d4 100644 --- a/chrome/plugin/webplugin_delegate_stub.cc +++ b/chrome/plugin/webplugin_delegate_stub.cc @@ -257,7 +257,8 @@ void WebPluginDelegateStub::OnGetPluginScriptableObject(int* route_id, *npobject_ptr = object; // The stub will delete itself when the proxy tells it that it's released, or // otherwise when the channel is closed. - NPObjectStub* stub = new NPObjectStub(object, channel_.get(), *route_id); + NPObjectStub* stub = new NPObjectStub( + object, channel_.get(), *route_id, webplugin_->modal_dialog_event()); // Release ref added by GetPluginScriptableObject (our stub holds its own). NPN_ReleaseObject(object); diff --git a/chrome/plugin/webplugin_proxy.h b/chrome/plugin/webplugin_proxy.h index d6922aa..fd55416 100644 --- a/chrome/plugin/webplugin_proxy.h +++ b/chrome/plugin/webplugin_proxy.h @@ -97,6 +97,10 @@ class WebPluginProxy : public WebPlugin { bool notify_needed, HANDLE notify_data); + base::WaitableEvent* modal_dialog_event() { + return modal_dialog_event_.get(); + } + private: bool Send(IPC::Message* msg); |