| OLD | NEW |
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "webkit/glue/plugins/plugin_lib.h" | 5 #include "webkit/glue/plugins/plugin_lib.h" |
| 6 | 6 |
| 7 #include "base/logging.h" | 7 #include "base/logging.h" |
| 8 #include "base/message_loop.h" | 8 #include "base/message_loop.h" |
| 9 #include "base/metrics/stats_counters.h" | 9 #include "base/metrics/stats_counters.h" |
| 10 #include "base/string_util.h" | 10 #include "base/string_util.h" |
| (...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 228 base::UnloadNativeLibrary(library); | 228 base::UnloadNativeLibrary(library); |
| 229 } | 229 } |
| 230 } | 230 } |
| 231 | 231 |
| 232 return rv; | 232 return rv; |
| 233 } | 233 } |
| 234 | 234 |
| 235 // This class implements delayed NP_Shutdown and FreeLibrary on the plugin dll. | 235 // This class implements delayed NP_Shutdown and FreeLibrary on the plugin dll. |
| 236 class FreePluginLibraryTask : public Task { | 236 class FreePluginLibraryTask : public Task { |
| 237 public: | 237 public: |
| 238 FreePluginLibraryTask(base::NativeLibrary library, | 238 FreePluginLibraryTask(const FilePath& path, |
| 239 base::NativeLibrary library, |
| 239 NP_ShutdownFunc shutdown_func) | 240 NP_ShutdownFunc shutdown_func) |
| 240 : library_(library), | 241 : path_(path), |
| 242 library_(library), |
| 241 NP_Shutdown_(shutdown_func) { | 243 NP_Shutdown_(shutdown_func) { |
| 242 } | 244 } |
| 243 | 245 |
| 244 ~FreePluginLibraryTask() {} | 246 ~FreePluginLibraryTask() {} |
| 245 | 247 |
| 246 void Run() { | 248 void Run() { |
| 247 if (NP_Shutdown_) | 249 if (NP_Shutdown_) { |
| 248 NP_Shutdown_(); | 250 // Don't call NP_Shutdown if the library has been reloaded since this task |
| 251 // was posted. |
| 252 bool reloaded = false; |
| 253 if (g_loaded_libs) { |
| 254 for (size_t i = 0; i < g_loaded_libs->size(); ++i) { |
| 255 if ((*g_loaded_libs)[i]->plugin_info().path == path_) |
| 256 reloaded = true; |
| 257 } |
| 258 } |
| 259 if (!reloaded) |
| 260 NP_Shutdown_(); |
| 261 } |
| 249 | 262 |
| 250 if (library_) { | 263 if (library_) { |
| 264 // Always call base::UnloadNativeLibrary so that the system reference |
| 265 // count is decremented. |
| 251 base::UnloadNativeLibrary(library_); | 266 base::UnloadNativeLibrary(library_); |
| 252 library_ = NULL; | 267 library_ = NULL; |
| 253 } | 268 } |
| 254 } | 269 } |
| 255 | 270 |
| 256 private: | 271 private: |
| 272 FilePath path_; |
| 257 base::NativeLibrary library_; | 273 base::NativeLibrary library_; |
| 258 NP_ShutdownFunc NP_Shutdown_; | 274 NP_ShutdownFunc NP_Shutdown_; |
| 259 DISALLOW_COPY_AND_ASSIGN(FreePluginLibraryTask); | 275 DISALLOW_COPY_AND_ASSIGN(FreePluginLibraryTask); |
| 260 }; | 276 }; |
| 261 | 277 |
| 262 void PluginLib::Unload() { | 278 void PluginLib::Unload() { |
| 263 if (!internal_ && library_) { | 279 if (!internal_ && library_) { |
| 264 // In case of single process mode, a plugin can delete itself | 280 // In case of single process mode, a plugin can delete itself |
| 265 // by executing a script. So delay the unloading of the library | 281 // by executing a script. So delay the unloading of the library |
| 266 // so that the plugin will have a chance to unwind. | 282 // so that the plugin will have a chance to unwind. |
| 267 bool defer_unload = webkit_glue::IsPluginRunningInRendererProcess(); | 283 bool defer_unload = webkit_glue::IsPluginRunningInRendererProcess(); |
| 268 | 284 |
| 269 /* TODO(dglazkov): Revisit when re-enabling the JSC build. | 285 /* TODO(dglazkov): Revisit when re-enabling the JSC build. |
| 270 #if USE(JSC) | 286 #if USE(JSC) |
| 271 // The plugin NPAPI instances may still be around. Delay the | 287 // The plugin NPAPI instances may still be around. Delay the |
| 272 // NP_Shutdown and FreeLibrary calls at least till the next | 288 // NP_Shutdown and FreeLibrary calls at least till the next |
| 273 // peek message. | 289 // peek message. |
| 274 defer_unload = true; | 290 defer_unload = true; |
| 275 #endif | 291 #endif |
| 276 */ | 292 */ |
| 277 | 293 |
| 278 if (defer_unload) { | 294 if (defer_unload) { |
| 279 FreePluginLibraryTask* free_library_task = | 295 FreePluginLibraryTask* free_library_task = |
| 280 new FreePluginLibraryTask(skip_unload_ ? NULL : library_, | 296 new FreePluginLibraryTask(web_plugin_info_.path, |
| 297 skip_unload_ ? NULL : library_, |
| 281 entry_points_.np_shutdown); | 298 entry_points_.np_shutdown); |
| 282 LOG_IF(ERROR, PluginList::DebugPluginLoading()) | 299 LOG_IF(ERROR, PluginList::DebugPluginLoading()) |
| 283 << "Scheduling delayed unload for plugin " | 300 << "Scheduling delayed unload for plugin " |
| 284 << web_plugin_info_.path.value(); | 301 << web_plugin_info_.path.value(); |
| 285 MessageLoop::current()->PostTask(FROM_HERE, free_library_task); | 302 MessageLoop::current()->PostTask(FROM_HERE, free_library_task); |
| 286 } else { | 303 } else { |
| 287 Shutdown(); | 304 Shutdown(); |
| 288 if (!skip_unload_) { | 305 if (!skip_unload_) { |
| 289 LOG_IF(ERROR, PluginList::DebugPluginLoading()) | 306 LOG_IF(ERROR, PluginList::DebugPluginLoading()) |
| 290 << "Unloading plugin " << web_plugin_info_.path.value(); | 307 << "Unloading plugin " << web_plugin_info_.path.value(); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 308 } | 325 } |
| 309 | 326 |
| 310 void PluginLib::Shutdown() { | 327 void PluginLib::Shutdown() { |
| 311 if (initialized_ && !internal_) { | 328 if (initialized_ && !internal_) { |
| 312 NP_Shutdown(); | 329 NP_Shutdown(); |
| 313 initialized_ = false; | 330 initialized_ = false; |
| 314 } | 331 } |
| 315 } | 332 } |
| 316 | 333 |
| 317 } // namespace NPAPI | 334 } // namespace NPAPI |
| OLD | NEW |