diff options
author | rsesek@chromium.org <rsesek@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-10-21 17:45:43 +0000 |
---|---|---|
committer | rsesek@chromium.org <rsesek@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-10-21 17:45:43 +0000 |
commit | d4af1e727ce10d9f4eda8424e63cbb82b16f22b9 (patch) | |
tree | 9b7db4554d5e7ad414e1f1564ca083f3abb5ee5c /content/browser/plugin_loader_posix.h | |
parent | 3cb34b797fe70cec168c0e5824014dcf856ee8e3 (diff) | |
download | chromium_src-d4af1e727ce10d9f4eda8424e63cbb82b16f22b9.zip chromium_src-d4af1e727ce10d9f4eda8424e63cbb82b16f22b9.tar.gz chromium_src-d4af1e727ce10d9f4eda8424e63cbb82b16f22b9.tar.bz2 |
Gracefully handle child process death in out-of-process plugin loading.
This also queues requests to load plugins, based on http://codereview.chromium.org/8243010/.
BUG=100053
TEST=Install Sonix webcam driver on OS X Lion and try to load a Flash video. It plays.
Review URL: http://codereview.chromium.org/8318028
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@106738 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'content/browser/plugin_loader_posix.h')
-rw-r--r-- | content/browser/plugin_loader_posix.h | 92 |
1 files changed, 84 insertions, 8 deletions
diff --git a/content/browser/plugin_loader_posix.h b/content/browser/plugin_loader_posix.h index e766f9e..1af2957 100644 --- a/content/browser/plugin_loader_posix.h +++ b/content/browser/plugin_loader_posix.h @@ -8,36 +8,112 @@ #include <vector> #include "base/memory/ref_counted.h" +#include "base/time.h" #include "content/browser/plugin_service.h" #include "content/browser/utility_process_host.h" +#include "ipc/ipc_message.h" #include "webkit/plugins/webplugininfo.h" +class FilePath; +class UtilityProcessHost; + namespace base { class MessageLoopProxy; } -class PluginLoaderPosix : public UtilityProcessHost::Client { +// This class is responsible for managing the out-of-process plugin loading on +// POSIX systems. It primarily lives on the IO thread, but has a brief stay on +// the FILE thread to iterate over plugin directories when it is first +// constructed. +// +// The following is the algorithm used to load plugins: +// 1. This asks the PluginList for the list of all potential plugins to attempt +// to load. This is referred to as the canonical list. +// 2. The child process this hosts is forked and the canonical list is sent to +// it. +// 3. The child process iterates over the canonical list, attempting to load +// each plugin in the order specified by the list. It sends an IPC message +// to the browser after each load, indicating success or failure. The two +// processes synchronize the position in the vector that will be used to +// attempt to load the next plugin. +// 4. If the child dies during this process, the host forks another child and +// resumes loading at the position past the plugin that it just attempted to +// load, bypassing the problematic plugin. +// 5. This algorithm continues until the canonical list has been walked to the +// end, after which the list of loaded plugins is set on the PluginList and +// the completion callback is run. +class PluginLoaderPosix : public UtilityProcessHost::Client, + IPC::Message::Sender { public: - // Must be called on the IO thread. - static void LoadPlugins(base::MessageLoopProxy* target_loop, - const PluginService::GetPluginsCallback& callback); + PluginLoaderPosix(); + + // Must be called from the IO thread. + void LoadPlugins(scoped_refptr<base::MessageLoopProxy> target_loop, + const PluginService::GetPluginsCallback& callback); // UtilityProcessHost::Client: virtual void OnProcessCrashed(int exit_code) OVERRIDE; virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE; + // IPC::Message::Sender: + virtual bool Send(IPC::Message* msg); + private: - PluginLoaderPosix(base::MessageLoopProxy* target_loop, + struct PendingCallback { + PendingCallback(scoped_refptr<base::MessageLoopProxy> target_loop, const PluginService::GetPluginsCallback& callback); + ~PendingCallback(); + + scoped_refptr<base::MessageLoopProxy> target_loop; + PluginService::GetPluginsCallback callback; + }; + virtual ~PluginLoaderPosix(); - void OnGotPlugins(const std::vector<webkit::WebPluginInfo>& plugins); + // Called on the FILE thread to get the list of plugin paths to probe. + void GetPluginsToLoad(); + + // Must be called on the IO thread. + virtual void LoadPluginsInternal(); + + // Message handlers. + void OnPluginLoaded(const webkit::WebPluginInfo& plugin); + void OnPluginLoadFailed(const FilePath& plugin_path); + + // Checks if the plugin path is an internal plugin, and, if it is, adds it to + // |loaded_plugins_|. + bool MaybeAddInternalPlugin(const FilePath& plugin_path); + + // Runs all the registered callbacks on each's target loop if the condition + // for ending the load process is done (i.e. the |next_load_index_| is outside + // the ranage of the |canonical_list_|). + void RunPendingCallbacks(); + + // The process host for which this is a client. + UtilityProcessHost* process_host_; + + // A list of paths to plugins which will be loaded by the utility process, in + // the order specified by this vector. + std::vector<FilePath> canonical_list_; + + // The index in |canonical_list_| of the plugin that the child process will + // attempt to load next. + size_t next_load_index_; + + // Internal plugins that have been registered at the time of loading. + std::vector<webkit::WebPluginInfo> internal_plugins_; + + // A vector of plugins that have been loaded successfully. + std::vector<webkit::WebPluginInfo> loaded_plugins_; // The callback and message loop on which the callback will be run when the // plugin loading process has been completed. - scoped_refptr<base::MessageLoopProxy> target_loop_; - PluginService::GetPluginsCallback callback_; + std::vector<PendingCallback> callbacks_; + + // The time at which plugin loading started. + base::TimeTicks load_start_time_; + friend class MockPluginLoaderPosix; DISALLOW_COPY_AND_ASSIGN(PluginLoaderPosix); }; |