diff options
-rw-r--r-- | webkit/data/plugins/force_reload.html | 13 | ||||
-rw-r--r-- | webkit/glue/plugins/plugin_lib.cc | 27 | ||||
-rw-r--r-- | webkit/tools/test_shell/plugin_tests.cc | 15 |
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(); |