diff options
author | apatrick@google.com <apatrick@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-10-30 20:09:46 +0000 |
---|---|---|
committer | apatrick@google.com <apatrick@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-10-30 20:09:46 +0000 |
commit | 6d98bcf2015ef0bd8ce67f79afe9d48225e59ed7 (patch) | |
tree | 5b6a3505ac52b3cab763b4045bd1fa036d86e5de /webkit/glue/plugins | |
parent | 1a9ae172dde1aed6720c7f00110d720eb1d0088f (diff) | |
download | chromium_src-6d98bcf2015ef0bd8ce67f79afe9d48225e59ed7.zip chromium_src-6d98bcf2015ef0bd8ce67f79afe9d48225e59ed7.tar.gz chromium_src-6d98bcf2015ef0bd8ce67f79afe9d48225e59ed7.tar.bz2 |
Ensure that NPN_PluginThreadAsyncCall callbacks are not invoked after NPP_Destroy.
TEST=none
BUG=none
Review URL: http://codereview.chromium.org/338050
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@30628 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit/glue/plugins')
-rw-r--r-- | webkit/glue/plugins/plugin_instance.cc | 4 | ||||
-rw-r--r-- | webkit/glue/plugins/test/plugin_client.cc | 4 | ||||
-rw-r--r-- | webkit/glue/plugins/test/plugin_thread_async_call_test.cc | 92 | ||||
-rw-r--r-- | webkit/glue/plugins/test/plugin_thread_async_call_test.h | 31 |
4 files changed, 130 insertions, 1 deletions
diff --git a/webkit/glue/plugins/plugin_instance.cc b/webkit/glue/plugins/plugin_instance.cc index 8ae1aeb..458d287 100644 --- a/webkit/glue/plugins/plugin_instance.cc +++ b/webkit/glue/plugins/plugin_instance.cc @@ -365,7 +365,9 @@ void PluginInstance::PluginThreadAsyncCall(void (*func)(void *), void PluginInstance::OnPluginThreadAsyncCall(void (*func)(void *), void *user_data) { - func(user_data); + // Do not invoke the callback if NPP_Destroy has already been invoked. + if (webplugin_) + func(user_data); } uint32 PluginInstance::ScheduleTimer(uint32 interval, diff --git a/webkit/glue/plugins/test/plugin_client.cc b/webkit/glue/plugins/test/plugin_client.cc index 3bde2c1..7d9a468 100644 --- a/webkit/glue/plugins/test/plugin_client.cc +++ b/webkit/glue/plugins/test/plugin_client.cc @@ -17,6 +17,7 @@ #include "webkit/glue/plugins/test/plugin_new_fails_test.h" #include "webkit/glue/plugins/test/plugin_private_test.h" #include "webkit/glue/plugins/test/plugin_schedule_timer_test.h" +#include "webkit/glue/plugins/test/plugin_thread_async_call_test.h" #include "webkit/glue/plugins/test/plugin_npobject_lifetime_test.h" #include "webkit/glue/plugins/test/plugin_npobject_proxy_test.h" #include "webkit/glue/plugins/test/plugin_window_size_test.h" @@ -169,6 +170,9 @@ NPError NPP_New(NPMIMEType pluginType, NPP instance, uint16 mode, } else if (test_name == "plugin_popup_with_plugin_target") { new_test = new NPAPIClient::ExecuteJavascriptPopupWindowTargetPluginTest( instance, NPAPIClient::PluginClient::HostFunctions()); + } else if (test_name == "plugin_thread_async_call") { + new_test = new NPAPIClient::PluginThreadAsyncCallTest( + instance, NPAPIClient::PluginClient::HostFunctions()); } else if (test_name == "private") { new_test = new NPAPIClient::PrivateTest(instance, NPAPIClient::PluginClient::HostFunctions()); diff --git a/webkit/glue/plugins/test/plugin_thread_async_call_test.cc b/webkit/glue/plugins/test/plugin_thread_async_call_test.cc new file mode 100644 index 0000000..11d514d --- /dev/null +++ b/webkit/glue/plugins/test/plugin_thread_async_call_test.cc @@ -0,0 +1,92 @@ +// Copyright (c) 2006-2008 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. + +#include "webkit/glue/plugins/test/plugin_thread_async_call_test.h" +#include "webkit/glue/plugins/test/plugin_client.h" + +namespace NPAPIClient { + +namespace { + +// There are two plugin instances in this test. The long lived instance is used +// for reporting errors and signalling test completion. The short lived one is +// used to verify that async callbacks are not invoked after NPP_Destroy. +PluginThreadAsyncCallTest* g_short_lived_instance; +PluginThreadAsyncCallTest* g_long_lived_instance; + +void OnCallSucceededHelper(void* data) { + static_cast<PluginThreadAsyncCallTest*>(data)->OnCallSucceeded(); +} + +void OnCallFailed(void* data) { + g_long_lived_instance->SetError("Async callback invoked after NPP_Destroy"); +} + +void OnCallCompletedHelper(void* data) { + static_cast<PluginThreadAsyncCallTest*>(data)->OnCallCompleted(); +} +} + +PluginThreadAsyncCallTest::PluginThreadAsyncCallTest( + NPP id, NPNetscapeFuncs *host_functions) + : PluginTest(id, host_functions) { +} + +NPError PluginThreadAsyncCallTest::New( + uint16 mode, int16 argc, const char* argn[], const char* argv[], + NPSavedData* saved) { + NPError error = PluginTest::New(mode, argc, argn, argv, saved); + if (error != NPERR_NO_ERROR) + return error; + + // Determine whether this is the short lived instance. + for (int i = 0; i < argc; ++i) { + if (base::strcasecmp(argn[i], "short_lived") == 0) { + if (base::strcasecmp(argv[i], "true") == 0) { + g_short_lived_instance = this; + } else { + g_long_lived_instance = this; + } + } + } + + // Schedule an async call that will succeed. + if (this == g_short_lived_instance) { + HostFunctions()->pluginthreadasynccall(id(), OnCallSucceededHelper, this); + } + + return NPERR_NO_ERROR; +} + +void PluginThreadAsyncCallTest::OnCallSucceeded() { + // Delete the short lived instance. + NPIdentifier delete_id = HostFunctions()->getstringidentifier( + "deleteShortLivedInstance"); + + NPObject *window_obj = NULL; + HostFunctions()->getvalue(id(), NPNVWindowNPObject, &window_obj); + + NPVariant result; + HostFunctions()->invoke(id(), window_obj, delete_id, NULL, 0, &result); +} + +NPError PluginThreadAsyncCallTest::Destroy() { + if (this == g_short_lived_instance) { + // Schedule an async call that should not be called. + HostFunctions()->pluginthreadasynccall(id(), OnCallFailed, NULL); + + // Schedule an async call to end the test using the long lived instance. + HostFunctions()->pluginthreadasynccall(g_long_lived_instance->id(), + OnCallCompletedHelper, + g_long_lived_instance); + } + + return NPERR_NO_ERROR; +} + +void PluginThreadAsyncCallTest::OnCallCompleted() { + SignalTestCompleted(); +} + +} // namespace NPAPIClient diff --git a/webkit/glue/plugins/test/plugin_thread_async_call_test.h b/webkit/glue/plugins/test/plugin_thread_async_call_test.h new file mode 100644 index 0000000..ff39ed8 --- /dev/null +++ b/webkit/glue/plugins/test/plugin_thread_async_call_test.h @@ -0,0 +1,31 @@ +// Copyright (c) 2006-2009 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. + +#ifndef WEBKIT_GLUE_PLUGINS_TEST_PLUGIN_THREAD_ASYNC_CALL_TEST_H +#define WEBKIT_GLUE_PLUGINS_TEST_PLUGIN_THREAD_ASYNC_CALL_TEST_H + +#include <vector> + +#include "webkit/glue/plugins/test/plugin_test.h" + +namespace NPAPIClient { + +// This class tests scheduling and unscheduling of async callbacks using +// NPN_PluginThreadAsyncCall. +class PluginThreadAsyncCallTest : public PluginTest { + public: + PluginThreadAsyncCallTest(NPP id, NPNetscapeFuncs *host_functions); + + virtual NPError New(uint16 mode, int16 argc, const char* argn[], + const char* argv[], NPSavedData* saved); + + virtual NPError Destroy(); + + void OnCallSucceeded(); + void OnCallCompleted(); +}; + +} // namespace NPAPIClient + +#endif // WEBKIT_GLUE_PLUGINS_TEST_PLUGIN_THREAD_ASYNC_CALL_TEST_H |