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

Unified Diff: content/browser/plugin_loader_posix.cc

Issue 718523002: Fix a bug that would cause the plugin_loader to stall. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Comments from avi. Created 6 years, 1 month 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 | « content/browser/plugin_loader_posix.h ('k') | content/browser/plugin_loader_posix_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: content/browser/plugin_loader_posix.cc
diff --git a/content/browser/plugin_loader_posix.cc b/content/browser/plugin_loader_posix.cc
index 22bc2b614c2599f8242540c471ea1a347ca16cb8..3523d326978e8432d56bad8a94663d54e90a46aa 100644
--- a/content/browser/plugin_loader_posix.cc
+++ b/content/browser/plugin_loader_posix.cc
@@ -19,7 +19,7 @@
namespace content {
PluginLoaderPosix::PluginLoaderPosix()
- : next_load_index_(0) {
+ : next_load_index_(0), loading_plugins_(false) {
}
void PluginLoaderPosix::GetPlugins(
@@ -34,9 +34,12 @@ void PluginLoaderPosix::GetPlugins(
return;
}
- if (callbacks_.empty()) {
+ if (!loading_plugins_) {
+ loading_plugins_ = true;
callbacks_.push_back(callback);
+ // When |loading_plugins_| is set to false, this instance must call
+ // SetPlugins().
PluginList::Singleton()->PrepareForPluginLoading();
BrowserThread::PostTask(BrowserThread::FILE,
@@ -81,6 +84,10 @@ void PluginLoaderPosix::OnProcessCrashed(int exit_code) {
LoadPluginsInternal();
}
+void PluginLoaderPosix::OnProcessLaunchFailed() {
+ FinishedLoadingPlugins();
+}
+
bool PluginLoaderPosix::Send(IPC::Message* message) {
if (process_host_.get())
return process_host_->Send(message);
@@ -120,15 +127,14 @@ void PluginLoaderPosix::LoadPluginsInternal() {
// Check if the list is empty or all plugins have already been loaded before
// forking.
- if (MaybeRunPendingCallbacks())
+ if (IsFinishedLoadingPlugins()) {
+ FinishedLoadingPlugins();
return;
+ }
RecordAction(
base::UserMetricsAction("PluginLoaderPosix.LaunchUtilityProcess"));
- if (load_start_time_.is_null())
- load_start_time_ = base::TimeTicks::Now();
-
UtilityProcessHostImpl* host = new UtilityProcessHostImpl(
this,
BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO).get());
@@ -138,7 +144,13 @@ void PluginLoaderPosix::LoadPluginsInternal() {
host->set_child_flags(ChildProcessHost::CHILD_ALLOW_HEAP_EXECUTION);
#endif
- process_host_->Send(new UtilityMsg_LoadPlugins(canonical_list_));
+ bool launched = LaunchUtilityProcess();
+ if (!launched) {
+ // The utility process either failed to start or failed to receive the IPC.
+ // This process will never receive any callbacks for OnPluginLoaded() or
+ // OnPluginLoadFailed().
+ FinishedLoadingPlugins();
+ }
}
void PluginLoaderPosix::GetPluginsWrapper(
@@ -159,12 +171,18 @@ void PluginLoaderPosix::OnPluginLoaded(uint32 index,
return;
}
- if (!MaybeAddInternalPlugin(plugin.path))
+ auto it = FindInternalPlugin(plugin.path);
+ if (it != internal_plugins_.end()) {
+ loaded_plugins_.push_back(*it);
+ internal_plugins_.erase(it);
+ } else {
loaded_plugins_.push_back(plugin);
+ }
++next_load_index_;
- MaybeRunPendingCallbacks();
+ if (IsFinishedLoadingPlugins())
+ FinishedLoadingPlugins();
}
void PluginLoaderPosix::OnPluginLoadFailed(uint32 index,
@@ -177,44 +195,45 @@ void PluginLoaderPosix::OnPluginLoadFailed(uint32 index,
++next_load_index_;
- MaybeAddInternalPlugin(plugin_path);
- MaybeRunPendingCallbacks();
+ auto it = FindInternalPlugin(plugin_path);
+ if (it != internal_plugins_.end()) {
+ loaded_plugins_.push_back(*it);
+ internal_plugins_.erase(it);
+ }
+
+ if (IsFinishedLoadingPlugins())
+ FinishedLoadingPlugins();
}
-bool PluginLoaderPosix::MaybeAddInternalPlugin(
+std::vector<WebPluginInfo>::iterator PluginLoaderPosix::FindInternalPlugin(
const base::FilePath& plugin_path) {
- for (std::vector<WebPluginInfo>::iterator it = internal_plugins_.begin();
- it != internal_plugins_.end();
- ++it) {
- if (it->path == plugin_path) {
- loaded_plugins_.push_back(*it);
- internal_plugins_.erase(it);
- return true;
- }
- }
- return false;
+ return std::find_if(internal_plugins_.begin(), internal_plugins_.end(),
+ [&plugin_path](const WebPluginInfo& plugin) {
+ return plugin.path == plugin_path;
+ });
}
-bool PluginLoaderPosix::MaybeRunPendingCallbacks() {
- if (next_load_index_ < canonical_list_.size())
- return false;
+bool PluginLoaderPosix::IsFinishedLoadingPlugins() {
+ if (canonical_list_.empty())
+ return true;
+
+ DCHECK(next_load_index_ <= canonical_list_.size());
+ return next_load_index_ == canonical_list_.size();
+}
+void PluginLoaderPosix::FinishedLoadingPlugins() {
+ loading_plugins_ = false;
PluginList::Singleton()->SetPlugins(loaded_plugins_);
- for (std::vector<PluginService::GetPluginsCallback>::iterator it =
- callbacks_.begin();
- it != callbacks_.end(); ++it) {
- base::MessageLoop::current()->PostTask(FROM_HERE,
- base::Bind(*it, loaded_plugins_));
+ for (auto& callback : callbacks_) {
+ base::MessageLoop::current()->PostTask(
+ FROM_HERE, base::Bind(callback, loaded_plugins_));
}
callbacks_.clear();
+}
- LOCAL_HISTOGRAM_TIMES("PluginLoaderPosix.LoadDone",
- (base::TimeTicks::Now() - load_start_time_) *
- base::Time::kMicrosecondsPerMillisecond);
- load_start_time_ = base::TimeTicks();
-
- return true;
+bool PluginLoaderPosix::LaunchUtilityProcess() {
+ return process_host_->Send(new UtilityMsg_LoadPlugins(canonical_list_));
}
} // namespace content
« no previous file with comments | « content/browser/plugin_loader_posix.h ('k') | content/browser/plugin_loader_posix_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698