summaryrefslogtreecommitdiffstats
path: root/webkit/glue/plugins
diff options
context:
space:
mode:
authorapatrick@google.com <apatrick@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-10-30 20:09:46 +0000
committerapatrick@google.com <apatrick@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-10-30 20:09:46 +0000
commit6d98bcf2015ef0bd8ce67f79afe9d48225e59ed7 (patch)
tree5b6a3505ac52b3cab763b4045bd1fa036d86e5de /webkit/glue/plugins
parent1a9ae172dde1aed6720c7f00110d720eb1d0088f (diff)
downloadchromium_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.cc4
-rw-r--r--webkit/glue/plugins/test/plugin_client.cc4
-rw-r--r--webkit/glue/plugins/test/plugin_thread_async_call_test.cc92
-rw-r--r--webkit/glue/plugins/test/plugin_thread_async_call_test.h31
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