summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--webkit/data/plugins/force_reload.html13
-rw-r--r--webkit/glue/plugins/plugin_lib.cc27
-rw-r--r--webkit/tools/test_shell/plugin_tests.cc15
3 files changed, 48 insertions, 7 deletions
diff --git a/webkit/data/plugins/force_reload.html b/webkit/data/plugins/force_reload.html
new file mode 100644
index 0000000..cc7cf39
--- /dev/null
+++ b/webkit/data/plugins/force_reload.html
@@ -0,0 +1,13 @@
+<html>
+<body>
+<embed id='1' type='application/vnd.npapi-test' src='foo' name='reload1'></embed>
+<script language="JavaScript">
+// Remove the existing embed object to force unload.
+var e = document.getElementById('1');
+e.parentNode.removeChild(e);
+
+// Add a new embed object to force reload.
+document.write("<embed id='2' type='application/vnd.npapi-test' src='foo' name='reload2'></embed>");
+</script>
+</body>
+</html>
diff --git a/webkit/glue/plugins/plugin_lib.cc b/webkit/glue/plugins/plugin_lib.cc
index ee613c1..292cd63 100644
--- a/webkit/glue/plugins/plugin_lib.cc
+++ b/webkit/glue/plugins/plugin_lib.cc
@@ -235,25 +235,41 @@ bool PluginLib::Load() {
// This class implements delayed NP_Shutdown and FreeLibrary on the plugin dll.
class FreePluginLibraryTask : public Task {
public:
- FreePluginLibraryTask(base::NativeLibrary library,
+ FreePluginLibraryTask(const FilePath& path,
+ base::NativeLibrary library,
NP_ShutdownFunc shutdown_func)
- : library_(library),
+ : path_(path),
+ library_(library),
NP_Shutdown_(shutdown_func) {
}
~FreePluginLibraryTask() {}
void Run() {
- if (NP_Shutdown_)
- NP_Shutdown_();
+ if (NP_Shutdown_) {
+ // Don't call NP_Shutdown if the library has been reloaded since this task
+ // was posted.
+ bool reloaded = false;
+ if (g_loaded_libs) {
+ for (size_t i = 0; i < g_loaded_libs->size(); ++i) {
+ if ((*g_loaded_libs)[i]->plugin_info().path == path_)
+ reloaded = true;
+ }
+ }
+ if (!reloaded)
+ NP_Shutdown_();
+ }
if (library_) {
+ // Always call base::UnloadNativeLibrary so that the system reference
+ // count is decremented.
base::UnloadNativeLibrary(library_);
library_ = NULL;
}
}
private:
+ FilePath path_;
base::NativeLibrary library_;
NP_ShutdownFunc NP_Shutdown_;
DISALLOW_COPY_AND_ASSIGN(FreePluginLibraryTask);
@@ -277,7 +293,8 @@ void PluginLib::Unload() {
if (defer_unload) {
FreePluginLibraryTask* free_library_task =
- new FreePluginLibraryTask(skip_unload_ ? NULL : library_,
+ new FreePluginLibraryTask(web_plugin_info_.path,
+ skip_unload_ ? NULL : library_,
entry_points_.np_shutdown);
LOG_IF(ERROR, PluginList::DebugPluginLoading())
<< "Scheduling delayed unload for plugin "
diff --git a/webkit/tools/test_shell/plugin_tests.cc b/webkit/tools/test_shell/plugin_tests.cc
index ef1d8f0..ffb84bd 100644
--- a/webkit/tools/test_shell/plugin_tests.cc
+++ b/webkit/tools/test_shell/plugin_tests.cc
@@ -127,7 +127,7 @@ TEST_F(PluginTest, Refresh) {
// don't crash.
TEST_F(PluginTest, DeleteFrameDuringEvent) {
FilePath test_html = data_dir_;
- test_html = test_html.AppendASCII("plugins");
+ test_html = test_html.AppendASCII(TEST_PLUGIN_DIRECTORY);
test_html = test_html.AppendASCII("delete_frame.html");
test_shell_->LoadFile(test_html);
test_shell_->WaitTestFinished();
@@ -142,6 +142,17 @@ TEST_F(PluginTest, DeleteFrameDuringEvent) {
// No crash means we passed.
}
+// Tests that a forced reload of the plugin will not crash.
+TEST_F(PluginTest, ForceReload) {
+ FilePath test_html = data_dir_;
+ test_html = test_html.AppendASCII(TEST_PLUGIN_DIRECTORY);
+ test_html = test_html.AppendASCII("force_reload.html");
+ test_shell_->LoadFile(test_html);
+ test_shell_->WaitTestFinished();
+
+ // No crash means we passed.
+}
+
#if defined(OS_WIN)
BOOL CALLBACK EnumChildProc(HWND hwnd, LPARAM lparam) {
HWND* plugin_hwnd = reinterpret_cast<HWND*>(lparam);
@@ -157,7 +168,7 @@ BOOL CALLBACK EnumChildProc(HWND hwnd, LPARAM lparam) {
// Tests that hiding/showing the parent frame hides/shows the plugin.
TEST_F(PluginTest, PluginVisibilty) {
FilePath test_html = data_dir_;
- test_html = test_html.AppendASCII("plugins");
+ test_html = test_html.AppendASCII(TEST_PLUGIN_DIRECTORY);
test_html = test_html.AppendASCII("plugin_visibility.html");
test_shell_->LoadFile(test_html);
test_shell_->WaitTestFinished();