Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(963)

Unified Diff: content/browser/plugin_loader_posix.h

Issue 8318028: Gracefully handle child process death in out-of-process plugin loading. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Do not send the index Created 9 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « build/common.gypi ('k') | content/browser/plugin_loader_posix.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: content/browser/plugin_loader_posix.h
diff --git a/content/browser/plugin_loader_posix.h b/content/browser/plugin_loader_posix.h
index e766f9e765ca8783a7b07b68fdf59d17fb1622a6..1af295799eabe21e4cfd56de7a04065f250c4c42 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);
};
« no previous file with comments | « build/common.gypi ('k') | content/browser/plugin_loader_posix.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698