| 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
|
|
|